Problema con le regole di riscrittura quando include lo slug della homepage

8 mag 2012, 18:32:13
Visualizzazioni: 1.97K
Voti: 0

Ho una pagina Esempio (ID=443, slug=example) configurata, tramite Dashboard->Impostazioni->Lettura, come homepage del mio sito WordPress. Ho anche la seguente regola di riscrittura configurata:

[(example)/(view-section)] => index.php?pagename=$matches[1]&foo=1&bar=2

Ho uno shortcode nella pagina Esempio che dovrebbe generare contenuti in base alla presenza e al valore delle variabili di query foo e bar. Il problema è che queste variabili non vengono impostate correttamente quando visito l'URL /example/view-section (e altri correlati, vedi sotto).

Sto usando un plugin di test solo per debug. Il codice completo è il seguente:

<?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');

Ci sono tre scenari che mi hanno dato risultati diversi:

  1. Visitare /example/view-section reindirizza a / e i valori delle variabili di query sono vuoti.
  2. Visitare /index.php?pagename=example&foo=1&bar=2 funziona come desiderato, mostrando il contenuto generato dallo shortcode con i valori delle variabili passate nell'URL.
  3. Se uso page_id invece di pagename o page: /index.php?page_id=443&foo=1&bar=2, la variabile page_id viene rimossa e viene mostrata nuovamente la homepage predefinita.

Vorrei capire perché WordPress si comporta come descritto sopra e, se possibile, come fare in modo che il primo caso funzioni almeno come il secondo.

Nota che se la pagina Esempio non è configurata come homepage, i casi 1 e 3 funzionano come il caso 2.

Apprezzo il tuo aiuto e sarò felice di fornire ulteriori dettagli se necessario.

MODIFICA

La domanda includeva originariamente link a un'istanza WordPress funzionante con un esempio del problema. Tuttavia, non posso mantenere quell'istanza attiva per sempre, quindi ho rimosso i link e ho cercato di spiegare la situazione solo con le parole.

2
Commenti

Cosa succede se salvi nuovamente le impostazioni dei permalink e poi provi?

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

@Stephen Harris, ottengo gli stessi risultati. Penso che salvare nuovamente i permalink abbia lo stesso effetto di chiamare flush_rewrite_rules o $wp_rewrite->flush_rules, no? Inoltre puoi vedere nella pagina dei risultati che la regola viene correttamente aggiunta all'array $wp_rewrite->rules. Grazie.

Willington Vega Willington Vega
8 mag 2012 20:23:02
Tutte le risposte alla domanda 1
1

Il problema non ha nulla a che fare con le regole di riscrittura (anche se suggerirei di utilizzare add_rewrite_rule() piuttosto che l'approccio più basilare di modificare direttamente l'array delle riscritture. Lo stesso vale per flush_rewrite_rules(). Inoltre, anche se così com'è le regole vengono aggiornate solo una volta - sarebbe meglio farlo all'attivazione del plugin, piuttosto che all'interno di un condizionale che viene verificato ad ogni caricamento di pagina.

... quindi il 'problema' è in realtà la canonicalizzazione. In pratica, vari URL possono puntare allo stesso contenuto (inclusi URL con solo barre aggiuntive). L'idea è che:

  1. Questo non sia buono da un punto di vista SEO - se i motori di ricerca non si rendono conto che tutti questi URL rappresentano la stessa risorsa, potrebbero finire per competere tra loro
  2. Non sia buono da un punto di vista utente. Se arrivano a www.example.com?year=2012 sarebbe meglio reindirizzarli a www.example.com/2012 - più carino e facile da ricordare.

Quindi, quando WordPress riceve un URL 'rotto' o 'duplicato' come www.example.com?year=2012, lo reindirizza all'URL corretto (o 'canonico'). (www.example.com/2012) in questo caso.

Uno dei controlli che esegue è verificare se siamo sulla 'home page' e, se lo siamo, controlla che stiamo utilizzando l'URL canonico per la nostra home page: http://108.166.64.229/ nel tuo caso. Se non è così, vieni reindirizzato qui. Noterai che anche http://108.166.64.229/example reindirizza lì.

Puoi disattivare questa funzionalità. La canonicalizzazione viene eseguita sull'hook template_redirect. Quindi puoi semplicemente rimuoverlo:

remove_filter('template_redirect', 'redirect_canonical');

Oppure puoi 'annullarlo' (nel caso specifico della tua front page), utilizzando un hook che viene usato all'interno della 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;
}

Puoi vedere come WordPress gestisce la canonicalizzazione qui.

8 mag 2012 22:01:12
Commenti

Grazie @StephenHarris, questa è una spiegazione perfetta per il problema che ho avuto e i tuoi suggerimenti mi hanno indirizzato direttamente alla soluzione.

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