Créer ses propres URLs dynamiques dans WordPress

La mise en place d’applications web PHP et de parcours utilisateurs complexes requiert très souvent la création de routes uniques pour intercepter les actions des utilisateurs.

Réinitialisation de mot de passe, identification utilisateur, création de compte, déconnexion, etc. Tous ces processus possèdent idéalement leur propre adresse web sur votre domaine. Mais comment créer de telles routes dans un contexte d’application web développée avec WordPress ?


Améliorer ses compétences WordPress

Cet article fait partie d’une série de leçons présentant les différentes APIs et fonctions PHP disponibles dans WordPress. Découvrez l’article de présentation Comment devenir un bon développeur back-end WordPress ? pour en savoir plus et accéder aux autres leçons.

La réécriture d’URLs dans le CMS WordPress

Pourquoi créer de nouvelles routes ?

Vous le savez probablement déjà, on dispose par défaut de beaucoup d’URLs pré-construites automatiquement par le cœur de WordPress :

  • l’enregistrement d’un type de contenu personnalisé « livre » entraîne la création d’une page d’archives sur /livres et de pages uniques par livre sur /livre/<nom-du-livre>,
  • l’enregistrement d’une taxonomie maison « genre » crée aussi des pages d’archives listant les posts relatifs, sur /genre/<nom-du-genre>
  • la création d’une page ou d’un article génère une URL propre permettant l’accès au contenu.

Mais comment faire pour créer nos propres URLs programmatiquement en PHP dans WordPress sans nécessairement être lié à la création d’un contenu, d’un type de contenu ou d’une taxonomie ?

Créer des règles d’écriture d’URL sur-mesure pour répondre aux besoins de votre application web

Prenons l’exemple de l’annuaire Miam.Store que j’ai développé pour un client. Un routeur PHP a été mis en place pour créer de nombreuses URLs répondant à des actions spécifiques des utilisateurs en front-end, comme par exemple :

  • /order/<id>/<token> pour permettre à un acheteur de suivre l’avancement de sa commande en direct via une adresse web unique et protégée ne nécessitant pas d’authentification utilisateur (mais un token secret),
  • /verify/<user_id> pour déclencher le parcours de vérification par SMS du numéro de téléphone d’un utilisateur,
  • de nombreuses routes pour héberger les pages du tableau de bord des professionnels :
    • /dashboard/orders pour suivre les commandes,
    • /dashboard/order/<id> pour afficher les détails d’une commande,
    • /dashboard/invoices pour lister des factures,
    • /dashboard/invoice/<id> pour afficher les détails d’une facture…

Un tel tableau de bord est précisément ce que nous allons tenter de recréer simplement dans l’exercice suivant.

Exemple pratique : créer un tableau de bord utilisateur

Le but de cet exercice sera donc :

  1. d’enregistrer, en PHP via une extension WordPress, une route d’URL dynamique /dashboard/<page> accessible aux utilisateurs connectés,
  2. de charger un template PHP provenant du dossier /templates/ de notre plugin,
  3. d’y afficher un listing d’onglets et le contenu de la sous-page actuellement visitée.
Créer des URLs Rewrite Rules personnalisées dans WordPress
Résultat du tableau de bord créé, sur une URL type /dashboard/<sous-page>

Et tout ça sans avoir à créer une seule page dans notre site WordPress, ni copier-coller de shortcode, ni inventer un template de page, ni créer de type de contenu. Des URLs 100% issues du code et gérées par le code ! Pratique non ?

Code sur GitHub

Une extension WordPress fonctionnelle a été créée pour accompagner cet article. Elle est disponible sur GitHub. Après installation et activation, visitez votre page d’administration Permaliens pour les regénérer, puis vous pourrez visiter la page /dashboard/home pour voir le résultat.

Créer une Rewrite Rule sur-mesure

Du code vaut mieux qu’un long discours d’introduction :

/**
 * Enregistrement des nouvelles routes que l'on souhaite ajouter.
 *
 * @return void
 */
function register_new_rules() {
	add_rewrite_tag( '%dashboard%', '([^&]+)' );
	add_rewrite_tag( '%dashboard_page%', '([^&]+)' );
	add_rewrite_rule( 'dashboard/([a-z0-9-]+)[/]?$', 'index.php?dashboard=1&dashboard_page=$matches[1]', 'top' );
}
add_action( 'init', __NAMESPACE__ . '\\register_new_rules', 10, 1 );

Intéressons-nous d’abord à la fonction add_rewrite_rule(). Elle nous permet d’enregistrer un nouveau regex d’URL et de préciser comment interpréter ce regex. Dans notre exemple ci-dessus :

  1. premier argument : on autorise de nouvelles URLs site.fr/dashboard/<page>,
  2. deuxième argument : on demande à WordPress de les interpréter, sous le capot, en les transformant en des paramètres (appelés query vars en anglais) :
    1. dashboard avec une valeur 1
    2. dashboard_page avec la valeur indiquée après /dashboard/ dans l’URL (comme orders ou home par exemple),
  3. troisième argument : on indique la priorité de cette règle, les routes à priorité top étant prioritaires sur celles ayant une priorité bottom.

On comprend alors l’intérêt des deux premiers appels à la fonction add_rewrite_tag() qui ont pour mission de définir les nouvelles query vars que l’on souhaite autoriser dans le routeur WordPress afin d’être rendues accessibles dans nos autres fonctions.

À noter

Après l’enregistrement de nouveaux tags et règles d’écriture, n’oubliez pas de visiter la page d’administration Permaliens pour les regénérer. Alternativement, penser à appeler la fonction flush_rewrite_rules() à l’activation de votre extension pour enregistrer vos nouvelles routes et regénérer les routes mises en cache par le cœur WordPress.

