Evitando que index.php?category_name=algo redirija
Estoy intentando filtrar publicaciones en una categoría por el año de la fecha de publicación. También quiero hacer esto sin ser redirigido a la plantilla del año, por lo que mi URL ideal sería http://ejemplo.com/category/reports/2011/ que cargaría el archivo de plantilla category.php donde luego podría usar query_posts para incluir solo las publicaciones que se publicaron en 2011 y están en la categoría reports.
Aquí está mi código de reglas de reescritura...
function filter_category_by_year_rewrite_rules( $wp_rewrite ) {
/* Crea reglas de reescritura para filtrar archivos de categoría por año (/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');
Mi problema es que WordPress redirige automáticamente index.php?category_name=reports&year=2011
a /category/reports/
sin rastro del parámetro year. ¿Cómo puedo interceptar esta redirección?
Intenté engancharme a la acción template_redirect
sin éxito :(
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);

Esto debería funcionar:
add_action( 'init', 'wpa12742_init' );
function wpa12742_init(){
// Añadir reglas de reescritura para categorías con año
add_rewrite_rule( 'category/(.+?)/(\d{4})/?$', 'index.php?category_name=$matches[1]&year=$matches[2]', 'top' );
// Añadir reglas de reescritura para paginación en categorías con año
add_rewrite_rule( 'category/(.+?)/(\d{4})/page/(\d+)/?$', 'index.php?category_name=$matches[1]&year=$matches[2]&paged=$matches[3]', 'top' );
}
EDITAR
Pensándolo mejor, eso no es suficiente, ya que te atrapará redirect_canonical()
.
Añade esto también:
add_filter( 'term_link', 'wpa12743_term_link', 10, 3 );
function wpa12743_term_link( $link, $term, $taxonomy ){
// Solo modificar enlaces de categoría cuando haya un año en la consulta
if('category' != $taxonomy && !preg_match( '@^\d{4}$@', get_query_var('year') ) )
return $link;
// Añadir el año al final del enlace
return trailingslashit( $link ) . get_query_var( 'year' );
}

Tienes razón, canonical_redirect era el problema. Mira mi respuesta más abajo para ver cómo lo solucioné. ¿Querías filtrar term_link
y no redirect_canonical
? Me gusta más tu método para la barra diagonal final.

Ahhh redirect_canonical
era el culpable. Así es como eliminé este error...
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);
Básicamente, reviso la regla de reescritura que coincidió con la solicitud de página y si es la que escribí, entonces sé que puedo eliminar la redirección canónica simplemente devolviendo false.
Quizás la información más útil para cualquiera que lea esto es cómo lo descubrí. Instalé el plugin Better HTTP Redirects (http://hakre.wordpress.com/2011/03/20/how-to-debug-redirect-problems-in-wordpress/) que tiene una herramienta muy útil para depurar redirecciones cuando WP_DEBUG
está configurado como true en wp-config.php
.
Desde ahí, me di cuenta de que la redirección se estaba activando desde la línea 367 de /wp-includes/canonical.php
, así que después de revisar el código fuente en Trac (http://core.trac.wordpress.org/browser/trunk/wp-includes/canonical.php#L367), descubrí cómo eliminar la redirección canónica.

Una herramienta realmente increíble para revisar el núcleo es PHPXref: http://phpxref.ftwr.co.uk/wordpress/nav.html
