Formation « Développer un thème WordPress sur-mesure (Classique) »

La réécriture d’URL dans WordPress

Lecture : 7 minutes • 20

Même si WordPress gère automatiquement les URL du site au travers des permaliens, il reste possible de créer des URL sur mesure pour répondre à vos besoins spécifiques grâce à l’URL rewriting.

WordPress gère seul les URL du site, et les affiche de manière lisible et sexy grâce au réglage par défaut /%postname%/ dans Réglages > Permaliens.

Capture d'écran du panneau de réglage des permaliens dans WordPress
Les permaliens dans WordPress

Mais parfois, pour des besoins spécifiques, vous allez devoir créer des URL spéciales. Et ça, c’est possible grâce à quelques fonctions fournies par WordPress.

Prérequis : Afin de bien appréhender ce cours, il vous faut être à l’aise avec le Template Hierarchy, les Custom Post Types et la WP Query.

Dans quels cas utiliser l’URL Rewriting ?

Il existe de nombreux cas dans lesquels vous voudriez avoir une URL particulière qui sort du système natif de WordPress. Cependant ce sont des cas assez spécifiques. Voici quelques exemples :

Sur ce site, j’utilise une structure d’URL particulière pour gérer mes cours :

https//capitainewp.io/formations/<nom-formation>/<url-cours>

Je simule une relation parent / enfant entre mes CPT Formation et Cours. Pourtant il n’existe pas de telle relation entre Custom Post Types dans WordPress.

Capture d'écran de l'URL d'un cours sur Capitaine WP, avec une URL composée
Les URL composées de Capitaine WP

C’est donc grâce à l’URL Rewriting que j’ai pu faire ça ! Ce système permet à Google de bien comprendre l’architecture de mes cours et leur relation avec la formation. On va justement voir comment j’ai fait dans le prochain cours (premium).

On va commencer avec un exemple plus simple afin de voir le principe de l’URL rewriting.

Imaginons un CPT « Catalogue » dans lequel on afficherait des produits. On veut aussi filtrer les résultats via une WP Query sur mesure. On aurait plusieurs filtres possibles comme :

  • La marque ;
  • La couleur ;
  • Et la taille.

L’URL type serait : monsite.fr/catalogue?brand=adidas&color=red&size=large. On a d’ailleurs vu dans un cours précédent comment faire un tel filtre (premium).

Maintenant, on voudrait une URL plus sexy, du genre : monsite.fr/catalogue/adidas/red/large.

Mais si on tape cette adresse, WordPress va nous renvoyer une erreur 404. Après tout il n’existe aucune page enfant de catalogue qui s’appelle Adidas.

Car en réalité, ce ne sont pas des pages, mais simplement des paramètres GET pour notre filtre. On va donc déclarer tout ça à WordPress, afin qu’il comprenne.

Créer une règle de réecriture d’URL

Bien, maintenant on va donner les instructions à WordPress pour qu’il comprenne ce genre d’URL, et les traite comme il faut.

Pour cela, on va écrire nos instructions dans le fichier functions.php de notre thème.

PHP
functions.php

La fonction est lancée sur le Hook init, très tôt dans l’exécution de WordPress. C’est normal car il faut que le CMS ait cette information avant d’arriver au Template Hierarchy.

Dans la fonction, on va déclarer des tags, c’est-à-dire des paramètres qu’il reconnaitra et qu’il transmettra à la page. S’ils ne sont pas déclarés, ils les ignorera. On déclare donc nos 3 paramètres : brand, color et size via la fonction add_rewrite_tag().

Ensuite tout va se jouer dans la fonction add_rewrite_rule(). On indique 3 paramètres :

  • L’URL telle qu’elle apparaitra dans le navigateur ;
  • La transcription en URL non réecrite, native ;
  • Et la priorité (top indique une priorité haute).

On utilise les expressions régulières pour définir les endroits dynamiques de notre URL. ([^/]+) veut dire qu’on attend à cet endroit un ou plusieurs caractères, qui peuvent être des chiffres, lettres ou caractères spéciaux. Le + veut dire qu’il y en a un ou plusieurs.

On ne va pas rentrer dans les détails des expressions régulières car c’est une syntaxe complexe que tout le monde aime éviter. Et dans la plupart des cas ([^/]+) suffira.

Aparté: Les expressions régulières

Véritable fléau du développeur débutant, les expressions régulières sont toutefois indispensables car elles permettent de vérifier rapidement des chaines et valeurs. Ce sont les expressions régulières qui permettent de vérifier la validité d’une adresse e-mail ou d’un numéro de téléphone dans un formulaire.

C’est un outil puissant pour les développeurs, mais avec une syntaxe certes un peu particulière

