web-dev-qa-db-fra.com

query_posts exclut une clé méta

<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_key' => featured_product, 'meta_value' => 1)); ?>


<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC')); ?>

J'ai 2 requêtes, la première pour montrer la méta clé avec Featured_product eq 1. Je souhaite donc exclure tous les produits présentés de la seconde requête. Comment puis-je faire ça s'il vous plaît? Merci!

4
ray

Je n'ai jamais eu la moindre chance de comparer la méta au travail - mais j'ai trouvé une solution de contournement pour cette situation précise (avoir "présenté" des éléments en haut de la page).

Tout d'abord, vous ne devriez probablement pas utiliser query_posts pour les deux requêtes. Vous devez utiliser une requête personnalisée pour au moins la première. Ensuite, pendant que vous exécutez cette boucle, conservez les identifiants de toutes les publications "en vedette" dans une variable. Lorsque vous exécutez votre deuxième boucle, vous pouvez utiliser l'argument "post__not_in" pour exclure celles qui sont présentées. Ainsi:

// Set up a custom query
$featured_query = new WP_query();

// Your query args
    $featured_args=array(
        'post_type'=>'post',
        'meta_key'=>'featured_product',
        'meta_value'=>'1'
    );

// Run it
    $featured_query->query($featured_args);

    if ($featured_query->have_posts()) {

    while ($featured_query->have_posts()) {

            $featured_query->the_post();

        // Remember the featued ID
        $featured_post_id = get_the_ID(); 

        // Render your featured post here

    }

}

// Set up the args for your main query
$args = array(
        'post_type' => 'post',
        'post__not_in' => array($featured_post_id) // Don't show the featured post
    );

// Now run your main query and so on...
6
MathSmath

La réponse de MathSmath est correcte, mais elle est très inefficace et ne serait pas adaptée à un site WordPress contenant plus de 100 000 publications ou ce que vous avez. Faire une WP_Query() pour 1000 messages sera assez lent.

Plutôt que d'utiliser un posts_not_it (qui transmettrait une requête longue si vous aviez plusieurs milliers de publications ici) si vous avez MySQL 4.1+, il serait préférable d'utiliser une sous-requête pour exclure les publications que vous ne voulez pas.

Voici un exemple légèrement modifié que j'utilise sur un site comptant plus de 250 000 publications.

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );    

// make the query, the below function will be called
query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC'));

function _exclude_meta_key_in_posts_where( $where ) {

    global $wpdb;
    return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured_product' AND meta_value > '' )";
}

//remove the filter incase we do any more query_posts()s
remove_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );

Vous pourriez probablement tout faire en une create_function() bien que je ne sois pas sûr que ce soit très efficace, mais ce serait moins de lignes:

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', create_function( '$where', 'global $wpdb; return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = \'featured_product\' AND meta_value > \'\' )";' ) );

Je n'ai pas testé l'exemple create_function().

7
Joe Hoyle

Ma solution a été d’ajouter le champ personnalisé avec une valeur "false" à tous les messages existants et d’accrocher la création de nouveaux messages afin d’y ajouter le champ.

Je ne suis pas sûr que ce soit un moyen plus efficace de gérer cette situation, mais je voulais éviter les requêtes SQL personnalisées.

Voici une fonction à usage unique que j'ai utilisée pour ajouter le champ à tous les postes existants:

function unfeature_all() {
    $args = array(
        'numberposts'   => -1,
    );

    $posts = get_posts( $args );

    foreach ($posts as $post) {
        $status = get_post_meta($post->ID, 'featured_post', true);
        if (!$status) {
            update_post_meta($post->ID, 'featured_post', false);
        }
    }

}

if (current_user_can('manage_options')) unfeature_all();
1
Arieleo

Je n'ai pas essayé cela, mais certaines recherches m'ont laissé le faire. En utilisant meta_compare, vous pouvez vérifier si meta_value n'est pas égal à 1 et afficher les posts.

<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_value' => featured_product, 'meta_compare' => '!=', 'meta_value' => 1 )); ?>
1
eileencodes