Escludi i post delle sottocategorie dalla visualizzazione della categoria principale
Ho una struttura di categorie per i post come questa:
- news
- news / conferences
- news / newsletter
In Aspetto > Menu, ho aggiunto 3 voci di menu.
Una per ciascuna delle categorie News, Conferences e Newsletter.
Tuttavia, la pagina News mostra anche i post di Conferences e Newsletter.
Come posso escludere i post delle sottocategorie dalla visualizzazione nella pagina della categoria genitore?
Grazie

Ho riscritto il codice da un post su 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 )
//esclude i post nelle sottocategorie
$query->set( 'category__not_in', array_merge( $child_cats ) );
}
return $query;
}
add_filter( 'pre_get_posts', 'wpse_filter_child_cats' );
Provalo incollando lo snippet nel tuo functions.php
. Tieni presente che un post non può appartenere sia alla categoria genitore che alla sottocategoria, altrimenti non verrà visualizzato.

Ciao @1fixdotio. Grazie per l'aiuto. Ho aggiunto questo al functions.php del mio tema child, ma i post delle sottocategorie continuano a essere visualizzati nella categoria genitore.

Hai ricevuto messaggi di errore? Posso sapere se hai abilitato il permalink?

@Steve Ho testato il codice e potrebbe funzionare sul mio server. Ho appena aggiornato un po' il codice, spero che aiuti.

Nessun errore. Ho caricato il codice aggiornato ma ancora non funziona. Il mio tema è un child theme di Twenty Twelve. Vedi questa pagina che contiene "2012 WA Men’s Shed Conference Presentations" e "The Warbler – WA Men’s Shed newsletter". Questi due non sono nella categoria genitore.

@Steve Ho creato un child theme per twentytwelve e incollato il mio codice in functions.php, ha funzionato bene. Potresti disabilitare i plugin come Jetpack e riprovare?

Ho appena aggiunto un nuovo post a Conferences, e non appare nella pagina della categoria News, quindi sembra che la tua correzione funzioni per i nuovi post, ma non per i post che erano precedentemente nella categoria News ma sono stati spostati in sottocategorie separate.

pre_get_posts
è un hook di azione non un hook di filtro. Quindi, dovrebbe essere add_action()
senza restituire nulla perché l'argomento $query
è passato per riferimento.

Usa category__in
invece di cat
nella tua query.
Come già sai, cat
interrogherà una categoria e le sue sottocategorie:
$category = get_category (get_query_var('cat'));
WP_Query( 'cat'=>$category, 'post_type' => 'post' );
Tuttavia, quando usi category__in
, non otterrai risultati dalla sottocategoria.
$category = get_category (get_query_var('cat'));
WP_Query( 'category__in'=>$category, 'post_type' => 'post' );
La documentazione su come interrogare in base alle categorie è qui.

Ciao e benvenuto su WP.SE. Tieni presente che get_category()
restituisce OBJECT
, ARRAY_A,
o ARRAY_N
. Assegnarlo direttamente non funzionerà. Dovrai verificare il valore restituito e assegnare un valore tramite la sua chiave associativa/numerica o tramite la proprietà dell'oggetto. Assicurati di verificarne l'esistenza prima di utilizzarlo.

Se vuoi includere tutti i post che hanno la categoria attualmente in fase di query, puoi utilizzare il seguente codice. Questo potrebbe potenzialmente includere post che hanno sotto-categorie/figlie della categoria interrogata, ma solo se hanno anche la categoria genitore. Non includerà i post che hanno solo una categoria figlia. In altre parole, dato il seguente scenario:
Categoria 1
Categoria 2, che è una categoria figlia della categoria 1
Post A, che ha solo la categoria 1
Post B, che ha solo la categoria 2
Post C, che ha sia la categoria 1 che la categoria 2
questa query restituirà i post A e C, ma non 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 risposta fornita da @createscape è valida, ma escluderebbe post come il post B, il che potrebbe essere o meno ciò che desideri. Quindi, a seconda di cosa vuoi includere nella tua lista di risultati, potresti usare quella soluzione oppure questa. Ulteriori informazioni qui: https://developer.wordpress.org/reference/classes/wp_query/#category-parameters

Questo funziona bene e impedisce che i post nelle categorie figlie vengano visualizzati nell'elenco della categoria genitore. Tuttavia, assicurati di avere almeno un post in quella categoria genitore, altrimenti otterrai un errore "non trovato" se qualcuno fa clic sulla voce del menu della categoria genitore.

Ho scritto la mia funzione personalizzata per escludere i post delle sottocategorie dal loop, poiché ho scoperto che il codice sopra non funzionava per me.
Nel mio file archive.php del tema, sopra il loop, elenco le sottocategorie:
<?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 } ?>
Nel mio file functions.php, ho aggiunto la seguente funzione personalizzata utilizzando 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() ) {
// Non è una query per una pagina di amministrazione.
// È la query principale per una pagina front-end del tuo sito.
if ( is_category() ) {
// Ottieni la categoria corrente
$current_category = get_queried_object();
// ottieni l'id della categoria corrente
$current_cat_id = $current_category->term_id;
// trova le sottocategorie della categoria corrente
$cat_args = array( 'parent'=>$current_category->term_id, 'child_of' => $current_category->term_id, );
$subcategories = get_categories( $cat_args );
// Ottieni una lista di ID delle sottocategorie, aggiungi un segno meno davanti
$subcat_id = array();
foreach($subcategories as $subcategory) {
$subcat_id[] = " -". $subcategory->term_id;
}
// uniscili insieme come stringa con una virgola come separatore
$excludesubcatlist = join(',', $subcat_id);
// Se hai parametri multipli, usa $query->set più volte
$query->set( 'posts_per_page', '10' );
$query->set( 'cat', ''.$current_cat_id.','.$excludesubcatlist.'' );
}
}
}
Poi in archive.php, sotto le sottocategorie, ho aggiunto il classico loop di WordPress che ora viene modificato dalla funzione sopra:
<?php while (have_posts() ) : the_post(); ?>
<h2><?php the_title();?></h2>
<p> etc....</p>
<?php endwhile;?>
Anche se il codex di WordPress dice che usando "category__in" verranno esclusi i post delle sottocategorie, questo non ha funzionato per me e i post delle sottocategorie continuavano a essere mostrati.
https://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters
https://developer.wordpress.org/reference/hooks/pre_get_posts/

Ok, a partire dal 2019 ho dovuto utilizzare un codice leggermente modificato che funziona con qualsiasi tassonomia, non solo con le categorie standard. L'ho utilizzato con la mia configurazione di WooCommerce e WP, impedendo che i prodotti delle categorie nidificate venissero visualizzati nella categoria genitore:
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 ) //esclude i post nelle categorie figlie
{
$query->tax_query->queries[] = [
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => array_merge( $child_cats ),
'operator' => 'NOT IN'
];
}
}
}
