web-dev-qa-db-fra.com

Itinéraire du plugin personnalisé dans Wordpress

Bon alors ma question est assez simple. Je dois implémenter des règles de routage personnalisées pour mon plugin. Ces routes ne prendraient qu’un seul argument (donc rien de compliqué) et ressembleraient ainsi: http://www.example.org/myroute/myargument

Et idéalement, cela appellerait une classe personnalisée et afficherait un modèle personnalisé (pouvant directement accéder à la classe).

Quelle est la meilleure approche pour cela? À votre santé

10
Fran

Vous devez faire 3 choses importantes.

  1. Créer une règle de réécriture personnalisée pour transformer des parties de l'URI en valeurs transmises à index.php
  2. Ajoutez myroute et myargument en tant que requête vars à wordpress sait qu'ils sont des paramètres $ _GET valides lorsque les règles de réécriture leur transmettent quelque chose
  3. Videz les règles de réécriture.

Premièrement, je vais recommander au lieu de http://www.example.org/myroute/myargument de choisir un préfixe ou un suffixe spécial pour indiquer quand l'uri doit être considéré comme l'un de ces "itinéraires" spéciaux. Pour les besoins de cet exemple, j'ai choisi le préfixe api, de sorte qu'il s'agisse de http://www.example.org/api/myroute/myargument. J'ai choisi api parce que lorsque j'ai fait quelque chose de reposant, comme ce sur quoi vous semblez travailler, c'était pour une API.

Le code

add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_filter( 'query_vars','my_insert_query_vars' );
add_action( 'wp_loaded','my_flush_rules' );

// flush_rules() if our rules are not yet included
function my_flush_rules(){
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['api/(.*?)/(.+?)'] ) ) {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }
}

// Adding a new rule
function my_insert_rewrite_rules( $rules )
{
    $newrules = array();
    $newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
    return $newrules + $rules;
}

// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars )
{
    array_Push($vars, 'myroute', 'myargument');
    return $vars;
}

Répartition rapide

Tout cela est assez simple, le motif regex est ajouté à la liste de toutes les règles de réécriture dans WordPress, et votre motif personnalisé est en bas de la liste. Lorsqu'il y a correspondance avec le motif, WordPress cesse de regarder et passe les valeurs capturées aux références arrière de la chaîne index.php.

L'ajout des vars de requête les rend simplement myroute et myargument valides pour index.php.

Manière alternative de 'namespacing' votre route personnalisée

Si vous souhaitez éviter d'utiliser /api/ comme préfixe, vous pouvez également utiliser une chaîne de requête var. Pour faire quelque chose comme ça, changez l'expression rationnelle en quelque chose comme (.*?)/(.+?)\\?api=1 et ajoutez ensuite api comme paramètre supplémentaire à la fonction array_Push dans my_insert_query_vars().

Cela changerait l'itinéraire personnalisé pour qu'il soit déclenché à chaque fois qu'il y a http://example.com/anytext/anytext?json=1.

Ignorez l'utilisation du terme 'namespacing' - simplement utilisé pour des raisons de concision.

Si vous ne possédez pas d '"espace de noms" avec un préfixe ou un suffixe, vous vous retrouverez avec des motifs uri en collision. En effet, WordPress n'aura aucun moyen de distinguer votre modèle personnalisé de celui destiné à être un message ou une page. Comment wordpress pourrait-il savoir si cette "route" n'est ni une taxonomie, ni un terme, ni une page parent?

J'espère que cela t'aides.

12
eddiemoya

Pour développer un peu ce que eddiemoya a fait ci-dessus:

Tout comme l'affiche originale de cette question, je voulais créer une réécriture personnalisée et également fournir un modèle personnalisé pour cette page de réécriture. Le code de edditmoya m'a permis de démarrer dans la bonne direction et j'ai ajouté une fonction supplémentaire pour servir mon modèle personnalisé lors de l'accès à la page.

Le modèle personnalisé pourrait être situé n'importe où, dans mon cas, il est stocké dans le répertoire du plugin.

Je voulais aussi seulement vérifier si les règles de réécriture devaient être effacées lors de l'activation du plugin, je l'ai donc mise sur register_activation_hook

Voir ci-dessous pour un exemple complet de ce que j'ai fait:

MIS À JOURsimplifié sur la base des conseils de milo

class Your_Class
{

    public function init()
    {
        add_filter( 'template_include', array( $this, 'include_template' ) );
        add_filter( 'init', array( $this, 'rewrite_rules' ) );
    }

    public function include_template( $template )
    {
        //try and get the query var we registered in our query_vars() function
        $account_page = get_query_var( 'account_page' );

        //if the query var has data, we must be on the right page, load our custom template
        if ( $account_page ) {
            return PATH_TO_PLUGIN_TEMPLATES_DIR . 'register.php';
        }

        return $template;
    }

    public function flush_rules()
    {
        $this->rewrite_rules();

        flush_rewrite_rules();
    }

    public function rewrite_rules()
    {
        add_rewrite_rule( 'account/(.+?)/?$', 'index.php?account_page=$matches[1]', 'top');
        add_rewrite_tag( '%account_page%', '([^&]+)' );
    }

}

add_action( 'plugins_loaded', array( new Your_Class, 'init' ) );

// One time activation functions
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );
4
Matt Keys