Excluir publicaciones de subcategorías en la visualización de categorías

2 mar 2014, 11:51:17
Vistas: 19K
Votos: 3

Tengo una estructura de categorías de publicaciones así:

  • noticias
  • noticias / conferencias
  • noticias / newsletter

En Apariencia > Menú, he añadido 3 elementos de menú:

Uno para cada categoría: Noticias, Conferencias y Newsletter.

Sin embargo, la página de Noticias también muestra publicaciones de Conferencias y Newsletter.

¿Cómo puedo excluir las publicaciones de subcategorías para que no aparezcan en la página de la categoría principal?

Gracias.

1
Comentarios

Tengo mucha curiosidad sobre esto. Incluso parece ser el comportamiento que estoy experimentando en el backend de administración.

Ver: "¿Por qué la lista de publicaciones de administración para un término también muestra publicaciones para todos los términos secundarios?" https://wordpress.stackexchange.com/questions/318175/why-does-admin-post-list-for-a-term-also-show-posts-for-all-child-terms

¿Es realmente un comportamiento estándar?

Robert Andrews Robert Andrews
1 nov 2018 14:11:38
Todas las respuestas a la pregunta 6
7

Reescribí el código de una publicación en WP Engineer:

function wpse_filter_child_cats( $query ) {

if ( $query->is_category ) {
    $queried_object = get_queried_object();
    $child_cats = (array) get_term_children( $queried_object->term_id, 'category' );

    if ( ! $query->is_admin )
        //excluir las publicaciones en categorías hijas
        $query->set( 'category__not_in', array_merge( $child_cats ) );
    }

    return $query;
}
add_filter( 'pre_get_posts', 'wpse_filter_child_cats' );

Pruébalo pegando el fragmento en tu archivo functions.php. Ten en cuenta que una publicación no puede pertenecer tanto a la categoría padre como a la categoría hija, o no se mostrará.

2 mar 2014 13:24:03
Comentarios

Hola @1fixdotio. Gracias por tu ayuda. Añadí esto al functions.php de mi tema hijo, pero los posts de las subcategorías aún se muestran en la categoría padre.

Steve Steve
3 mar 2014 15:07:42

¿Recibiste algún mensaje de error? ¿Podrías confirmarme si tienes habilitados los permalinks?

1fixdotio 1fixdotio
3 mar 2014 16:34:40

@Steve He probado el código y funciona en mi servidor. Acabo de actualizar un poco el código, espero que te ayude.

1fixdotio 1fixdotio
3 mar 2014 16:53:09

No hay errores. He subido el código actualizado y todavía no funciona. Mi tema es un tema hijo de Twenty Twelve. Mira esta página que contiene "Presentaciones de la Conferencia WA Men's Shed 2012" y "The Warbler - boletín de WA Men's Shed". Estos dos no están en la categoría principal.

Steve Steve
4 mar 2014 13:33:14

@Steve Creé un tema hijo para twentytwelve y pegué mi código en functions.php, funcionó bien. ¿Podrías desactivar los plugins como jetpack e intentar de nuevo?

1fixdotio 1fixdotio
4 mar 2014 16:20:31

Acabo de agregar una nueva entrada a Conferencias, y no aparece en la página de la categoría Noticias, por lo que parece que tu solución funciona para nuevas entradas, pero no para entradas que solían estar en la categoría Noticias pero fueron movidas a subcategorías separadas.

Steve Steve
8 mar 2014 02:05:44

pre_get_posts es un hook de acción, no un hook de filtro. Por lo tanto, debe usarse add_action() sin devolver nada porque el argumento $query se pasa por referencia.

vee vee
16 ago 2024 10:28:21
Mostrar los 2 comentarios restantes
1

Utiliza category__in en lugar de cat en tu consulta.

Como ya sabes, cat consultará una categoría y sus subcategorías:

$category = get_category (get_query_var('cat'));
WP_Query( 'cat'=>$category, 'post_type' => 'post' );

Sin embargo, cuando usas category__in, no obtendrás resultados de la subcategoría.

$category = get_category (get_query_var('cat'));
WP_Query( 'category__in'=>$category, 'post_type' => 'post' );

La documentación sobre consultas basadas en categorías está aquí.

17 ene 2015 14:34:04
Comentarios

Hola y bienvenido a WP.SE. Ten en cuenta que get_category() devuelve OBJECT, ARRAY_A, o ARRAY_N. Asignarlo directamente no funcionará. Tendrás que verificar el valor de retorno y asignar un valor ya sea mediante su clave asociativa/numérica o mediante la propiedad del objeto. Asegúrate de verificar su existencia antes de usarlo.

kaiser kaiser
17 ene 2015 14:41:51
0

