「WordPress でサムネイルが存在する記事だけ一覧で表示したい」という相談を受けました。
普通に考えると以下のように has_post_thumbnail() を使って条件分岐すれば良さそうですが、これだと1ページに表示される記事数がバラバラになってしまいます。
また、ページネーションも上手く行きません。
(サムネイルが無い記事もページネーションの対象になってしまい、空白ページができてしまう)
<?php if(have_posts()): while(have_posts()): the_post(); ?> <?php if ( has_post_thumbnail() ) {?> --内容-- <?php } ?> <?php endwhile; endif; ?>
こんな時は posts_where フィルターフックを使って、投稿を取得する際の条件文を変更してやりましょう。
こんな感じのコードをテーマの <?php
より下、get_header();
より上に書いておきましょう。
# 例えば、トップページのみ対応したければ top.php
global $query_string; function posts_where_thumbnail($where) { global $wpdb; $where .= " AND EXISTS (select 'x' from {$wpdb->prefix}postmeta where {$wpdb->prefix}posts.ID = {$wpdb->prefix}postmeta.post_id and {$wpdb->prefix}postmeta.meta_key = '_thumbnail_id') "; return $where; } add_filter('posts_where', 'posts_where_thumbnail'); query_posts($query_string);
簡単に説明すると
- posts_where フィルターフックを使って、$posts を取得する際の where 文にサムネイル有りの投稿だけを対象にする条件を追加
- query_posts() で投稿を取得しなおす
ということをやってます。
これでサムネイルが無い投稿は対象外になるため、while(have_posts()):
のループ内にはサムネイルがある投稿だけが出てきます。
また、これによりページネーションされる際の元になる $posts も置き換えているため、特に何もせずともページネーションが上手いことできるようになります。
ここで注意したいのは、このコードは functions.php に書いてしまってはいけないということです。
それやっちゃうと、すべてのページでサムネイルが無い記事が表示されなくなっちゃいますので 🙂