Ruta personalizada de plugin en WordPress
Bien, mi pregunta es bastante simple. Necesito implementar algunas reglas de enrutamiento personalizadas para mi plugin. Estas rutas solo tomarían un argumento (nada complicado) y se verían así: http://www.example.org/myroute/myargument
Y lo ideal sería que esto llamara a una clase personalizada y mostrara una plantilla personalizada (que pudiera acceder directamente a la clase).
¿Cuál es el mejor enfoque para esto? Gracias
Necesitas hacer tres cosas importantes:
- Crear una regla de reescritura personalizada para convertir partes del URI en valores pasados a
index.php
. - Añadir
myroute
ymyargument
a la lista blanca de variables de consulta de WordPress, para que WordPress no las ignore cuando aparezcan en una cadena de consulta. - Vaciar las reglas de reescritura.
En primer lugar, voy a recomendar que en lugar de http://www.example.org/myroute/myargument
, utilices algún tipo de prefijo o sufijo especial para denotar cuándo el URI debe considerarse una de estas "rutas" especiales. Para este ejemplo, he elegido el prefijo api
, por lo que sería http://www.example.org/api/myroute/myargument
. Elegí api
porque cuando hice algo RESTful, como lo que pareces estar trabajando, era 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() si nuestras reglas aún no están incluidas
function my_flush_rules() {
$rules = get_option( 'rewrite_rules' );
if ( ! isset( $rules['api/(.*?)/(.+?)'] ) ) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
// Añadiendo una nueva regla
function my_insert_rewrite_rules( $rules ) {
$newrules = array();
$newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
return $newrules + $rules;
}
// Añadiendo la variable id para que WordPress la reconozca
function my_insert_query_vars( $vars ) {
array_push( $vars, 'myroute', 'myargument' );
return $vars;
}
Desglose rápido
Es bastante sencillo. El patrón regex se añade a una lista de todas las reglas de reescritura en WordPress, y tu patrón personalizado está en la parte superior de la lista. Cuando el patrón coincide, WordPress dejará de buscar en la lista de reglas de reescritura y usará los valores capturados por el regex en lugar de las referencias ($matches[1]
y $matches[2]
) en la cadena de consulta pasada a index.php
.
Añadir las variables de consulta myroute
y myargument
a la lista blanca hace que WordPress les preste atención en lugar de descartarlas.
Forma alternativa de 'agrupar' tu ruta personalizada
Si quisieras evitar usar /api/
como prefijo, podrías usar una variable/campo de cadena de consulta en su lugar. Para hacer algo así, cambiarías el regex a algo como (.*?)/(.+?)\\?api=1
y luego añadirías api
como un parámetro adicional a la llamada array_push()
hecha en my_insert_query_vars()
.
Eso cambiaría la ruta personalizada para que se active cada vez que api=1
sea el primer elemento de la cadena de consulta, por ejemplo, se activaría para http://example.com/anytext/anytext?api=1
.
Ignora el uso del término 'agrupar' - solo lo usé por brevedad.
Si no 'agrupas' con un prefijo o un sufijo, terminarás con patrones de URI que colisionan. Esto se debe a que WordPress no tendrá forma de distinguir tu patrón personalizado de uno destinado a ser una entrada o página. ¿Cómo sabría WordPress que myroute
no es una taxonomía, término o una página padre?
Espero que esto ayude.

Nota útil: las reglas definidas en my_insert_rewrite_rules
siguen el orden de definición. ¡Comienza con la regla más larga primero y luego baja a la más simple, de lo contrario /api/miruta anulará /api/miruta/miargumento.

@npc Ese es un punto importante a tener en cuenta al crear reglas de reescritura personalizadas, también pueden colisionar de esa manera. En el ejemplo anterior, sin embargo, eso no es un problema porque /api/miruta simplemente no sería una ruta válida.

¿Cómo podría alguien cargar una plantilla personalizada desde su directorio de plugins cada vez que se solicite la página http://www.example.org/api/miruta/miargumento?

Aquí está la solución actual y completa de WordPress: https://codex.wordpress.org/Rewrite_API/add_rewrite_rule

Para ampliar un poco lo que hizo eddiemoya anteriormente:
Al igual que el autor original de esta pregunta, quería crear una reescritura personalizada y también entregar una plantilla personalizada para esa página reescrita. El código de edditmoya me puso en el camino correcto, y agregué una función adicional para servir mi plantilla personalizada cuando se accede a la página.
La plantilla personalizada podría estar en cualquier lugar, en mi caso está almacenada en el directorio del plugin.
También solo quería verificar si era necesario actualizar las reglas de reescritura durante la activación del plugin, así que lo coloqué en un register_activation_hook.
Mira a continuación el ejemplo completo de lo que hice:
ACTUALIZADO simplificado basado en el consejo 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 )
{
//intentar obtener la variable de consulta que registramos en nuestra función query_vars()
$account_page = get_query_var( 'account_page' );
//si la variable de consulta tiene datos, debemos estar en la página correcta, cargar nuestra plantilla personalizada
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' ) );
// Funciones de activación únicas
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );

también puedes usar simplemente add_rewrite_endpoint
, que generará la regla por ti y añadirá la variable de consulta de una sola vez. Además, si estás añadiendo tus propias reglas de reescritura, sugiero la función add_rewrite_rule
en lugar de filtrar rewrite_rules_array
.

Gracias Milo, actualicé el código para usar add_rewrite_rule en lugar de filtrar el array de reescritura. Miré add_rewrite_endpoint pero creo que add_rewrite_tag podría adaptarse mejor a mis necesidades. Parece que add_rewrite_endpoint es principalmente útil si quieres añadir argumentos extra a las reescrituras existentes de WP. Corrígeme si estoy equivocado.
