Problema con las reglas de reescritura cuando la regla incluye el slug de la página de inicio
Tengo una página Ejemplo (ID=443, slug=example) que está configurada, mediante Dashboard->Settings->Reading
, como la página de inicio de mi sitio WordPress. También tengo la siguiente regla de reescritura configurada:
[(example)/(view-section)] => index.php?pagename=$matches[1]&foo=1&bar=2
Tengo un shortcode en la página Ejemplo que debería generar contenido basado en la presencia y valor de las variables de consulta foo
y bar
. El problema es que las variables de consulta no se configuran correctamente cuando visito la URL /example/view-section
(y otras relacionadas, ver más abajo).
Estoy usando un plugin de prueba para depurar este problema. El código completo está abajo:
<?php
function test_shortcode() {
global $wp_rewrite;
echo '<pre>' . 'foo: ' . get_query_var('foo') . '</pre>';
echo '<pre>' . 'bar: ' . get_query_var('bar') . '</pre>';
echo '<pre>' . print_r($wp_rewrite->rules, true) . '</pre>';
}
add_shortcode('foobar', 'test_shortcode');
function test_rules() {
$rules = get_option('rewrite_rules');
if (!isset($rules['(example)/(view-section)'])) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
add_action('wp_loaded', 'test_rules');
function test_rewrite_rules($wprules) {
$rules = array('(example)/(view-section)' => 'index.php?pagename=$matches[1]&foo=1&bar=2');
return $rules + $wprules;
}
add_action('rewrite_rules_array', 'test_rewrite_rules');
function test_query_vars($query_vars) {
array_push($query_vars, 'foo');
array_push($query_vars, 'bar');
return $query_vars;
}
add_filter('query_vars', 'test_query_vars');
Hay tres escenarios que me dieron resultados diferentes:
- Al acceder a /example/view-section redirige a / y los valores de las variables de consulta están vacíos.
- Al acceder a /index.php?pagename=example&foo=1&bar=2 funciona como necesito. Muestra el contenido generado por el shortcode y el valor de las dos variables de consulta pasadas en la URL.
- Si uso
page_id
en lugar depagename
opage
: /index.php?page_id=443&foo=1&bar=2, la variable de consultapage_id
se elimina y se muestra nuevamente la página de inicio por defecto.
Me gustaría saber por qué WordPress se comporta como se describe arriba y, si es posible, cómo hacer que el primer caso funcione al menos como el segundo.
Ten en cuenta que si la página Ejemplo no está configurada como página de inicio, los casos 1 y 3 funcionan como el caso 2.
Agradezco tu ayuda y estaré encantado de proporcionar más detalles si son necesarios.
EDITADO
La pregunta original incluía enlaces a una instancia de WordPress en funcionamiento con un ejemplo del problema. Sin embargo, no puedo mantener esa instancia funcionando para siempre, así que eliminé los enlaces e intenté explicar la situación solo con palabras.

El problema no tiene nada que ver con las reglas de reescritura (aunque sugeriría usar add_rewrite_rule()
en lugar del enfoque de bajo nivel de alterar directamente el array de reescritura. Lo mismo para flush_rewrite_rules()
. Además, aunque como lo tienes las reglas solo se vacían una vez, sería mejor hacerlo en la activación del plugin, en lugar de dentro de un condicional que se verifica en cada carga de página.
... así que el 'problema' es en realidad la canonicalización. Básicamente, varias URLs pueden apuntar al mismo contenido (incluyendo URLs con barras diagonales adicionales). La idea es que:
- Esto no es bueno desde una perspectiva SEO: si los motores de búsqueda no se dan cuenta de que todas estas URLs representan el mismo recurso, pueden terminar compitiendo entre sí.
- No es bueno desde la perspectiva del usuario. Si van a www.example.com?year=2012, sería mejor redirigirlos a www.example.com/2012 - más bonito y fácil de recordar.
Entonces, cuando WordPress recibe una URL 'rota' o 'duplicada' como www.example.com?year=2012, la redirige a la URL correcta (o 'canónica'). (www.example.com/2012) en este caso.
Uno de los chequeos que realiza es si estamos en la 'página de inicio', y si es así, verifica que estamos usando la URL canónica para nuestra página de inicio: http://108.166.64.229/ en tu caso. Si no es así, te redirige aquí. Notarás que http://108.166.64.229/example también redirige allí.
Puedes desactivar esto. La canonicalización se ejecuta en el hook template_redirect
. Así que simplemente puedes eliminarlo:
remove_filter('template_redirect', 'redirect_canonical');
O puedes 'deshacerlo' (en el caso específico de tu portada), usando un hook que se utiliza dentro del callback redirect_canonical
:
add_filter('redirect_canonical', 'wpse51530_redirect_canonical', 10, 2);
function wpse51530_redirect_canonical($redirect_url, $requested_url){
if( is_front_page() )
return $requested_url;
else
return $redirect_url;
}
Puedes ver cómo WordPress realiza la canonicalización aquí.
