WordPress でサムネイルがある記事だけ表示する方法

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

簡単に説明すると

  1. posts_where フィルターフックを使って、$posts を取得する際の where 文にサムネイル有りの投稿だけを対象にする条件を追加
  2. query_posts() で投稿を取得しなおす

ということをやってます。

これでサムネイルが無い投稿は対象外になるため、while(have_posts()): のループ内にはサムネイルがある投稿だけが出てきます。
また、これによりページネーションされる際の元になる $posts も置き換えているため、特に何もせずともページネーションが上手いことできるようになります。

ここで注意したいのは、このコードは functions.php に書いてしまってはいけないということです。
それやっちゃうと、すべてのページでサムネイルが無い記事が表示されなくなっちゃいますので 🙂

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください