Puis-je exclure un message par une clé méta à l'aide de la fonction pre_get_posts?

21

Je vois que beaucoup de gens préfèrent utiliser pre_get_posts hook au lieu de query_posts . Le code ci-dessous fonctionne et montre tous les messages qui ont la méta clé "sélectionnée"

function show_featured_posts ( $query ) {
    if ( $query->is_main_query() ) {
       $query->set( 'meta_key', 'featured' );
       $query->set( 'meta_value', 'yes' );
    }
}

add_action( 'pre_get_posts', 'show_featured_posts' );

Toutefois, je souhaite que les publications contenant la méta_key ' featured ' soient exclues de la requête principale. Y a-t-il un moyen facile pour cela?

    
posée Carlisle 10.11.2012 - 00:55
la source

3 réponses

30
  

Je vois que beaucoup de gens préfèrent utiliser le hook pre_get_posts au lieu de query_posts

Oui!

So pre_get_posts filtre un WP_Query object , ce qui signifie quoi que ce soit que vous puissiez faire. via query_posts() , vous pouvez le faire via $query->set() et $query->get() . En particulier, nous pouvons utiliser l'attribut meta_query (voir Codex ):

$meta_query = array(
                 array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                 ),
);
$query->set('meta_query',$meta_query);

Mais .. ceci remplace la 'méta requête' originale (si elle en avait une). Donc, à moins que vous ne vouliez remplacer complètement la méta-requête d'origine, je suggère:

//Get original meta query
$meta_query = $query->get('meta_query');

//Add our meta query to the original meta queries
$meta_query[] = array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                );
$query->set('meta_query',$meta_query);

De cette façon, nous ajoutons notre méta requête aux côtés des méta requêtes existantes.

Il est possible que vous souhaitiez ou non définir la propriété relation de $meta_query sur AND ou OR (pour renvoyer des publications qui satisfont à toutes les méta-requêtes ou à au moins une d'entre elles).

* Remarque: Ce type de requête renverra les publications contenant la clé méta 'sélectionnée', mais dont la valeur n'est pas yes . Cela n'inclut pas les publications pour lesquelles la clé méta 'sélectionnée' n'existe pas. vous pourrez le faire dans la version 3.5 .

    
réponse donnée Stephen Harris 10.11.2012 - 11:32
la source
2

Je souhaite publier ma solution temporaire pour les publications en vedette au cas où certaines personnes pourraient s'en servir. Je n'utilise pas pre_get_posts hook ici, mais pas query_posts non plus. Le problème est que je dois jouer avec la requête principale et exécuter une requête SQL. Je serais heureux si des experts pouvaient vérifier le code et me laisser savoir si tout va bien et ne causera pas de problèmes de performances. Ce sera également formidable si quelqu'un a une meilleure approche et le partage avec nous.

Créer une requête pour les messages en vedette

<?php 

$featured_query = new WP_query( array(
    'meta_key'       =>'featured', 
    'meta_value'     =>'yes', 
    'posts_per_page' => 5, 
    'no_found_rows'  => true
    )
);

while ($featured_query->have_posts()) : 

    $featured_query->the_post(); 
    //Stuff...

endwhile; 
wp_reset_postdata(); 

?>

Créez la requête principale, excluez les publications contenant la méta_key sélectionnée, limitez l'exclusion aux 5 publications les plus récentes et affichez toutes les autres.

<?php 

$excludeposts = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured' AND meta_value != '' ORDER BY post_id DESC LIMIT 0, 5" );

$main_query = new WP_Query( array(
    'post__not_in' => $excludeposts, 
    'paged' => $paged 
    ) 
);  

while ($main_query->have_posts()) : 

    $main_query->the_post();
    //Stuff...

endwhile;

?>
    
réponse donnée Carlisle 10.11.2012 - 17:27
la source
0

Dans la réponse @Carlisle, si vous souhaitez exclure les 5 publications les plus récentes sélectionnées, procédez comme suit. Modifiez le nombre de posts que vous souhaitez exclure avec posts_per_page et la méta_query selon le mode de désignation de la catégorie sélectionnée.

function cmp_exclude_featured_posts($query) {
    $exclude = array();  //Create empty array for post ids to exclude
    if ( $query->is_main_query() ) {
            $featured = get_posts(array(
                'post_type' => 'post',
                'meta_query' => array(
                    array(
                        'key' => 'featured',
                        'value' => '1',
                        'compare' => '==',
                    ),
                ),
                'posts_per_page' => 2
            ));

            foreach($featured as $hide) {
                $exclude[] = $hide->ID;
            }   

            $query->set('post__not_in', $exclude);
        }
}

add_filter( 'pre_get_posts', 'cmp_exclude_featured_posts' );
    
réponse donnée cpeckens 29.04.2015 - 20:21
la source

Lire d'autres questions sur les étiquettes