Modificar páginas de Taxonomía para excluir elementos en taxonomías hijas
Encontré esta pregunta:
¿Hay alguna manera de usar $query->set('tax_query' en el filtro pre_get_posts?
Lo cual parece indicar que sí, puedes alterar la consulta de taxonomía en los archivos de taxonomía mediante pre_get_posts(). Así que intenté esto:
add_action('pre_get_posts', 'kia_no_child_terms' );
function kia_no_child_terms( $wp_query ) {
if( is_tax() ) {
$wp_query->tax_query->queries[0]['include_children'] = 0;
}
}
Así como también:
add_action('pre_get_posts', 'kia_no_child_terms' );
function kia_no_child_terms( $wp_query ) {
if( is_tax() ) {
$tax_query = $wp_query->get( 'tax_query' );
$tax_query->queries[0]['include_children'] = 0;
$wp_query->set( 'tax_query', $tax_query );
}
}
Para intentar establecer el parámetro include_children como falso... y casi todas las combinaciones posibles que se me ocurren. Sin embargo, el archivo de taxonomía sigue mostrando los elementos del término hijo.
Y la siguiente prueba parece AGREGAR consultas de taxonomía adicionales en lugar de sobrescribirlas... lo cual me confunde.
function dummy_test( $wp_query){
$tax_query = array(
'relation' => 'OR',
array(
'taxonomy' => 'tax1',
'terms' => array( 'term1', 'term2' ),
'field' => 'slug',
),
array(
'taxonomy' => 'tax2',
'terms' => array( 'term-a', 'term-b' ),
'field' => 'slug',
),
);
$wp_query->set( 'tax_query', $tax_query );
);
add_action('pre_get_posts','dummy_test');
¿No debería SET sobrescribir el valor actual?

Sé que esta es una pregunta antigua, pero puede resultar un poco confusa y con suerte ayudará a alguien. La razón por la que `$query->set` no funciona es porque la consulta ya ha sido parseada y ahora también necesitamos actualizar el objeto tax_query. Así es como lo hice:
function my_tax_query( $query ) {
$package_id = 12345;
$tax_query = array(
'taxonomy' => 'package_id',
'terms' => array( $package_id ),
'field' => 'slug',
'operator' => 'IN',
);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
}
add_action( 'pre_get_posts', 'my_tax_query' );

¡Genial! Lo revisé y pude adaptar tu código para que funcione con todas las taxonomías, que era la pregunta original. +1 (te daría más votos si pudiera)

Me sorprendió y me tranquilizó ver que este método también funciona para consultas de fecha.

A partir de WordPress 3.7 se añadió una nueva acción llamada parse_tax_query
exactamente para este propósito.
function kia_no_child_terms($wp_query) {
$wp_query->tax_query->queries[0]['include_children'] = 0;
}
add_action('parse_tax_query', 'kia_no_child_terms');
Este hook modifica los valores tanto de query_vars como de tax_query. Usar el método pre_get_posts
resultaba en consultas de taxonomía duplicadas, al menos en mi caso.
Antes de la versión 3.7 debes usar la acción pre_get_posts
en su lugar, como se detalla en las otras respuestas.

En mi caso, esto parece un poco excesivo y tiene efectos secundarios no deseados... evita que se muestren los submenús de mi navegación.

@Manu - tienes toda la razón. El ejemplo proporcionado está muy simplificado y muestra solo las variables relevantes. En un escenario real, inspeccionarías $wp_query
, usarías etiquetas de plantilla, o ambas cosas, o alguna otra lógica, para determinar si la consulta debería modificarse en primer lugar.

No pude hacer que esto funcione con ninguna combinación de pre_get_posts
o parse_query
. Puedo hacerlo relativamente fácil borrando el objeto de consulta después de que se crea. No me gusta porque entonces estoy ejecutando la consulta dos veces, pero estoy al límite de mis fuerzas intentando ser "eficiente".
function kia_no_child_taxonomies(){
if(is_tax()){
$args = array(
'tax_query' => array(
array(
'taxonomy' => get_query_var('taxonomy'),
'field' => 'slug',
'terms' => get_query_var('term'),
'include_children' => FALSE
)
)
);
query_posts($args);
}
}
add_action('wp','kia_no_child_taxonomies');
Así que hasta que alguien aparezca con una mejor respuesta, este es el único método que he encontrado hasta ahora.
EDITAR:
Adaptando la respuesta de @Tanner Moushey, finalmente pude hacer que esto funcione para excluir todos los términos hijos de un archivo de taxonomía en el hook pre_get_posts
sin la ineficiente doble consulta.
function kia_no_child_taxonomies( $query ) {
if( is_tax() ):
$tax_obj = $query->get_queried_object();
$tax_query = array(
'taxonomy' => $tax_obj->taxonomy,
'field' => 'slug',
'terms' => $tax_obj->slug,
'include_children' => FALSE
);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
endif;
}
add_action( 'pre_get_posts', 'kia_no_child_taxonomies' );

Esto es incorrecto. No deberías usar query_posts, utiliza pre_get_posts o request en su lugar.

eso no es útil. ¿Por qué no publicas una respuesta entonces si sabes cómo hacer que pre_get_posts funcione en este caso? Obviamente mencioné en mi pregunta que lo intenté, pero llegué a la conclusión de que no se puede modificar el objeto tax_Query a través de ese filtro

Lo siento, debería haber sido más útil. El verdadero tax query se construye (con parse_tax_query) después de que se dispara pre_get_posts, y en un WP_Tax_Query real, que contiene todas las tax queries combinadas de las variables de consulta (incluyendo la variable tax_query) así que en tu caso está analizando tu variable tax_query, y luego añadiendo cualquier otra cosa disponible a través de variables de consulta, como categoría, tag__in, y otras. Puedes usar pre_get_posts para eliminar variables de consulta existentes antes de añadir las tuyas.

Gracias por la mejor explicación. Obviamente esto es antiguo, así que seguí adelante con la solución que tenía. Nunca pude modificar el parámetro include_children
mediante el hook pre_get_posts
. Ah bueno.

Parece que también estoy atascado con este problema. :-/

Para aquellos que como yo estuvieron atascados con este problema, encontré algo útil. Utilicé el sistema de prioridades
function kia_no_child_taxonomies( $query ) {
if( is_tax() ):
$tax_obj = $query->get_queried_object();
$tax_query = array(
'taxonomy' => $tax_obj->taxonomy,
'field' => 'slug',
'terms' => $tax_obj->slug,
'include_children' => FALSE);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
return $query;
endif;
}
add_action( 'pre_get_posts', 'kia_no_child_taxonomies',0 );
Mi consulta no estaba incluida en los resultados y la búsqueda se rompía con mis exclusiones. Espero que esto ayude.

Encontré este hilo en el núcleo de WP y lo estoy usando con éxito para excluir los términos hijos de una taxonomía específica:
function wpse_43181_parse_tax_query( $query ) {
if ( ! empty( $query->tax_query->queries ) ) {
foreach ( $query->tax_query->queries as &$tax_query ) {
if ( $tax_query['taxonomy'] === 'tu_taxonomia' ) {
$tax_query['include_children'] = false;
}
}
}
}
add_action( 'parse_tax_query', 'wpse_43181_parse_tax_query' );
Modifícalo según tus necesidades para excluir los términos hijos en todas las páginas de taxonomías.
