Come visualizzare solo i post di primo livello nel loop con WP_Query?
Come posso impostare il mio loop personalizzato per mostrare solo i post di primo livello? Ho un tipo di post personalizzato gerarchico e la pagina archivio mostra sia i post genitore che quelli figlio.

Questa soluzione si basa su del codice di Justin Tadlock. pre_get_posts viene chiamato prima che WordPress recuperi i post del loop principale. In sostanza, si verifica se la pagina è un archivio del tipo di post e si assicura che post_parent non sia stato impostato. Quindi si imposta post_parent a 0, che è il genitore predefinito per i post di livello superiore. Semplice come bere un bicchier d'acqua.
<?php
//pre_get_posts filter è chiamato prima che WordPress recuperi i post
add_filter( 'pre_get_posts', 'my_get_posts' );
function my_get_posts( $query ) {
//Se l'utente sta visualizzando il frontend, la pagina è un archivio e post_parent non è impostato e post_type è il tipo di post in questione
if ( ! is_admin() && is_archive() && false == $query->query_vars['post_parent'] && $query->query_vars['post_type'] === 'my_post_type')
//imposta post_parent a 0, che è il post_parent predefinito per i post di livello superiore
$query->set( 'post_parent', 0 );
return $query;
}
?>

Prendendo spunto dal post di @Ryan, la chiave è impostare post_parent=0
e post_type='page'
.
Puoi sempre visualizzare la richiesta SQL dell'oggetto WP_Query per vedere quali argomenti devi aggiungere per ottenere i risultati desiderati.
Questo codice funziona per me:
<?php
$args=array('post_parent' => 0, // obbligatorio
'post_type' => 'page', // obbligatorio
'orderby' => 'menu_order', // per visualizzare secondo la gerarchia
'order' => 'ASC', // per visualizzare secondo la gerarchia
'posts_per_page' => -1, // per visualizzare tutti perché il default è 10
);
$query = new \WP_Query( $args );
/* Rimuovi il commento per vedere l'SQL risultante per debug
echo $query->request; die();
//*/
if ( $query->have_posts() ) {
while($query->have_posts()) {
$query->the_post();
$post_id=get_the_ID();
$post=get_post($post_id,'ARRAY_A');
echo $post['ID'].': '.$post['post_title'].'<br>';
}
}