Revenons-en à notre expression réguliere : dans notre cas on indique à WordPress que s’il trouve une URL de type : catalogue/truc/truc/truc , qui commence donc par catalogue avec 3 éléments derrière, il devra suivre notre réecriture d’URL.

Le deuxième paramètre est tout autant important : il indique à WordPress comment gérer cette URL.


Avant de poursuivre, voici une petite explication du fonctionnement des URL de WordPress. Tous les permaliens sont des réécritures d’URL. Quand on va sur une page dont l’URL estmonsite.fr/page/, le serveur ne va pas chercher une page index.html située dans le dossier /page/. Ce n’est bien sûr pas comme ça que fonctionne WordPress.

Si on désactive les permaliens, on verrait en fait que l’URL classique serait : monsite.fr/index.php?pagename=page.

Vous pouvez d’ailleurs faire l’essai. Allez dans Réglages > Permaliens et désactivez la réecriture en choisissant Simple. Naviguez ensuite sur votre site et constatez que les URL ont changé :

Capture d'écran d'un site WordPress sans réecriture des URL. Le permalien est donc brut.
les URL WordPress natives, sans réécriture

Dans cet exemple, j’affiche un article et l’URL est index.php/?p=188. En y regardant de plus près, ce sont exactement les mêmes paramètres que ceux de la WP Query. Et pour cause, c’est eux qui vont permettre de définir quelles données récupérer !

En fait peu importe l’URL tapée dans le navigateur, tout passe toujours par index.php (la racine de WordPress), et ce sont les paramètres derrière qui vont permettre à WordPress de comprendre quelle page il doit charger dans la WP Query, et le template dans le Template Hierarchy.

Conseil

La structure des permaliens permet donc à WordPress d’avoir des URL plus jolies et plus lisibles, ce que Google appréciera grandement.

Mais revenons-en à notre code.

Dans notre second paramètre, on indique donc que les 3 éléments trouvés seront reportés dans 3 paramètres de l’URL. $matches est un tableau correspondant aux résultats trouvés par l’expression régulière :

PHP
functions.php

Tous ces paramètres passés dans WordPress s’appellent les Query Vars et pourront être utilisés par la WP Query.

Le premier attribut après index.php est essentiel à WordPress, puisque c’est lui qui lui indique quelle page aller chercher via la WP Query.

  • Pour une page, utilisez index.php?pagename=<slug> ;
  • Pour un article, utilisez index.php?p=<id> ;
  • Et pour un CPT, utilisez index.php?post_type=<slug>.

On résume :

  • On a indiqué à WordPress qu’il risque de recevoir une URL du type : /catalogue/ suivie de 3 paramètres ;
  • On lui donne les instructions pour récupérer ces paramètres dans son URL réelle ;
  • On a déclaré ces 3 paramètres via add_rewrite_tag() afin que WordPress puisse nous les restituer.

Maintenant que tout semble bon, on va passer aux tests.

Récupérer nos paramètres d’URL

Avant de tester, il faut retourner dans Réglages > Permaliens et cliquer sur Enregistrer, sans rien modifier. Cela va permettre à WordPress de prendre en compte votre règle, et l’enregistrer en base de données.

Sans ça, votre réecriture ne sera pas prise en compte, et votre URL tombera toujours sur une erreur 404.

Dans mon exemple, j’utilise un Custom Post Type  « catalogue », je vais donc réceptionner mes données dans archive-catalogue.php.

PHP
archive-catalogue.php

Si j’avais utilisé une page, j’aurais utilisé le template page.php (ou page-<id>.php) selon le Template Hierarchy.

Dans un code PHP classique, on aurait récupéré les paramètres via la variable système $_GET, mais pas dans WordPress ! On va attendre que ce dernier aie traité tous les paramètres, et on va les retrouver dans les Query Vars, le tableau de données qui permet à WordPress de monter sa WP Query.

Les noms « brand », « color » et « size » sont les mêmes noms que ceux définis dans add_rewrite_tag().

Désormais, vous pouvez utiliser ces valeurs comme bon vous semble dans votre template. Le cas le plus classique est de venir modifier la WP Query en ajoutant des filtres.

Tapez votre URL site.fr/catalogue/adidas/red/large et testez la bonne récupération des données, par exemple avec un echo :

PHP
archive-catalogue.php

Si tout s’est bien passé, ça devrait fonctionner correctement !

Conseil

Pensez toujours à retourner enregistrer la structure des permaliens dans Réglages > Permaliens après une modification dans votre code, afin que WordPress prenne bien en compte la réecriture d’URL.

Changer l’URL d’un Custom Post Type

On a vu comment créer un Custom Post Type plus tôt dans cette formation. Maintenant vous pourriez avoir besoin de changer son nom dans l’URL.

On ne peut plus changer le slug, sinon on perdrait toutes nos publications rattachées. Mais on peut réecrire son URL :

