Percorso plug-in personalizzato in Wordpress


12

Ok, quindi la mia domanda è abbastanza semplice. Devo implementare alcune regole di routing personalizzate per il mio plugin. Tali percorsi prenderebbero solo un argomento (quindi niente di complicato) e sembrerebbero: http://www.example.org/myroute/myargument

E idealmente, questo chiamerebbe una classe personalizzata e visualizzerebbe un modello personalizzato (che potrebbe accedere direttamente alla classe).

Qual è l'approccio migliore per questo? Saluti

Risposte:


15

Devi fare tre cose importanti:

  1. Crea una regola di riscrittura personalizzata per trasformare parti dell'URI in valori passati index.php.
  2. Aggiungi myroutee myargumentalla whitelist delle variabili di query di WordPress, in modo che WordPress non le ignori solo quando compaiono in una stringa di query.
  3. Svuota le regole di riscrittura.

In primo luogo, raccomanderò invece di scegliere http://www.example.org/myroute/myargumentun prefisso o un suffisso speciale per indicare quando l'URI dovrebbe essere considerato uno di questi "percorsi" speciali. Per il bene di questo esempio, ho scelto il prefisso api, in modo che lo sia http://www.example.org/api/myroute/myargument. Ho scelto apiperché quando ho fatto qualcosa di RESTful, come quello su cui sembra stia lavorando, era per un'API.

Il codice

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;
}

Ripartizione rapida

È tutto abbastanza semplice. Il modello regex viene aggiunto a un elenco di tutte le regole di riscrittura in WordPress e il modello personalizzato si trova in cima all'elenco. Quando il modello viene abbinato, WordPress smetterà di cercare nell'elenco delle regole di riscrittura e utilizzerà i valori acquisiti del regex al posto dei riferimenti ( $matches[1]e $matches[2]) nella stringa di query passata a index.php.

L'aggiunta delle variabili di query myroutee myargumentalla whitelist fa sì che WordPress presti attenzione a loro anziché scartarle.

Modo alternativo di "spazio dei nomi" del percorso personalizzato

Se si desidera evitare l'utilizzo /api/come prefisso, è possibile utilizzare invece una variabile stringa / campo della query. Per fare una cosa del genere, cambiate regex in qualcosa del genere (.*?)/(.+?)\\?api=1e quindi aggiungete apicome parametro aggiuntivo alla array_push()chiamata effettuata my_insert_query_vars().

Ciò cambierebbe il percorso personalizzato in modo che si inneschi in qualsiasi momento api=1è il primo elemento della stringa di query, ad esempio per cui si innescherebbe http://example.com/anytext/anytext?api=1.

Ignora l'uso del termine "spazio dei nomi" - lo hai usato solo per brevità.

Se non si 'spazio dei nomi' con un prefisso o un suffisso, si finirà con la collisione di schemi URI. Questo perché WordPress non avrà modo di distinguere il tuo modello personalizzato da uno destinato a essere un post o una pagina. Come potrebbe sapere WordPress che myroutenon è una tassonomia, un termine o una pagina principale?

Spero che questo ti aiuti.


1
Nota pratica: regole definite nel seguente my_insert_rewrite_rulesordine di definizione! Inizia prima con la regola più lunga, poi passa al più semplice, altrimenti / api / myroute sovrascriverà / api / myroute / myargument.
emc

1
@npc Questo è un punto importante da tenere presente quando si creano regole di riscrittura personalizzate, anche loro possono scontrarsi in quel modo. Nell'esempio sopra, tuttavia, questo non è un problema perché / api / myroute semplicemente non sarebbe un percorso valido.
Eddiemoya,

Come si può caricare un modello personalizzato dalla propria directory dei plugin ogni volta che viene richiesta la pagina example.org/api/myroute/myargument ?
Matt Keys,

1
Ecco la soluzione attuale e completa del wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor

6

Per espandere un po 'quello che ha fatto eddiemoya sopra:

Come il poster originale di questa domanda, volevo creare una riscrittura personalizzata e fornire anche un modello personalizzato per quella pagina di riscrittura. Il codice di edditmoya mi ha fatto iniziare nella giusta direzione e ho aggiunto una funzione aggiuntiva per pubblicare il mio modello personalizzato quando si accede alla pagina.

Il modello personalizzato potrebbe trovarsi ovunque, nel mio caso è memorizzato nella directory dei plugin.

Volevo anche solo verificare se le regole di riscrittura dovevano essere scaricate durante l'attivazione del plugin, quindi l'ho messo su register_activation_hook

Vedi sotto per l'esempio completo di ciò che ho fatto:

AGGIORNATO semplificato sulla base dei consigli di 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' ) );

1
puoi anche solo usare add_rewrite_endpoint, che genererà la regola per te e aggiungerà la query var in una volta sola. anche se stai aggiungendo le tue regole di riscrittura, suggerisco la add_rewrite_rulefunzione invece di filtrare rewrite_rules_array.
Milo,

Grazie Milo, ho aggiornato il codice per utilizzare add_rewrite_rule invece di filtrare l'array di riscrittura. Ho esaminato add_rewrite_endpoint ma penso che add_rewrite_tag possa adattarsi meglio alle mie esigenze. Sembra che add_rewrite_endpoint sia utile soprattutto se si desidera aggiungere ulteriori argomenti alle riscritture WP esistenti. Correggimi se sbaglio qui.
Matt Keys,

1
Mi piace l'approccio orientato agli oggetti. Troppi sviluppatori WP non sanno ancora come utilizzare OOP. Grazie per aver cercato di ripristinare la mia fiducia negli sviluppatori PHP. ;)
Arvid,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.