web-dev-qa-db-fra.com

En boucle: les publications ont une vignette ET d'autres variables

Je cherche à afficher des messages qui répondent à certaines exigences. Tout d’abord, l’idée est de montrer aux visiteurs les messages les plus visités. J'ai implémenté cela avec un peu d'aide . Donc, je travaille avec le PHP suivant. Je travaille pour moi, c'est Nice. Maintenant, je veux ajouter une contrainte, à savoir: seules les publications avec des miniatures devraient être éligibles pour la boucle, mais vous ne pouvez pas ignorer une publication si elle ne comporte pas de vignette et simplement créer moins de publications dans la sortie réelle: J'ai besoin de quatre postes au total! Donc, idéalement, je veux un moyen de passer un argument qui dit "a une vignette" au WP_Query. Cependant, j'ai aussi besoin de la méta_key déjà présente. Comment puis-je conserver cette clé méta et en utiliser un autre? J'ai trouvé ici que vous pouvez ajouter 'key' => '_thumbnail_id', mais je ne sais pas comment ajouter plusieurs clés à cette requête.

N'oubliez pas que je dois utiliser orderby, qui ordonne les publications dans l'ordre de la plupart des vues.

Par souci d'exhaustivité, je posterai l'intégralité de l'extrait, en pensant à la réponse de Pieter Goosen. Je pensais que le "30 jours" ne ferait aucune différence, mais maintenant je me rends compte que cela pourrait être le cas. post_date_selection est une fonction dans functions.php qui limite les publications aux 30 derniers jours. Je l'ai eu de ici .

<?php if (is_home()) : ?>
  <section class="featured-posts clear">
    <?php // restrict loop to 30 last days, see functions.php
      add_filter('posts_where', 'post_date_selection');
      global $query_string;
      query_posts($query_string);
    ?>
    <?php 
      $args = array(
        'order'             => 'DESC',
        'posts_per_page'    => 4,
        'meta_key'          => 'post_views_count',
        'orderby'           => 'meta_value_num',
        'meta_query'        => array(
          'relation'      => 'AND',
          array(
            'key' => 'post_views_count',
            'compare' => 'EXISTS'
          ),
          array(
            'key' => '_thumbnail_id',
            'compare' => 'EXISTS'
          ),
        ),
      );
      $popularPosts = new WP_Query($args);
      $counter = 1;
    ?>
    <?php while ($popularPosts->have_posts() ) : $popularPosts->the_post(); ?>
      <article class="box-<?php echo $counter++; ?>">
        <a href=" <?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?><span><?php the_title(); ?></span></a>
      </article>
    <?php endwhile; ?>
    <?php wp_reset_postdata(); ?>
  </section>
<?php endif; // is_home ?>
<?php remove_filter('posts_where', 'post_date_selection'); // remove restriction from loop ?>

Principales fonctions de functions.php:

/*
 * Getting and setting post count
 */
// Set post count
function set_post_views($postID) {
    $count_key = 'post_views_count';
    $count = get_post_meta($postID, $count_key, true);
    if($count==''){
        $count = 0;
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, '0');
    }else{
        $count++;
        update_post_meta($postID, $count_key, $count);
    }
}
// To keep the count accurate, lets get rid of prefetching
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0);

// Update post count
function track_post_views ($post_id) {
    if ( !is_single() ) return;
    if ( empty ( $post_id) ) {
        global $post;
        $post_id = $post->ID;    
    }
    set_post_views($post_id);
}
add_action( 'wp_head', 'track_post_views');

// Only 30 last days, needs in content
function post_date_selection ($when = '') {
    $when .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
    return $when;
}
3
Bram Vanroy

Vous pouvez utiliser les paramètres de champ personnalisés dans WP_Query comme vous l'avez fait, il vous suffit de l'étendre un peu plus loin.

Vous pouvez faire votre tri par post_views_count et utiliser meta_query pour obtenir toutes les publications qui ont le plus grand nombre de vues et une miniature de publication.

Vous pouvez probablement essayer quelque chose comme ça

$args = array(
    'order'             => 'DESC',
    'posts_per_page'    => 20,
    'meta_key'          => 'post_views_count',
    'orderby'           => 'meta_value_num',
    'meta_query'        => array(
        'relation'      => 'AND',
        array(
            'key' => 'post_views_count',
            'compare' => 'EXISTS'
        ),
        array(
            'key' => '_thumbnail_id',
            'compare' => 'EXISTS'
        ),
    ),
);
$popularPosts = new WP_Query( $args );

Pour un décompte plus précis des vues, consultez ce message je l’ai fait sur le sujet. C'est très précis et ne compte pas les doubles vues

EDIT

En passant, vous devez réinitialiser votre requête personnalisée et, d’autre part, les requêtes any and all custom car elles seront influencées et influenceront les autres requêtes. Juste après <?php endwhile; ?>, ajoutez <?php wp_reset_postdata(); ?>

EDIT 2

J'ai testé votre code, et cela casse mon contenu dans l'encadré. J'ai modifié votre code pour le code ci-dessous. Cela fonctionne comme prévu, seules les publications des trente dernières années sont récupérées en fonction du fait qu’elles ont des miniatures et qu’elles sont classées par le plus grand nombre de publications. Je teste également ceci sur localhost. Une autre chose que vous devez prendre en compte, vous devez avoir Wordpress 3.9+ pour que cela fonctionne

Il n'est pas nécessaire de spécifier une valeur lorsque vous utilisez les comparaisons "EXISTS" ou "NOT EXISTS" dans WordPress version 3.9 et ultérieure.

<?php if (is_home()) : ?>
    <section class="featured-posts clear">
        <?php
        function filter_where($where = '') {
        //posts in the last 30 days
            $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
            return $where;
        }

        add_filter('posts_where', 'filter_where');

        $args = array(
            'order'             => 'DESC',
            'posts_per_page'    => 20,
            'meta_key'          => 'post_views_count',
            'orderby'           => 'meta_value_num',
            'meta_query'        => array(
                'relation'      => 'AND',
                array(
                    'key' => 'post_views_count',
                    'compare' => 'EXISTS'
                ),
                array(
                    'key' => '_thumbnail_id',
                    'compare' => 'EXISTS'
                ),
            ),
        );
        $popularPosts = new WP_Query( $args );

        remove_filter('posts_where', 'filter_where');

        $counter = 1; ?>

        <?php while ($popularPosts->have_posts() ) : $popularPosts->the_post(); ?>
        <article class="box-<?php echo $counter++; ?>">
            <a href=" <?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?>
                <span><?php the_title(); ?></span>
            </a>
        </article>
        <?php endwhile; ?>
        <?php wp_reset_postdata(); ?>

    </section>
<?php endif; // is_home ?>

EDIT 3

Vous pouvez également utiliser l'approche décrite dans cette réponse de @ialocin à l'une de mes questions pour appliquer et supprimer un filtre à l'aide de pre_get_posts. Ce code peut être très facilement adapté pour être utilisé sur votre requête personnalisée. Personnellement, j'estime qu'il s'agit d'une meilleure méthode à utiliser pour appliquer et supprimer votre filtre personnalisé pour votre requête personnalisée.

3
Pieter Goosen