PHP
functions.php

Du coup dans la barre d’adresse, ce ne sera plus monsite.fr/portfolio, mais monsite.fr/creations.

Pensez là aussi à réenregistrer la structure des permaliens après toute modification.

On peut même aller plus loin et proposer une URL différente en fonction de la langue du site :

PHP

On a pas encore abordé les notions de multilangue et d’internationalisation de thème, mais on abordera ces sujets très bientôt.

Changer l’URL des auteurs

Et enfin, si vous utilisez les pages auteurs sur votre site, vous avez peut-être remarqué que vous ne pouvez pas modifier le slug d’URL, comme on peut le faire pour les catégories et les étiquettes :

Capture d'écran des réglages de permalien de WordPress. Il est possible de modifier les catégories et les étiquettes, mais pas l'auteur
Impossible de modifier le slug des auteurs ici

Du coup, on se retrouve avec des URL du type monsite.fr/author/maxime même sur un site en français.

Alors pour changer ça, on va ajouter un petit bout de code dans functions.php :

PHP
functions.php

Et là aussi, pensez bien à réenregistrer la structure des permaliens.


La mise en place de la réécriture d’URL est plutôt simple avec WordPress, mais ça peut vite devenir un casse-tête sur des sujets plus complexes.

Le plus difficile étant de bien comprendre comment fonctionnent les URL et les paramètres dans WordPress, et leur relation directe avec la WP Query et le Template Hierarchy.

Dans tous les cas vous allez pouvoir créer des URL sur mesure et élégantes grâce à ce système.

20

