web-dev-qa-db-ja.com

ループ内:投稿にはサムネイルと他の変数があります

特定の要件を満たす投稿を表示しようとしています。まず第一に、アイデアは訪問者に最も閲覧された投稿を表示することです。 ある程度の助けを借りて を実装しました。だから、私はそれが次のPHPで動作するようになった。私はそれがうまくいくようになった。今、私は制約を加えたいと思います。すなわち、サムネイルのある投稿だけがループに適格であるべきですが、サムネイルがなければ投稿をスキップすることはできず、実際の出力で投稿を減らすことはできません。全部で4つの投稿が必要です。そのため、理想的には、「サムネイルがある」という引数をWP_Queryに渡す方法が必要です。ただし、me​​ta_keyも既に存在している必要があります。どのようにしてそのメタキーを保持し、別のものを使用することができますか: ここ あなたが'key' => '_thumbnail_id'を追加できることがわかりました、しかし私がこの問い合わせに複数のキーを追加できる方法がわかりません。

私はorderbyを使う必要があることを覚えておいてください。

完全を期すために、Pieter Goosenの答えを念頭に置いて、スニペット全体を投稿します。私は「30日」は違いがないと思いました、しかし今私はそれが大丈夫であることに気づきます。 post_date_selectionは、投稿を過去30日間に制限するfunctions.phpの関数です。 ここ から入手しました。

<?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 ?>

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

WP_Query にあるカスタムフィールドパラメータを利用することができます、あなたはそれをもう少し拡張する必要があります。

post_views_countでソートして、meta_queryを使用して、投稿の表示回数が最も多く、投稿のサムネイルがあるすべての投稿を取得できます。

あなたはおそらくこのようなことを試すことができます

$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 );

より正確な投稿ビュー数については、 この投稿 /を参照してください。それは非常に正確であり、二重のビューを数えません

編集

ちなみに、あなたはあなたのカスタムクエリをリセットする必要があります、そしてそれに関しては、それらが影響を受けて他のクエリに影響するのでanyとすべてのカスタムクエリ。 <?php endwhile; ?>の直後に<?php wp_reset_postdata(); ?>を追加

EDIT 2

私はあなたのコードをテストしました、そしてそれは私のサイドバーの内容を壊します。あなたのコードを以下のコードに変更しました。それは予想通りに動作します、それが最後の30からの投稿だけがそれが投稿サムネイルを持っていて最も高い投稿数で順序付けられているという事実に従って検索されます。私はlocalhostでもこれをテストしています。あなたが注意する必要があるもう一つのことは、これが動作するためにはWordpressの3.9 +を持っている必要があります

WordPress 3.9以降で 'EXISTS'または 'NOT EXISTS'比較を使用するときは、値を指定する必要はありません。

<?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

pre_get_postsを使用してフィルタを適用および削除するには、 この@ialocinによる回答 で説明されているアプローチを使用することもできます。このコードは、カスタムクエリで使用するために非常に簡単に適応させることができます。私は個人的にはこれがあなたのカスタムクエリにあなたのカスタムフィルタを適用したり削除するのに使うより良い方法だと思います

3
Pieter Goosen