Aller au contenu principal
Version: Next

URLRewriter

La façade URLRewriter permet de déclarer des rewrite rules WordPress avec une API fluide, puis de récupérer facilement les variables capturées dans l'URL.

Cas d'usage

Utilisez cette façade pour exposer des URLs lisibles (SEO-friendly) tout en conservant une logique de routage WordPress (index.php?...).

use Elementum\Facades\URLRewriter;

URLRewriter::for('hebergements')
    ->type('pagename')
    ->segment('item_slug')
    ->segment('item_id', URLRewriter::INT)
    ->register();

Ensuite, vous pouvez récupérer les valeurs :

$slug = URLRewriter::get('item_slug');
$id = URLRewriter::get('item_id');

Exemples complets

Fiche hébergement avec slug et ID

Objectif : exposer une URL comme /hebergements/chalet-des-alpes/42 au lieu de /?pagename=hebergements&item_slug=chalet-des-alpes&item_id=42.

1. Déclaration de la rule (hook init) :

use Elementum\Facades\URLRewriter;

add_action('init', function () {
    URLRewriter::for('hebergements')
        ->type('pagename')
        ->segment('item_slug')
        ->segment('item_id', URLRewriter::INT)
        ->register();
});

La rule générée redirige hebergements/([^/]+)/([0-9]+) vers index.php?pagename=hebergements&item_slug=$matches[1]&item_id=$matches[2].

2. Récupération dans le controller :

use Elementum\Facades\URLRewriter;

class HebergementsController extends Controller
{
    public function index(): array
    {
        $slug = URLRewriter::get('item_slug'); // "chalet-des-alpes"
        $id   = URLRewriter::get('item_id');   // "42"

        $hebergement = Hebergement::find((int) $id);

        return compact('hebergement');
    }
}

Résultat : /hebergements/chalet-des-alpes/42 est une URL propre, lisible et indexable, qui charge la page WordPress hebergements avec les variables disponibles dans le controller.


Multi-type avec base capturante

Objectif : gérer plusieurs types de contenus sous une même rule — ex. /prestations/massage/12, /hebergements/chalet/42, /activites/rando/7 — sans déclarer une rule par type.

1. Déclaration de la rule :

add_action('init', function () {
    $types = 'prestations|hebergements|activites';

    URLRewriter::for($types)
        ->captureBase('item_type')
        ->param('standalone', '1')
        ->segment('item_slug')
        ->segment('item_id', URLRewriter::INT)
        ->register();
});

La base devient un groupe capturant : (prestations|hebergements|activites)/([^/]+)/([0-9]+)index.php?standalone=1&item_type=$matches[1]&item_slug=$matches[2]&item_id=$matches[3].

2. Récupération dans le controller :

$type = URLRewriter::get('item_type'); // "hebergements"
$slug = URLRewriter::get('item_slug'); // "chalet"
$id   = URLRewriter::get('item_id');   // "42"

Résultat : une seule rule gère les trois types. Le paramètre fixe standalone=1 permet de distinguer ces requêtes dans la logique applicative (ex. pour afficher un template dédié sans sidebar).


Listing WordPress filtré par segment (page classique)

Objectif : la page WordPress biens affiche un listing de biens immobiliers. On veut que /biens/acheter et /biens/louer soient des URLs propres qui chargent la même page mais filtrent la WP_Query selon le segment.

1. Déclaration de la rule :

add_action('init', function () {
    URLRewriter::for('biens')
        ->type('pagename')
        ->segment('transaction_type', 'acheter|louer')
        ->register();
});

La rule générée : biens/(acheter|louer)index.php?pagename=biens&transaction_type=$matches[1].

astuce

La regex acheter|louer est passée directement comme contrainte du segment — seules ces deux valeurs sont acceptées, toute autre URL ne correspondra pas à cette rule.

2. Modification de la WP_Query dans le controller :

use Elementum\Facades\URLRewriter;

class BiensController extends Controller
{
    #[Template('post_type_archive', params: ['estate'])]
    public function index(): array
    {
        $transaction = URLRewriter::get('transaction_type'); // "acheter" ou "louer"
        $args = [
            'posts_per_page' => 12,
        ];

        if ($transaction) {
            $args['tax_query'] = [[
                'taxonomy' => 'transaction',
                'field'    => 'slug',
                'terms'    => $transaction,
            ]];
        }

        $estateQuery = $this->getPostType('estate')->getQuery($args);

        return compact('estateQuery', 'transaction');
    }
}

3. Utilisation dans le template Twig :

<h1>Biens à {{ transaction ?? 'vendre ou louer' }}</h1>

<nav>
    <a href="/biens/acheter" class="{{ transaction == 'acheter' ? 'active' : '' }}">Acheter</a>
    <a href="/biens/louer"   class="{{ transaction == 'louer'   ? 'active' : '' }}">Louer</a>
</nav>

{% wp_query estateQuery %}
    <article>{{ post.title }}</article>
{% endwp_query %}

Résultat :

URL visitéetransaction_typeBoucle affichée
/biens(vide)Tous les biens
/biens/acheter"acheter"Biens filtrés par taxonomie
/biens/louer"louer"Biens filtrés par taxonomie

La page WordPress biens reste unique — c'est le segment capturé qui pilote le filtre, sans JavaScript ni paramètre ? visible dans l'URL.


Méthodes

for(string $base): static

Point d'entrée de la chaîne fluide.

  • base : segment principal de l'URL (ex: hebergements).

type(string $type): static

Définit le type de query WordPress injecté dans la rule.

Exemples fréquents : pagename, post_type, category_name.

segment(string $name, string $regex = self::ANY): static

Ajoute un segment dynamique capturé dans l'URL.

  • name : nom de la query var
  • regex : expression de capture (constantes disponibles ci-dessous)

captureBase(string $queryVar): static

Marque la base comme groupe capturant et mappe la valeur capturée vers une query var.

Utile quand la base est une alternance dynamique (ex : type1|type2|type3). La regex générée devient (base)/seg1/seg2 au lieu de base/seg1/seg2, et l'indice des segments est décalé automatiquement.

$types = 'prestations|hebergements|activites';

URLRewriter::for($types)
    ->captureBase('item_type')
    ->param('standalone', '1')
    ->segment('item_slug')
    ->segment('item_id', URLRewriter::INT)
    ->register();

param(string $key, string $value): static

Ajoute un paramètre fixe (non capturé) dans la chaîne de redirect.

->param('standalone', '1') // → index.php?standalone=1&...

priority(string $priority): static

Définit la priorité de la rewrite rule :

  • top (par défaut)
  • bottom

register(): void

Enregistre la rewrite rule et les query vars associées.

get(string $name, mixed $default = null): mixed

Récupère la valeur d'une query var (get_query_var).

flush(): void

Exécute flush_rewrite_rules().

Constantes utiles

  • URLRewriter::ANY[^/]+
  • URLRewriter::SLUG[a-zA-Z0-9-]+
  • URLRewriter::INT[0-9]+
  • URLRewriter::ALPHA[a-zA-Z]+

Recommandations

  • Déclarez vos rules pendant l'initialisation WordPress (par ex. sur init).
  • Évitez d'appeler flush() à chaque requête (coûteux) : déclenchez-le lors de l'activation/mise à jour du plugin ou thème.