Si deseas incluir todas las publicaciones que tengan la categoría que se está consultando actualmente, puedes usar lo siguiente. Esto podría incluir potencialmente publicaciones que tengan subcategorías/hijas de la categoría consultada, pero solo si también tienen la categoría padre. No incluirá publicaciones que solo tengan una categoría hija. En otras palabras, dado lo siguiente:

  • Categoría 1

  • Categoría 2, que es una categoría hija de la categoría 1

  • Publicación A, que tiene solo la categoría 1

  • Publicación B, que tiene solo la categoría 2

  • Publicación C, que tiene tanto la categoría 1 como la categoría 2

esta consulta devolverá las publicaciones A y C, pero no la B

function cat_query_filter($query) {
    if (!is_admin() && $query->is_main_query() && is_category()) {
        $queried_cat_obj = get_queried_object();
        $queried_cat_id = $queried_cat_obj->term_id;
        $query->set('category__in', $queried_cat_id);
    }
}
add_action('pre_get_posts', 'cat_query_filter');

La respuesta proporcionada por @createscape es buena, pero excluiría publicaciones como la B, lo cual puede o no ser lo que deseas. Por lo tanto, dependiendo de lo que quieras incluir en tu lista de resultados, podrías usar esa solución o esta. Información adicional aquí: https://developer.wordpress.org/reference/classes/wp_query/#category-parameters

1 ago 2020 02:04:27
0

Eso funciona bien y evita que las publicaciones en categorías hijas aparezcan en el listado de la categoría padre. Sin embargo, asegúrate de tener al menos una publicación en esa categoría padre, de lo contrario obtendrás un error de "no encontrado" si alguien hace clic en el ítem del menú de la categoría padre.

18 oct 2014 10:19:17
0

Escribí mi propia función para excluir las publicaciones de subcategorías del loop, ya que el código anterior no funcionó para mí.

En el archivo archive.php de mi tema, antes del loop, listo las subcategorías:

    <?php
       $current_cat = get_queried_object();

       $args = array( 'parent'=>$current_cat->term_id, 'child_of' => $current_cat->term_id, );
        $categories = get_categories( $args );
        foreach($categories as $category) { ?>

           <h2><?php echo $category->name ;?></h2>
           <p> etc....</p>
      <?php } ?>

En mi archivo functions.php, agregué la siguiente función personalizada usando pre_get_posts:

add_action( 'pre_get_posts', 'main_query_without_subcategory_posts' );

function main_query_without_subcategory_posts( $query ) {

if ( ! is_admin() && $query->is_main_query() ) {
    // No es una consulta para una página de administración
    // Es la consulta principal para una página frontal de tu sitio

    if ( is_category() ) {

   // Obtener la categoría actual
        $current_category = get_queried_object();
        // obtener el ID de la categoría actual
        $current_cat_id = $current_category->term_id;

        // encontrar las subcategorías de la categoría actual
        $cat_args = array( 'parent'=>$current_category->term_id, 'child_of' => $current_category->term_id, );
        $subcategories = get_categories( $cat_args );

        // Obtener una lista de IDs de subcategorías con un signo menos al frente
        $subcat_id = array();         
        foreach($subcategories as $subcategory) { 
            $subcat_id[] = " -". $subcategory->term_id; 
        }

        // unirlos como una cadena con comas como separadores          
        $excludesubcatlist = join(',', $subcat_id);

       // Si tienes múltiples parámetros, usa $query->set varias veces
        $query->set( 'posts_per_page', '10' );
        $query->set( 'cat', ''.$current_cat_id.','.$excludesubcatlist.'' );
      }
    }
  }

Luego en archive.php, debajo de las subcategorías, agregué el loop regular de WordPress que ahora es modificado por la función anterior:

<?php  while (have_posts() ) : the_post(); ?>
     <h2><?php the_title();?></h2>
     <p> etc....</p>
 <?php endwhile;?>

Aunque el codex de WordPress dice que usar "category__in" excluirá las publicaciones de subcategorías, eso no funcionó para mí y las publicaciones de subcategorías seguían apareciendo.

https://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters

https://developer.wordpress.org/reference/hooks/pre_get_posts/

8 dic 2018 06:20:04
0

Vale, en 2019 tuve que usar un código ligeramente modificado y funciona con cualquier taxonomía. No solo con las categorías estándar. Lo usé con mi configuración de WooCommerce y WP, evitando que se muestren productos de categorías anidadas en la categoría padre:

add_action('parse_tax_query', 'wpse_filter_child_cats'); 

function wpse_filter_child_cats( $query ) {
    if ( is_tax( 'product_cat' ) ) {

        $queried_object = get_queried_object();
        $child_cats     = (array) get_term_children( $queried_object->term_id, 'product_cat' );

        if ( ! $query->is_admin ) //excluir los posts en categorías hijas
        {

            $query->tax_query->queries[] = [
                'taxonomy' => 'product_cat',
                'field'    => 'term_id',
                'terms'    => array_merge( $child_cats ),
                'operator' => 'NOT IN'
            ];
        }

    }

}
24 abr 2019 16:21:07