Comment débugger les paramètres d’URLs et la requête en cours d’une page WordPress ?

Il est vital d’installer et d’activer Query Monitor lors du développement de votre application web WordPress.

Débug des requêtes de pages WordPress avec Query Monitor
Débug des requêtes de pages WordPress avec Query Monitor

Comme vous constatez sur l’image ci-dessus, Query Monitor propose un onglet « Requête » (au singulier, à ne pas confondre avec l’onglet « Requêtes » au pluriel qui liste toutes les requêtes SQL exécutées sur la page en cours — onglet lui aussi fort pratique d’ailleurs !).

Sur cet onglet, vous trouverez bon nombre d’informations sur l’interprétation de l’URL de la page en cours par WordPress, la ou les règles de réécriture correspondantes, et toutes les variables de requête extraites de l’URL.

Dans l’exemple ci-dessus, on remarque bien nos deux nouvelles variables dashboard et dashboard_page et leur valeur lors d’une visite de la page /dashboard/orders.

Lire les paramètres passés en URL

Maintenant que nos nouvelles URLs sont enregistrées, il nous faut pouvoir lire les nouvelles query vars définies ci-dessus pour vérifier si un utilisateur est actuellement en train de visiter une page du tableau de bord, et savoir quelle sous-page est visitée.

On utilise la fonction get_query_var( 'dashboard' ) pour vérifier si l’on visite une page de tableau de bord, et get_query_var( 'dashboard_page' ) pour connaître le slug de page envoyé via cette nouvelle URL propre.

Ainsi, sur une page type monsite.fr/dashboard/home :

  • la première fonction retournera une valeur 1,
  • la seconde retournera une valeur home.
/**
 * Vérification si la page actuellement visitée est une page du Tableau de bord.
 *
 * @return boolean
 */
function is_dashboard_page() {
	return (int) get_query_var( 'dashboard' ) === 1 && ! empty( get_query_var( 'dashboard_page' ) );
}

La fonction ci-dessus va donc nous permettre de savoir si la requête en cours concerne bien une page du tableau de bord.

Charger un template PHP spécifique sur cette nouvelle route

/**
 * Chargement d'un template PHP spécifique si l'on visite des pages /dashboard/.
 *
 * @param string $template
 * @return string
 */
function load_custom_template_on_dashboard_page( $template ) {
	if ( is_dashboard_page() ) {
		return sprintf( '%1$s%2$stemplates%2$sdashboard.php', untrailingslashit( MSK_REWRITE_DIR ), DIRECTORY_SEPARATOR );
	}

	return $template;
}
add_filter( 'template_include', __NAMESPACE__ . '\\load_custom_template_on_dashboard_page' );

Maintenant que l’on sait vérifier si une visite concerne notre nouveau tableau de bord, on va charger notre propre template PHP (hébergé dans le dossier de notre extension) grâce au filtre template_include. Ce dernier nous permet d’indiquer à WordPress que l’on veut potentiellement charger un autre fichier PHP à la place de celui chargé par le CMS.

Si on visite une page du tableau de bord, on charge alors le fichier template /templates/dashboard.php hébergé dans notre extension.

Aller plus loin

On pourrait rendre cette logique encore plus dynamique en utilisant la fonction locate_template pour vérifier si un fichier dashboard.php existe dans le dossier du thème ou sous-thème actif, donnant ainsi la possibilité à d’autres développeurs d’écraser/modifier l’affichage du tableau de bord. C’est ainsi que fonctionne WooCommerce en proposant des views PHP par défaut dans ses fichiers d’extension, fichiers qui peuvent être remplacés et modifiés si ils sont présents dans le dossier woocommerce du thème actif.

Je ne m’attarde pas sur le contenu du template dashboard.php que vous pouvez décortiquer librement car ce n’est pas l’objectif premier de ce tutoriel.

Il présente simplement des onglets à gauche et le contenu de l’onglet actif à droite, reprenant le principe de la zone Mon Compte présente dans WooCommerce. C’est dans ce template que vous pourrez afficher les informations que vous souhaitez.

Intercepter les visites de notre URL et rediriger les utilisateurs non-identifiés

Pour terminer, voyons comment on peut intercepter les visites du tableau de bord par des utilisateurs non-connectés afin de les rediriger vers la page du formulaire d’authentification.

/**
 * Redirection des utilisateurs non-connectés vers la page d'accueil.
 *
 * @return void
 */
function redirect_non_logged_in_users() {
	if ( is_dashboard_page() && ! is_user_logged_in() ) {
		wp_safe_redirect( wp_login_url( get_dashboard_url() ) );
		exit();
	}
}
add_action( 'template_redirect', __NAMESPACE__ . '\\redirect_non_logged_in_users', 10, 1 );

On exécute une fonction sur le hook template_redirect : cet événement est déclenché dans le cycle de vie WordPress avant la génération des headers de la page, ce qui permet d’intercepter les visites très tôt et d’éventuellement rediriger certains utilisateurs.

C’est ce qu’on fait ici : si la visite concerne une page du tableau de bord (is_dashboard_page()) et que l’utilisateur n’est pas connecté (! is_user_logged_in()), on le redirige vers la page d’identification (wp_login_url() avec l’URL du tableau de bord en paramètre pour re-rediriger l’utilisateur après son identification).


Et voila ! En quelques lignes de code dans une extension maison, on a réussi à enregistrer de nouvelles URLs dans notre site WordPress et afficher un tableau de bord uniquement avec du code.

N’hésitez pas à partager en commentaire les parcours utilisateurs sur-mesure que vous avez pu créer grâce à la réécriture d’URL dans WordPress !


Vous avez aimé cet article ?

Partagez-le sur vos réseaux sociaux en guise de remerciement :)


Laisser un commentaire