¿Qué pasa si queremos mostrar los posts que pertenezcan a dos categorías a la vez? por ejemplo, mostrar los posts que sean de “PHP” y de “Noticias” o “PHP” y “Ejemplos”.
La forma de hacerlo es fácil, primero debemos crearnos la estructura del permalink y que WordPress lo reconozco, en este caso será /categories/slug-category-A/slug-category-B. Para ello tenemos que dar de alta esta estructura el el $wp_rewrite y añadir la variable cats en los parámetros tratados por WordPress.
// Crea la estructura para el rewrite
function categories_rewrite_rules() {
global $wp_rewrite;
$rewrite_tag = '%categories%';
// En la variable cats se almacenará 'slug-category-A/slug-category-B' que luego trataremos
$wp_rewrite->add_rewrite_tag( $rewrite_tag, 'categories/([^/]+/[^/]+)', 'cats=' );
$rewrite_keywords_structure = $wp_rewrite->root . "$rewrite_tag/";
$new_rule = $wp_rewrite->generate_rewrite_rules( $rewrite_keywords_structure );
$wp_rewrite->rules = $new_rule + $wp_rewrite->rules;
return $wp_rewrite->rules;
}
// Permitimos que la variable cats se tenga en cuenta en las queries (URL) de WordPress
function categories_variables( $public_query_vars ) {
$public_query_vars[] = 'cats';
return $public_query_vars;
}
// Hacemos un flush para que tenga en cuenta la nueva regla en el rewrite
function me_flush_rewrite_rules() {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
add_action( 'init', 'me_flush_rewrite_rules' );
add_action( 'generate_rewrite_rules', 'categories_rewrite_rules' );
add_filter( 'query_vars', 'categories_variables' );
Vale, ya tenemos creada la estructura, ahora solo falta modificar la query para que tenga en cuenta la nueva condición: que el post tenga la categoría A y la categoría B, para lo cual modificaremos el join de la query añadiendo un left join para cada categoría
add_filter( 'posts_join' , 'categories_join' );
function categories_join( $join ) {
global $wpdb, $wp_query;
if (get_query_var('cats')) {
// Recuperamos los slugs de las categorias
$cats = explode('/', $wp_query->query_vars['cats']);
$ids = array();
// Por cada slug recuperamos la categoría y añadimos left join
foreach($cats as $i=>$c) {
$obj = get_category_by_slug($c);
if ($obj) {
$ids[] = $obj->term_id;
$join .= " JOIN {$wpdb->term_relationships} r{$i} on r{$i}.object_id = {$wpdb->posts}.ID and r{$i}.term_taxonomy_id = {$obj->term_id} ";
}
}
}
return $join;
}
Y ya está, si accedieramos a nuestro blog http://miblog.com/categories/php/noticias veríamos los posts que están dentro de PHP y Noticias, con su paginación y demás.
Si por un casual queremos utilizar una template en particular para esto, tan solo deberemos añadir lo siguiente a nuestro functions.php:
function categories_template() {
if (get_query_var('cats')) {
include (TEMPLATEPATH . '/category-videos.php');
exit;
}
}
add_action('template_redirect', 'categories_template');
O si queremos obtener el título de las categorías, podremos crearnos una función que nos lo devuelva:
function get_cats_names() {
if (get_query_var('cats')) {
$cats = explode('/', get_query_var('cats'));
$names = array();
foreach($cats as $i=>$c) {
$obj = get_category_by_slug($c);
if ($obj) {
$names[] = $obj->name;
}
}
return implode(' | ', $names);
}
return '';
}
Lo malo es que estas cosas un dÃa cualquiera dejan de funcionar, y si quieres proveer un servicio serio que las utilice te arriesgas a que eso ocurra en cualquier momento.
Creo que Alexa deberÃa tener algún tipo de api oficial gratuita, al fin y al cabo no es algo extraordinario.
Josep, estoy totalmente de acuerdo contigo. Yo creo que Alexa es lo peor que existe, pero curiosamente, algunos lo siguen como si fuera la única verdad.
Espero que a esas personas les sirva el script.