Problema con las reglas de reescritura cuando la regla incluye el slug de la página de inicio

8 may 2012, 18:32:13
Vistas: 1.97K
Votos: 0

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:

  1. Al acceder a /example/view-section redirige a / y los valores de las variables de consulta están vacíos.
  2. 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.
  3. Si uso page_id en lugar de pagename o page: /index.php?page_id=443&foo=1&bar=2, la variable de consulta page_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.

2
Comentarios

¿Qué pasa si guardas nuevamente la configuración de tus enlaces permanentes y luego lo intentas?

Stephen Harris Stephen Harris
8 may 2012 18:58:30

@Stephen Harris, obtengo los mismos resultados. Creo que guardar los enlaces permanentes nuevamente tiene el mismo efecto que llamar a flush_rewrite_rules o $wp_rewrite->flush_rules, ¿no es así?. También puedes ver en la página de resultados que la regla se está agregando correctamente al array $wp_rewrite->rules. Gracias.

Willington Vega Willington Vega
8 may 2012 20:23:02
Todas las respuestas a la pregunta 1
1

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:

  1. 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í.
  2. 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í.

8 may 2012 22:01:12
Comentarios

Gracias @StephenHarris, esa es una gran explicación para el problema que tengo y tus sugerencias me llevaron directamente a la solución.

Willington Vega Willington Vega
9 may 2012 16:32:18