Rută personalizată pentru plugin în WordPress

10 iul. 2012, 22:14:25
Vizualizări: 23K
Voturi: 16

Bine, întrebarea mea este destul de simplă. Am nevoie să implementez niște reguli de rutare personalizate pentru plugin-ul meu. Aceste rute ar accepta doar un singur argument (deci nimic complicat) și ar arăta astfel: http://www.example.org/myroute/myargument

Și în mod ideal, aceasta ar apela o clasă personalizată și ar afișa un șablon personalizat (care ar putea accesa direct clasa).

Care este cea mai bună abordare pentru acest lucru? Mulțumesc

0
Toate răspunsurile la întrebare 2
4
16

Trebuie să faci trei lucruri importante:

  1. Crează o regulă personalizată de rescriere pentru a transforma părți din URI în valori transmise către index.php.
  2. Adaugă myroute și myargument la lista de variabile de interogare permise în WordPress, astfel încât WordPress să nu le ignore când apar într-un șir de interogare.
  3. Resetează regulile de rescriere.

În primul rând, recomand să folosești un prefix sau sufix special pentru a indica când URI-ul ar trebui considerat una dintre aceste 'rute' speciale. Pentru acest exemplu, am ales prefixul api, astfel încât adresa să fie http://www.example.org/api/myroute/myargument. Am ales api pentru că atunci când am implementat ceva RESTful, similar cu ceea ce pare că lucrezi, a fost pentru un API.

Codul

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

// Resetează regulile dacă regulile noastre nu sunt încă incluse
function my_flush_rules() {
    $rules = get_option( 'rewrite_rules' );

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

// Adăugarea unei noi reguli
function my_insert_rewrite_rules( $rules ) {
    $newrules = array();
    $newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
    return $newrules + $rules;
}

// Adăugarea variabilelor id astfel încât WordPress să le recunoască
function my_insert_query_vars( $vars ) {
    array_push( $vars, 'myroute', 'myargument' );
    return $vars;
}

Scurtă explicație

Este destul de simplu. Modelul regex este adăugat la lista tuturor regulilor de rescriere din WordPress, iar modelul tău personalizat este în partea de sus a listei. Când modelul este potrivit, WordPress va înceta să mai caute prin lista de reguli de rescriere și va folosi valorile capturate ale regex în locul referințelor ($matches[1] și $matches[2]) din șirul de interogare transmis către index.php.

Adăugarea variabilelor de interogare myroute și myargument la lista de permisiuni face ca WordPress să le ia în considerare în loc să le ignore.

Altă metodă de a 'namespace-ui' ruta personalizată

Dacă dorești să eviți utilizarea prefixului /api/, poți folosi în schimb o variabilă/câmp de interogare. Pentru a face asta, ai putea schimba regex-ul în ceva de genul (.*?)/(.+?)\\?api=1 și apoi să adaugi api ca parametru suplimentar la apelul array_push() din my_insert_query_vars().

Asta ar schimba ruta personalizată astfel încât să se activeze ori de câte ori api=1 este primul element al șirului de interogare, de exemplu, s-ar activa pentru http://example.com/anytext/anytext?api=1.

Ignoră utilizarea termenului 'namespacing' - l-am folosit doar pentru concizie.

Dacă nu folosești un prefix sau un sufix pentru a 'namespace-ui', vei ajunge cu modele de URI care se suprapun. Acest lucru se întâmplă pentru că WordPress nu va avea nicio modalitate de a distinge modelul tău personalizat de unul destinat să fie o postare sau o pagină. Cum ar ști WordPress că myroute nu este o taxonomie, un termen sau o pagină părinte?

Sper că acest lucru te ajută.

11 iul. 2012 03:28:19
Comentarii

Notă utilă: regulile definite în my_insert_rewrite_rules urmează ordinea definiției! Începeți cu cea mai lungă regulă prima dată, apoi continuați cu cele mai simple, altfel /api/myroute va înlocui /api/myroute/myargument.

emc emc
25 feb. 2014 19:42:52

@npc Acesta este un aspect important de reținut atunci când creați reguli personalizate de rescriere, ele se pot suprapune în acest fel. În exemplul de mai sus însă, aceasta nu este o problemă deoarece /api/myroute pur și simplu nu ar fi o cale validă.

eddiemoya eddiemoya
3 mar. 2014 21:37:13

Cum ar putea cineva încărca un șablon personalizat din directorul pluginului lor ori de câte ori este solicitată pagina http://www.example.org/api/myroute/myargument?

Matt Keys Matt Keys
21 sept. 2014 13:36:17

Iată soluția actuală și completă oferită de WordPress: https://codex.wordpress.org/Rewrite_API/add_rewrite_rule

Imran Zahoor Imran Zahoor
12 sept. 2015 23:15:56
3

Pentru a dezvolta puțin ceea ce a făcut eddiemoya mai sus:

La fel ca autorul inițial al acestei întrebări, am vrut să creez o rescriere personalizată și să furnizez un șablon personalizat pentru acea pagină rescrisă. Codul de la edditmoya m-a orientat în direcția corectă, iar eu am adăugat o funcție suplimentară pentru a încărca șablonul meu personalizat atunci când pagina este accesată.

Șablonul personalizat poate fi localizat oriunde, în cazul meu este stocat în directorul pluginului.

De asemenea, am vrut să verific dacă regulile de rescriere trebuie reîmprospătate doar în timpul activării pluginului, așa că am plasat această acțiune pe un register_activation_hook

Mai jos vedeți exemplul complet al ceea ce am făcut:

ACTUALIZAT simplificat pe baza sfatului de la 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 )
    {
        //încercăm să obținem variabila de interogare pe care am înregistrat-o în funcția noastră query_vars()
        $account_page = get_query_var( 'account_page' );

        //dacă variabila de interogare are date, trebuie să fim pe pagina corectă, încărcăm șablonul nostru personalizat
        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' ) );

// Funcții de activare unice
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );
24 sept. 2014 02:14:05
Comentarii

poți folosi și add_rewrite_endpoint, care va genera regula pentru tine și va adăuga variabila de interogare într-un singur pas. de asemenea, dacă adaugi propriile reguli de rescriere, sugerez funcția add_rewrite_rule în loc să filtrezi rewrite_rules_array.

Milo Milo
24 sept. 2014 02:31:05

Mulțumesc Milo, am actualizat codul pentru a folosi add_rewrite_rule în loc să filtrez array-ul de rescriere. M-am uitat la add_rewrite_endpoint, dar cred că add_rewrite_tag ar putea fi mai potrivit pentru nevoile mele. Se pare că add_rewrite_endpoint este mai util în principal dacă vrei să adaugi argumente suplimentare la rescrierile existente din WP. Corectează-mă dacă greșesc aici.

Matt Keys Matt Keys
24 sept. 2014 03:03:30

Îmi place abordarea orientată pe obiecte. Prea mulți dezvoltatori WP încă nu știu să folosească OOP. Mulțumesc că încerci să-mi restaurezi credința în dezvoltatorii PHP. ;)

Arvid Arvid
19 feb. 2018 19:36:36