Outils pour utilisateurs

Outils du site


Panneau latéral

ref:core:re-ecriture_d_urls

Contenu en cours de rédaction / validation

Ré-écriture d'URLs

RBS Change permet la ré-écriture des URLs des documents et des actions web, par simple configuration.

Depuis la version 3.5.0 de RBS Change, le système de ré-écriture est amélioré et permet notamment :

  • Un suivi complet des URLs ré-écrites de document : des redirections sont générées lors d'un changement du schéma d'URL
  • Des schémas d'URL de document sans identifiant
  • Une ré-écriture par défaut, sans action spéciale du développeur
  • Une gestion complète des ré-écritures depuis le Backoffice, grâce au module SEO

URLs de documents

Note : avant d'agir sur la ré-écriture des URLs de vos documents, assurez-vous d'avoir consulté affichage des documents et notamment d'avoir déclaré has-url à true.

La ré-écriture de l'URL d'un document peut se faire :

  • Automatiquement, tous les documents d'un même type partagent alors une même règle de génération d'URL. Cette règle est définie par configuration ou par code.
  • Manuellement, pour un document précis depuis l'onglet “URL” de son éditeur backoffice.

Depuis la version 3.5.0 de RBS Change, les URLs des documents sont forcément ré-écrites : un document du module mymodule aura pour URL ré-écrite par défaut /mymodule/<label>,<id>.html (où <label> et <id> sont respectivement le libellé et l'identifiant du document).

Définition manuelle de l'URL d'un document

L'onglet URL est ajouté automatiquement à l'éditeur backoffice d'un document lorsque son modèle définit “has-url” à true. Pour chaque site, il est alors possible de spécifier l'URL d'un document : cette URL doit être unique au sein d'un même site.

Définition d'une règle de ré-écriture par configuration

Les règles de ré-écriture des documents d'un module sont définies dans config/urlrewriting.xml. Ce fichier peut être surchargé dans le dossier override d'un projet. Ces règles utilisent des propriétés ou des méthodes des documents pour construire les URLs.

Chaque règle est définie par un élément <rule/> dont l'attribut documentModel précise le modèle au quel la règle s'applique.

Exemple : re-définition de la règle de ré-écriture des documents “page” du module website dans override/website/config/urlrewriting.xml

<urlrewriting>
  <rules>
    <rule documentModel="page">
      <template>/$label.html</template>
    </rule>
  </rules>
</urlrewriting>

N.B. : la surcharge du fichier config/urlrewriting.xml redéfinit entièrement le fichier.

L'élément <template/> peut faire référence à toutes les propriétés du document sous la forme $<propertyName>, à l'exception des propriétés de type document.

Il est également possible d'utiliser une méthode de la classe PHP qui représente le document. Pour cela, le paramètre doit être déclaré dans la section <parameters/> et indiquer la méthode à utiliser avec l'attribut method.

Dans l'exemple suivant, l'URL des pages est de la forme /<prefix>/<label>.html<prefix> est le retour de la méthode getPrefixForURL() (à implémenter) du document :

<urlrewriting>
  <rules>
    <rule documentModel="page">
      <template>/$prefix/$label.html</template>
      <parameters>
        <parameter name="prefix" method="getPrefixForURL" />
      </parameters>
    </rule>
  </rules>
</urlrewriting>

Définition d'une règle de ré-écriture par code

Si aucune action manuelle ou règle XML n'existe pour un document, la méthode getWebLink() du service est appelée pour construire son URL.

C'est le cas par exemple de media_FileService qui gère les URLs des médias :

class media_FileService extends f_persistentdocument_DocumentService
{
  /**
   * @param website_UrlRewritingService $urlRewritingService
   * @param f_persistentdocument_PersistentDocument $document
   * @param website_persistentdocument_website $website
   * @param string $lang
   * @param array $parameters
   * @return f_web_Link | null
   */
  public function getWebLink($urlRewritingService, $document, $website, $lang, $parameters)
  {
    // ...
    $protocol = RequestContext::getInstance()->getProtocol();
    $host = $this->getHostForDocumentId($documentId, $lang);
    $link = new f_web_ParametrizedLink($protocol, $host,
      '/publicmedia/formatted/' . $this->getRelativeFolder($documentId, $lang) . rawurlencode($fileName) . 
      ';' . $formatKey . $resourceExtension);
    return $link;
  }
}

Remarques

Il se peut notamment que l'URL générée ne soit pas l'URL configurée ; en effet, tant qu'un document n'a pas été affiché, l'URL retournée par LinkHelper::getDocumentUrl() ou LinkHelper::getDocumentUrlForWebsite() sera l'URL ré-écrite par défaut.

Ce n'est qu'au moment où ce lien est consulté que la table f_url_rules est remplie avec l'URL finale et que LinkHelper retournera la “bonne” URL. C'est également à ce moment qu'une redirection peut-être générée, si l'URL actuelle du document est différente de celle demandée.

Le renseignement de la table f_url_rules peut être forcé par la commande Change refresh-url-rewriting. La génération d'un sitemap par le module SEO a le même effet pour les documents que le sitemap inclus.

URLs d'actions

Tout comme celles des documents, les URLs des actions web peuvent elles aussi être ré-écrites, par configuration dans le fichier config/urlrewriting.xml, ou par code.

Par configuration

Depuis la version 3.5.0, les URLs des actions sont systématiquement ré-écrites : l'URL de l'action SomeAction du module mymodule est par défaut /action/mymodule/SomeAction/.

La règle de ré-écriture de l'action SomeAction du module mymodule se fait dans un élément <rule/> du fichier config/urlrewriting.xml avec l'attribut redirection valant mymodule/SomeAction. Sous <rule/>, l'élément <template/> déclare la règle de ré-écriture, qui utilise des paramètres qui sont déclarés dans la section <parameters/>.

Exemple : ré-écriture de l'URL de l'action ViewPageexternal du module website, avec les paramètres navigationtitle et cmpref :

<urlrewriting>
  <rules>
    <rule redirection="website/ViewPageexternal">
      <template>/external/$navigationtitle,$cmpref</template>
      <parameters>
        <parameter name="navigationtitle" />
        <parameter name="cmpref" />
      </parameters>
    </rule>
  </rules>
</urlrewriting>

Par défaut les paramètres sont transmis à l'action sous la forme de paramètres globaux et spécifiques au module (ie. dans le paramètre de requête <moduleName>Param).

Ainsi les paramètres cmpref et navigationtitle transmis dans l'exemple suivant à l'action website_ViewPageexternalAction seront accessibles directement via $request→getParameter() et depuis le paramètre websiteParam.

LinkHelper::getActionUrl('website', 'ViewPageexternal', 
  array('cmpref' => 1234,
        'navigationtitle' => 'mytitle'));
// This generates http://.../external/mytitle,1234
 
// Later in Action:
class website_ViewPageexternalAction extends f_action_BaseAction
{
  /**
   * @param Context $context
   * @param Request $request
   */
  public function _execute($context, $request)
  {
    // By default, two different ways to retrieve action parameters
 
    // 1. Directly:
    $cmpref = $request->getParameter("cmpref");
    $navigationtitle = $request->getParameter("navigationtitle");
 
    // 2. Using "websiteParam":
    $websiteModuleParams = $request->getParameter("websiteParam");
    $cmpref = $websiteModuleParams ["cmpref"];
    $navigationtitle = $websiteModuleParams["navigationtitle"];
  }
}

La manière de transmettre les paramètres à l'action est différente selon la valeur de l'attribut type de l'élément <parameter/> :

Valeur de type Comportement
global le paramètre est transmis en tant que paramètre global seulement
module le paramètre est transmis en tant que paramètre de module seulement. Ce comportement est utile notamment lorsque l'action effectue des traitements puis délègue l'affichage à une page dont les blocs doivent exploiter certains des paramètres.
out le paramètre ne sera pas transmis à l'action
all valeur par défaut, le paramètre est transmis en tant que paramètre global et paramètre de module

Il est également possible de transmettre un paramètre sous un ou plusieurs noms différents, en utilisant l'attribut forwardTo.

Dans l'exemple suivant, le paramètre cmpref est transmis à l'action sous les noms id et websiteParam[myid]. Du fait de la valeur de @type (out), $request→getParameter(“cmpref”) retournera null.

<urlrewriting>
  <rules>
    <rule redirection="website/ViewPageexternal">
      <template>/external/$navigationtitle,$cmpref</template>
      <parameters>
        <parameter name="navigationtitle" />
        <parameter name="cmpref" type="out" forwardTo="id,websiteParam[myid]" />
      </parameters>
    </rule>
  </rules>
</urlrewriting>

Par code

L'URL ré-écrite d'une action peut-être définie par code en implémentant la méthode generateActionRewritePath() du service du module. Cette méthode reçoit entre autres en argument le module, le nom de l'action, un référence au tableau de paramètres à lui transmettre, et retourne l'URL de l'action.

Exemple : génération par code de l'URL ré-écrite de l'action SomeAction du module mymodule, en utilisant le paramètre myParam transmis.

class mymodule_ModuleService extends ModuleBaseService
{
  /**
   * @param website_UrlRewritingService $wsurs
   * @param string $moduleName
   * @param string $actionName
   * @param website_persistentdocument_website $website
   * @param string $lang
   * @param array $parameters
   * @return string or null
   */
  public function generateActionRewritePath($wsurs, $moduleName, $actionName, $website, $lang, &$parameters)
  {
    if ($actionName == "SomeAction")
    {
      return LinkHelper::getDocumentURL($website, $lang)."/$moduleName/$actionName/".$wsurs->encodePathString($parameters["myParam"]);
    }
    return parent::generateActionRewritePath($wsurs, $moduleName, $actionName, $website, $lang, &$parameters);
  }
}

N.B. : notez l'utilisation de la méthode encodePathString() de website_UrlRewritingService pour filtrer les caractères du paramètre myParam.

ref/core/re-ecriture_d_urls.txt · Dernière modification: 2017/01/19 14:54 (modification externe)