WordPressで特定カテゴリの新着記事を表示する方法

テーマ

wpphp_category

WordPressでサイトを運営する上でカテゴリ、タグは欠かせないものです。
中でもカテゴリは必ずと言っていいほど利用されるのではないでしょうか。
記事一覧を特定のカテゴリーに絞って表示したいケースはよくあるものです。

「ニュース」の新着記事だけサムネイル付きでサイドバーに表示したい
「用語一覧」カテゴリの記事タイトルをタイトル順で表示したい
特定のカテゴリのみ除外して新着記事を表示したい

などなど。
今回はカテゴリを限定した記事の表示方法を紹介します。

WordPressの記事取得方法は3種類ある

カテゴリを絞った検索方法をまとめる前に、記事の取得方法を軽くおさらいします。
WordPressでは記事の取得方法が3つあります。それぞれの特徴を見てみましょう。

query_posts(非推奨) そのページでの記事の検索条件(メインクエリと呼びます)を変更するタイプ
get_posts メインクエリは変更せずに、新たな検索条件(カスタムクエリ)を作る
WP_Query メインクエリは変更せずに、新たな検索条件(カスタムクエリ)を作る

メインクエリとは、ざっくり言うとそのページでの記事の検索条件のことです。
基盤となる条件、WordPress本体が定めた条件のため、
テーマテンプレートやプラグインで独自にカスタマイズしなければ、このメインクエリの条件で記事が表示されます。

フロントページ(index.php)なら 「新着記事を◯件取得」、
カテゴリページ(category.php)なら 「特定カテゴリの記事を◯件取得」、
タグページ(tag.php)なら 「特定タグの記事を◯件取得」……等

query_posts を使った「メインクエリ」の変更はしないほうがいい

