Ruta de complemento personalizada en Wordpress

12

Bien, entonces mi pregunta es bastante simple. Necesito implementar algunas reglas de enrutamiento personalizadas para mi complemento. Esas rutas solo tomarían un argumento (así que nada complicado) y se verían así: http://www.example.org/myroute/myargument

E idealmente, esto llamaría una clase personalizada y mostraría una plantilla personalizada (que podría acceder directamente a la clase).

¿Cuál es el mejor enfoque para esto? Salud

Fran
fuente

Respuestas:

15

Debes hacer tres cosas importantes:

  1. Cree una regla de reescritura personalizada para convertir partes del URI en valores pasados ​​a index.php.
  2. Agregue myroutey myargumenta la lista blanca de variables de consulta de WordPress, para que WordPress no solo las ignore cuando aparecen en una cadena de consulta.
  3. Vaciar las reglas de reescritura.

En primer lugar, voy a recomendar que, en lugar de hacerlo http://www.example.org/myroute/myargument, se decida por algún tipo de prefijo o sufijo especial para indicar cuándo el URI debe considerarse una de estas 'rutas' especiales. Por el bien de este ejemplo, he elegido el prefijo api, para que así sea http://www.example.org/api/myroute/myargument. Elegí apiporque cuando hice algo RESTful, como en lo que parece estar trabajando, fue para una API.

El código

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

Desglose rápido

Todo es bastante sencillo. El patrón regex se agrega a una lista de todas las reglas de reescritura en WordPress, y su patrón personalizado está en la parte superior de la lista. Cuando el patrón coincide, WordPress dejará de mirar a través de la lista de reglas de reescritura, y usará los valores capturados de la expresión regular en lugar de las referencias ( $matches[1]y $matches[2]) en la cadena de consulta pasada index.php.

Agregar las variables de consulta myroutey myargumentla lista blanca solo hace que WordPress les preste atención en lugar de descartarlas.

Manera alternativa de 'espaciar nombres' en su ruta personalizada

Si desea evitar su uso /api/como prefijo, puede utilizar una variable / campo de cadena de consulta en su lugar. Para hacer algo así, debe cambiar la expresión regular a algo así (.*?)/(.+?)\\?api=1y luego agregarla apicomo un parámetro adicional a la array_push()llamada realizada my_insert_query_vars().

Eso cambiaría la ruta personalizada para que se active en cualquier momento api=1es el primer elemento de la cadena de consulta, por ejemplo, se activaría para http://example.com/anytext/anytext?api=1.

Ignore el uso del término 'espacio de nombres', solo lo usé por brevedad.

Si no 'espacio de nombres' con un prefijo o sufijo, terminará con patrones de URI colisionantes. Esto se debe a que WordPress no tendrá forma de distinguir su patrón personalizado de uno destinado a ser una publicación o página. ¿Cómo sabría WordPress que myrouteno se trata de una taxonomía, término o página principal?

Espero que esto ayude.

eddiemoya
fuente
1
Nota práctica: las reglas se definen en el my_insert_rewrite_rulessiguiente orden de definición. Comience con la regla más larga primero y luego trabaje hasta la más simple, de lo contrario / api / myroute anulará / api / myroute / myargument.
emc
1
@npc Ese es un punto importante a tener en cuenta al crear reglas de reescritura personalizadas, también pueden colisionar de esa manera. Sin embargo, en el ejemplo anterior, eso no es un problema porque / api / myroute simplemente no sería una ruta válida.
eddiemoya
¿Cómo podría alguien cargar una plantilla personalizada desde su directorio de complementos cuando se solicita la página example.org/api/myroute/myargument ?
Matt Keys
1
Aquí está la solución real y completa de wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor
6

Para ampliar un poco lo que eddiemoya hizo arriba:

Al igual que el póster original de esta pregunta, quería crear una reescritura personalizada y también entregar una plantilla personalizada para esa página de reescritura. El código de edditmoya me ayudó a comenzar en la dirección correcta, y agregué una función adicional para servir mi plantilla personalizada cuando se accede a la página.

La plantilla personalizada podría ubicarse en cualquier lugar, en mi caso, se almacena en el directorio de complementos.

También solo quería verificar si las reglas de reescritura debían eliminarse durante la activación del complemento, así que lo puse en un register_activation_hook

Vea a continuación el ejemplo completo de lo que hice:

ACTUALIZADO simplificado en base a los consejos 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' ) );
Matt Keys
fuente
1
también puede usarlo add_rewrite_endpoint, lo que generará la regla para usted y agregará la consulta var de una vez. Además, si está agregando sus propias reglas de reescritura, sugiero la add_rewrite_rulefunción en lugar de filtrar rewrite_rules_array.
Milo
Gracias Milo, actualicé el código para usar add_rewrite_rule en lugar de filtrar la matriz de reescritura. Miré add_rewrite_endpoint pero creo que add_rewrite_tag puede ser mejor para mis necesidades. Parece que add_rewrite_endpoint es principalmente útil si desea agregar un argumento adicional a las reescrituras de WP existentes. Corrígeme si me equivoco aquí.
Matt Keys
1
Me gusta el enfoque orientado a objetos. Demasiados desarrolladores de WP todavía no saben cómo usar OOP. Gracias por intentar restaurar mi fe en los desarrolladores de PHP. ;)
Arvid