Questions, réponses et commentaires

  1. Aurélien

    Le 31 octobre 2020

    Bonjour, lorsque je change l’URL d’un Custom Post Type avec ‘rewrite’, je peux ouvrir la page « archive-CPT » mais la page « single-CPT » affiche la page « index ».

    Comment renommer un CPT sans perdre les articles existants?

    Merci de votre aide.

    1. Maxime BJ

      Le 31 octobre 2020

      Tu as dû oublier de réenregistrer la structure des permaliens (Réglage > Permaliens). Il faut impérativement le faire quand tu changes de nom dans le rewrite.

  2. MOYON

    Le 19 novembre 2020

    Bonjour, j’essaye de faire un Url rewriting vers un CPT. J’ai du mal comprendre. Je place pourtant mon global $query dans ma single.php dans mon CPT mais je suis redirigé vers une archive.php.

    Merci de votre aide

    1. Maxime BJ

      Le 19 novembre 2020

      On fait de la réecriture d’URL seulement sur le hook init, c’est-à-dire le plus tôt possible. C’est trop tard si tu le fais dans le template.

  3. Matthieu Ouin

    Le 29 mars 2021

    Merci pour ce tutoriel 🙂 J’ai mis du temps à trouver des infos sur comment créer ses propres permalink! Ton article est super clair, ça fait plaisir d’avoir du WordPress bien expliqué !

    1. Maxime BJ

      Le 3 avril 2021

      Merci beaucoup 🙂

  4. Noé

    Le 27 avril 2021

    Bonjour, tout d’abord merci pour cet article très instructif !
    Cela fait plusieurs heures que j’essaye de comprendre comment rewriter l’url d’un single post.
    J’essaye de composer une url comme suit : /page-name/cpt-name/post-name
    La rewrite rule :
    add_rewrite_rule(
    ‘([^/]+)/cpt-name/([^/]+)’,
    ‘index.php?cpt-name=$matches[2]’,
    ‘top’
    );
    En déclarant le CPT « publicly_queryable » accéder à l’url redirige vers le pretty permalink normal du post ( /cpt-name/post-name ) mais utilise bien le template « single.php ».
    En mettant « publicly_queryable » => false l’url reste bien la bonne mais le template chargé est « page.php » (le 404.php aurait été logique mais là je suis perdu…).
    Comme éviter cette redirection tout en utilisant bien le template « single.php » ?
    D’avance merci

    1. Maxime BJ

      Le 27 avril 2021

      Dans ton URL avec index.php, tu dois respecter les conventions de nommage de WordPress et de la WPQuery. Il ne connait pas cpt-name, c’est pour ça qu’il ne le trouvera pas.

  5. Noé

    Le 27 avril 2021

    Bonjour Maxime,
    Merci pour ta réponse ! J’ai utilisé « cpt-name » en tant qu’exemple, « cpt-name » correspond au nom de mon custom post type, dans mon cas « solutions » ( index.php?solutions=$matches[2] ), la query était donc bien correcte.
    J’ai fini par trouver, c’était logique, c’était WPML qui capturait la première partie de l’url pour avoir la langue. Si elle ne correspond pas à une langue existante il redirige vers la langue originale.

    1. Maxime BJ

      Le 29 avril 2021

      En effet, les extensions de multilangue comme WPML ou encore Polylang vont réécrire en grosse partie les URL, du coup il faut bien prendre en compte leurs paramètres dans un site multilangue.

  6. David C.

    Le 30 juin 2021

    Bonjour Maxime,

    Merci pour ces excellents tuto surtout sur quelque fonction que je ne maitrise pas… Comme la réécriture d’URL.
    Je trouve que c’est un p’tit chantier qui peut parfois faire un peu mal à la tête.

    J’ai cependant une bonne question…
    Concernant le cache et sitemap, on est d’accord que ces réécritures ne seront pas prise en compte ?
    Il s’agit là d’une réécriture pour faire des filtres (WP_Query avec arguments spécifiques), la prise en compte dans le cache pourrait poser problème vu qu’il ne peut pas savoir les filtres possibles ?

    1. Maxime BJ

      Le 1 juillet 2021

      Non c’est bien géré dans WordPress et tu n’auras pas de problème avec le cache. Pour le Sitemap, je ne pense pas qu’il va générer toutes les URL possibles avec les filtres nativement par contre. Mais c’est peut-être pas plus mal.

  7. Julien

    Le 8 juillet 2022

    Bonjour, concernant les CPT, qu’en est-il des URLS complète, càd que lorsqu’on clique sur un projet portfolio on est sur un lien de type : portfolio/234. Hors, j’aimerais portfolio pour la page archive qui liste les projets. Et une URL type projet/nom-du-projet.

    J’ai compris le mécanisme de réecriture, mais pour un CPT, la logique voudrait que ça soit différente et qu’on fasse pas une réécriture des liens. Y a t’il une astuce native à WordPress pour le CPT et la gestion des liens (archive et singular) ?

    Je vous remercie d’avance pour le temps que vous conscarerez à me répondre.

    Bien à vous.

    1. Maxime BJ

      Le 8 juillet 2022

      Pour le SEO, il n’y a pas d’interêt à changer d’URL entre temps. C’est plus sain d’avoir une structure hiérarchique « logique » je dirais. Donc tu aurais /projets/ pour l’archive et /projets/projet-slug pour le single. Tu pourrais toutefois avoir une base différente avec la réecriture d’URL. J’ai un cours à ce sujet dans cette formation, en utilisant notamment la fonction add_rewrite_tag(). Ça devrait marcher. C’est toujours un peu galère à bien configurer au début, mais après ça fonctionne bien.

      1. Julien

        Le 8 juillet 2022

        Bonsoir,

        En fait c’est pas pour des raisons SEO, du moins pas ici en terme de Portfolio. Mais pour d’autres CPT je voulais soulever la question pour voir si une alternative plus conventionnelle existait autre que la réécriture d’url.

        Pour la fonction taxomanie, je pense pas, sauf erreur de ma part, que je puisse m’en servir ici, sachant que dans l’url je veux voir aparraitre le titre du projet portfolio.

        Bien à vous.

        1. Maxime BJ

          Le 9 juillet 2022

          Le paramètre de rewrite dans la définition du CPT permet de changer l’URL qui est définie par défaut sur le slug. Mais ça le fera autant pour l’archive que les single. https://developer.wordpress.org/reference/functions/register_post_type/#rewrite. Je ne pense pas qu’il n’y ai d’autres choix que d’utiliser les rewrites rules du coup.

  8. adam Refined

    Le 26 juin 2023

    Hello Maxime. Quand tu fais un site à un client, pour l’URL d’un CPT, tu changes en dure dans le code (comme tu as fais dans ce cours) ou alors tu ajoutes une option réglages > permaliens, dans la section « facultatif » en dessous de
    « Préfixe des catégories » ?

    1. Maxime BJ

      Le 26 juin 2023

      Tu le changes directement dans le rewrite du CPT. Ce n’est pas une option que le client devrait pouvoir modifier. Et au pire tu pourras le modifier dans le code plus tard (en faisant les redirections 301 nécessaires). Tu pourrais bien entendu proposer l’option bien entendu dans réglages mais à quoi bon ?

      1. Adam Refined

        Le 26 juin 2023

        Ça lui donnerait plus de « liberté » si plus tard, il veut changer l’URL pour X raisons. Mais, tu as raison, ç’a assez peu d’intérêt pour un site fait pour un client unique. C’est surtout intéressant quand on commercialise le thème (envato market par ex) quand il y a pleins de clients potentiels :).

        1. Maxime BJ

          Le 26 juin 2023

          Oui voilà exactement ! Dans le cas d’un thème en vente, le champ d’option est judicieux. Pour un client, si tu utilises déjà ACF, tu as une interface pour créer un CPT visuellement, avec le champ permettant de modifier l’URL à tout moment.

Laisser un commentaire