上のまとめでは query_posts はメインクエリを変更するタイプとなっています。
メインクエリとはそのページに必要だから設定されている条件なので、これを変更した場合はちゃんと後で書き換えた設定を戻すことをしなければ思わぬ問題が起こることがあります。
(リセット方法はこちら:記事が表示されない!?WordPressの記事ループ後にやっておくべきこと
また、場合によってはページャーがうまく動かなかったり、他の記事一覧がおかしくなることもあります。

変更したメインクエリをリセットする方法があるとはいえ、query_posts でなければならないケースはそう多くないので、どうせなら何の心配もないカスタムループを作るタイプ get_posts 、WP_Query を使うことをおすすめします。

get_posts、WP_Query で特定カテゴリの記事を表示する

前置きが長くなりましたが、get_posts/WP_Query それぞれのカテゴリー別取得方法を紹介します。
この3つの関数はメインとは別のループ、サブクエリを作成することができます。

get_posts でのカテゴリ指定方法

get_posts はサブクエリを作成し、指定した検索条件に基づいて記事を返してくれます。
記事のIDやカテゴリ、タグ、投稿者、日付やソート順等、さまざまな条件が設定できます。

例1:カテゴリーIDが3と4の記事を取得する条件

<?php 
$args = ['category' => '3,4'];

// 条件を渡して記事を取得
$custom_posts = get_posts($args);
?>
<ul>
<?php 
foreach ( $custom_posts as $post ): setup_postdata($post); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>

例2:カテゴリーのスラッグが「news」の記事を10件取得する条件

<?php
$args = [
	'category_name' => 'news',
	'numberposts' => 10
];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = get_posts($args);

foreach ( $custom_posts as $post ): setup_postdata($post); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>

例3:カテゴリースラッグが「wordpress」の記事をタイトル昇順で取得する条件

<?php
$args = [
	'category_name' => 'wordpress',
	'orderby' => 'title',
	'order' => 'ASC'
];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = get_posts($args);

foreach ( $custom_posts as $post ): setup_postdata($post); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>

例4:カテゴリーIDが10の記事のみ除外して最新記事を取得する条件

複数指定する場合、例1と同じように,で区切ります。

<?php
$args = ['category' => '-10'];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = get_posts($args);

foreach ( $custom_posts as $post ): setup_postdata($post); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
?>

setup_postdata() はグローバル変数である$postを整形する関数です。
これがないと the_content() などのテンプレートタグが動きません。通常の記事ループと同じような仕様にさせる下準備です。get_posts ではforeachの直後に使っておくといいです。

WP_Query でのカテゴリ指定方法

WP_Queryクラス は get_posts 以上に高機能ですが使い方は大体同じです。
検索条件として渡したパラメーターに基づいて記事を返してくれます。

WP_Queryを使う場合、ループ終了後、必ずクエリのリセットをしましょう。
wp_reset_query() でリセットができます。
リセットをしない場合、テーマによっては記事のタイトルが変わってしまったり、
意図しない挙動になります。

例1、カテゴリーIDが3と4の記事を取得する条件

<?php 
$args = [
	'category_name' => 'news',
	'posts_per_page' => 10
];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile;

// 必ずクエリをリセット
wp_reset_query();
 ?>
</ul>

例2:カテゴリースラッグが「news」の記事を10件取得する条件

<?php 
$args = [
	'category_name' => 'news',
	'posts_per_page' => 10
];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile;

// 必ずクエリをリセット
wp_reset_query();
 ?>
</ul>

例3:カテゴリースラッグが「wordpress」の記事をタイトル昇順で取得する条件

<?php 
$args = [
	'category_name' => 'wordpress',
	'orderby' => 'title',
	'order' => 'ASC'
];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; 

// 必ずクエリをリセット
wp_reset_query();
?>
</ul>

例4:カテゴリーIDが5と8の両方を含む記事を取得する条件

<?php 
$args = ['category__and' => [5, 8]];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; 

// 必ずクエリをリセット
wp_reset_query();
?>
</ul>

例5:カテゴリIDが2もしくは10いずれかを含む記事を取得する条件

<?php 
$args = ['category__in' => [2, 10]];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; 

// 必ずクエリをリセット
wp_reset_query();
?>
</ul>

例6:カテゴリーIDが10の記事のみ除外した最新記事を取得する条件

<?php 
$args = ['cat' => '-10'];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile;

// 必ずクエリをリセット
wp_reset_query();
 ?>
</ul>

例7:カテゴリーIDが20か30を含む記事は除外する条件

<?php 
$args = ['category__not_in' => [20, 30]];
?>

<ul>
<?php 
// 条件を渡して記事を取得
$custom_posts = new WP_Query($args);

while ( $custom_posts->have_posts() ) : $the_query->the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile;

// 必ずクエリをリセット
wp_reset_query();
 ?>
</ul>

query_posts でのカテゴリ指定方法(非推奨)

あまり推奨されませんがこちらも紹介します。
query_posts ではパラメーターを渡して記事を表示したあと必ずリセットを忘れずに!

<?php 

// 例1:カテゴリーIDが3と4の記事を取得する条件
$args = ['cat' => '3,4'];

// 例2:カテゴリースラッグが「news」の記事を10件取得する条件
$args = [
	'category_name' => 'news',
	'posts_per_page' => 10
];

// 例3:カテゴリースラッグが「terminology」の記事をタイトル昇順で取得する条件
$args = [
	'category_name' => 'terminology',
	'orderby' => 'title',
	'order' => 'ASC'
];

// 例4:カテゴリーIDが5と8の両方を含む記事を取得する条件
$args = ['category__and' => [5, 8]];

// 例5:カテゴリIDが2もしくは10いずれかを含む記事を取得する条件
$args = ['category__in' => [2, 10]];

// 例6:カテゴリーIDが10の記事のみ除外した最新記事を取得する条件
$args = ['cat' => '-10'];

// 例7:カテゴリーIDが20か30を含む記事は除外する条件
$args = ['category__not_in' => [20, 30]];

?>

<ul>
<?php 
// 条件を渡す(メインクエリを変更)
query_posts( $args );

while ( have_posts() ) : the_post(); ?>
	<li><?php the_time('Y/m/d') ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>
</ul>
<?php

// 必ずクエリをリセット
wp_reset_query();

?>

おわりに

WPでの記事ループはとりあえず get_posts、もっと詳しく指定したいなら WP_Query がいいのではないでしょうか!
query_posts はメインの検索条件に加えて記事数を弄りたいときなど、ちょっとした変更のときに使うと良さそうです。
query_postsとWP_Queryはリセットを忘れずに。

クエリリセットを忘れずに。

テーマ

関連記事