Come prevenire il reindirizzamento di index.php?category_name=qualcosa
Sto cercando di filtrare i post in una categoria per anno di pubblicazione. Vorrei farlo senza essere reindirizzato al template dell'anno, quindi l'URL ideale sarebbe http://example.com/category/reports/2011/ che dovrebbe caricare il file template category.php dove potrei poi usare query_posts per includere solo i post pubblicati nel 2011 e nella categoria reports.
Ecco il mio codice per le regole di rewrite...
function filter_category_by_year_rewrite_rules( $wp_rewrite ) {
/* Crea regole di rewrite per filtrare gli archivi di categoria per anno (/category/reports/2011/)*/
$new_rules = array(
"category/(.+?)/(\d\d\d\d)/?$" => "index.php?category_name=" . $wp_rewrite->preg_index(1) . "&year=" . $wp_rewrite->preg_index(2)
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
var_dump($wp_rewrite);
}
add_action('generate_rewrite_rules', 'filter_category_by_year_rewrite_rules');
Il mio problema è che WordPress reindirizza automaticamente index.php?category_name=reports&year=2011
a /category/reports/
senza traccia del parametro year. Come posso intercettare questo reindirizzamento?
Ho provato ad agganciarmi all'azione template_redirect
senza successo :(
function testing_redirect() {
global $wp;
if($wp->request['matched_rule'] == 'category/(.+?)/(\d\d\d\d)/?$') {
load_template( 'category.php' ); //TEMPLATEPATH .'/category.php';
}
}
add_action('template_redirect', 'testing_redirect', 1);

Questo dovrebbe funzionare:
add_action( 'init', 'wpa12742_init' );
function wpa12742_init(){
// Aggiunge una regola di riscrittura per URL tipo category/nome-categoria/anno
add_rewrite_rule( 'category/(.+?)/(\d{4})/?$', 'index.php?category_name=$matches[1]&year=$matches[2]', 'top' );
// Aggiunge una regola di riscrittura per URL tipo category/nome-categoria/anno/page/numero-pagina
add_rewrite_rule( 'category/(.+?)/(\d{4})/page/(\d+)/?$', 'index.php?category_name=$matches[1]&year=$matches[2]&paged=$matches[3]', 'top' );
}
MODIFICA
Riflettendoci meglio, questo non è sufficiente, poiché verrai intercettato da redirect_canonical()
.
Aggiungi anche questo:
add_filter( 'term_link', 'wpa12743_term_link', 10, 3 );
function wpa12743_term_link( $link, $term, $taxonomy ){
// Modifica il link solo per le categorie quando è presente un anno valido
if('category' != $taxonomy && !preg_match( '@^\d{4}$@', get_query_var('year') ) )
return $link;
// Aggiunge l'anno alla fine del link della categoria
return trailingslashit( $link ) . get_query_var( 'year' );
}

Hai ragione, canonical_redirect era il problema. Vedi la mia risposta qui sotto per come l'ho risolto. Intendevi filtrare term_link
e non redirect_canonical
? Il tuo metodo per lo slash finale mi piace di più.

Ahhh redirect_canonical
era il colpevole. Ecco come ho scovato questo fastidioso bug...
function kill_canonical_redirect($redirect_url, $requested_url) {
global $wp;
if($wp->matched_rule == 'category/(.+?)/(\d\d\d\d)/?$') {
return false;
} else {
return $redirect_url;
}
}
add_filter('redirect_canonical', 'kill_canonical_redirect', 10, 2);
In sostanza, controllo la regola di riscrittura che corrisponde alla richiesta della pagina e se è quella che ho scritto io, so che posso eliminare il reindirizzamento canonico semplicemente restituendo false.
Forse l'informazione più utile per chi sta leggendo è come ho scoperto tutto ciò. Ho installato il plugin Better HTTP Redirects (http://hakre.wordpress.com/2011/03/20/how-to-debug-redirect-problems-in-wordpress/) che include un utilissimo strumento di debug per i reindirizzamenti quando WP_DEBUG
è impostato su true in wp-config.php
.
Da lì ho capito che il reindirizzamento era attivato dalla riga 367 di /wp-includes/canonical.php
, quindi dopo aver esaminato il codice sorgente su Trac (http://core.trac.wordpress.org/browser/trunk/wp-includes/canonical.php#L367), ho capito come eliminare il reindirizzamento canonico.

Uno strumento davvero incredibilmente utile per esaminare il core è PHPXref: http://phpxref.ftwr.co.uk/wordpress/nav.html
