web-dev-qa-db-fra.com

Exclure les publications personnalisées parentes uniquement

Je ne sais pas si cela est possible sans codage en dur, mais j'ai un type de post personnalisé appelé "ville". Dans le type de poste "ville", j'ai un poste de parent (par exemple, l'Angleterre, l'Amérique et la Chine) et quelques messages d'enfants (Londres, Washington DCet Beijing).

J'ai une requête qui affiche tous les messages sous "ville". Mais pour cette requête particulière, je voudrais réellement ignorer TOUT message POST pour les parents (par exemple, Angleterre, Amérique et Chine) et n’afficher que les messages enfant (Londres, Washington et Beijing).

Voici comment je code ma requête:

<?php $city = new WP_Query(array('post_type' => 'city', 'orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1 )); ?>
                            <?php while ($city->have_posts() ) : $city->the_post(); ?>
                                <?php the_title(); ?>
                            <?php endwhile; ?>

Alors est-ce possible? J'aurais pensé que faire le contraire est plus une question populaire (afficher uniquement les parents et exclure les enfants), mais j'espère que mon problème est possible!

Merci

2
remi90

Selon le codex pour WP_Query , la solution pourrait être d'utiliser le post_parent en tant qu'id de la publication de niveau supérieur. Mais comme il y a beaucoup de critiques de haut niveau dans votre cas, je pense que cette solution devrait vous aider: Comment afficher uniquement les publications de haut niveau en boucle via WP_Query? .

Update:

<?php
    $all = get_posts(array('post_type'=> 'city', 'posts_per_page' => -1));
    $parents = array();
    foreach ($all as $single)
    {
        $kids = get_children($single->ID);  
        if(isset($kids) && !empty($kids) && count($kids) >= 1)
        {
            $parents[] = $single->ID;
        }
    }

    $args = array('post_type' => 'city', 'orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1, 'post__not_in' => $parents );

    $city = new WP_Query($args);
    while ($city->have_posts() ) : $city->the_post();
            echo get_the_title()."<br />";
    endwhile;
    wp_reset_postdata();
?>

C'est une coupe longue, mais ça marche. Assurez-vous simplement de vérifier si le tableau $ parents n'est pas vide avant de l'inclure dans la requête.

1
Rutwick Gangurde

Je pense que vous voulez, c'est le filtre posts_where, qui vous permet d'ajouter des clauses WHERE supplémentaires à la requête SQL générée par get_posts. Cela vous évitera de vous rendre dans la base de données pour récupérer uniquement les publications parent.

La fonction accrochée recevra deux arguments: la clause WHERE elle-même et l'objet de requête. Vérifiez si la requête concerne le type d'article city, puis modifiez la clause where à partir de là.

<?php
add_filter( 'posts_where', 'wpse29897_no_parents', 10, 2 );
function wpse29897_no_parents( $where, $query )
{
    if( isset( $query->query_vars['post_type'] ) && 'city' == $query->query_vars['post_type'] )
    {
        if( '' != $where )
        {
            $where .= ' AND post_parent !=  0';
        }
        else
        {
            $where .= ' post_parent != 0';
        }
    }
    return $where;
}

Je suppose que vous ne voulez pas que cela se produise pour CHAQUE requête impliquant le type de publication city, cependant. Le mieux est donc probablement de coller l'appel add_filter juste au-dessus de l'endroit où vous créez le nouvel objet WP_Query. Puis collez la fonction wpse29897_no_parents dans votre fichier functions.php ou un plugin.

<?php 
add_filter( 'posts_where', 'wpse29897_no_parents', 10, 2 );
$city = new WP_Query(array('post_type' => 'city', 'orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1 ));
while ($city->have_posts() ) : $city->the_post(); 
?>
    <?php the_title(); ?>
<?php endwhile; ?>

Vous pouvez même retirer le filtre après votre boucle pour en être sûr.

<?php remove_filter( 'posts_where', 'wpse29897_no_parents', 10, 2 ); ?>
1
chrisguitarguy