「トップページのサイドバーに新着記事を並べたい」「企業サイトの新着情報(お知らせ一覧)をWordPressで自動的に出力したい」――Web制作の現場でほぼ毎回出てくる定番の要望です。私自身、コーポレートサイトを組むたびに必ず実装してきました。
やり方そのものは難しくありません。ただ、WordPressは歴史が長いぶん、ネット上には今では推奨されない古い書き方の記事もたくさん残っています。せっかく実装したのにメインループが壊れる、ページネーションがおかしくなる、といったトラブルの多くは、その「古い書き方」が原因です。
この記事では、私が普段使っている2026年時点で正しく動く出力方法を、用途別に整理して紹介します。テンプレートに直接書くWP_Queryとget_posts()、それからコードを書かずに済むブロックの3パターンです。どれを選べばいいかの判断もあわせて解説するので、自分のサイトに合うものを選んでください。
そもそも新着記事一覧は何で作るのが正解か
結論から言うと、テンプレートファイルに自前のループを書くならWP_Queryが現在の基本です。
かつてはquery_posts()という関数がよく使われていました。私も昔は使っていましたが、これはメインクエリそのものを書き換えてしまう関数で、ページネーションが狂ったり、後続の処理に副作用が出たりと厄介な問題を起こします。WordPress公式も使用を推奨していません。古い解説記事をコピーしてquery_posts()を使ってしまうのが、新着一覧まわりでいちばん多いつまずきです。
今の選択肢を整理すると、おおむね次の3つになります。
- WP_Query:テンプレート内で柔軟にループを組みたいときの基本。カスタムの一覧表示はほぼこれで対応できます。
- get_posts():投稿を配列でサクッと取得したいとき。サイドバーの簡単な新着リストなどに向きます。
- ブロック(最新の投稿ブロック):コードを書かずに、ブロックエディターやサイトエディターから設置したいとき。
以下、それぞれ具体的に見ていきます。
WP_Queryで新着記事一覧を出力する(推奨)
まずは基本のWP_Queryです。新しいクエリオブジェクトを作り、have_posts()とthe_post()でループを回す、という流れになります。
<dl class="news-list">
<?php
$news_query = new WP_Query( array(
'posts_per_page' => 5,
'post_status' => 'publish',
) );
if ( $news_query->have_posts() ) :
while ( $news_query->have_posts() ) : $news_query->the_post(); ?>
<dt><?php echo esc_html( get_the_date( 'Y/m/d' ) ); ?></dt>
<dd><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></dd>
<?php endwhile;
else : ?>
<dd>記事がまだありません。</dd>
<?php endif;
wp_reset_postdata(); ?>
</dl>
ポイントを順に説明します。
posts_per_pageが表示件数です。すべての投稿を出したいときは-1を指定します。post_status => 'publish'を入れておくと、公開済みの記事だけが対象になります。
日付の出力には、ループ内の現在位置に依存するthe_time()よりも、引数で書式を渡せるget_the_date()を使うのが今どきです。出力前にesc_html()でエスケープしておくと安全です。
そして最後のwp_reset_postdata()が最重要です。これを忘れると、グローバルな$post変数がループ後も書き換わったままになり、ページ内のほかのテンプレートタグが意図しない記事の情報を表示してしまいます。サブループを作ったら必ず呼ぶ、と覚えておいてください。私が他人のテーマを修正するとき、新着一覧の不具合はだいたいこのリセット漏れです。
カテゴリーを絞って出力する
「お知らせ」カテゴリーだけを新着情報として出したい、という場面も多いはずです。その場合はカテゴリーのスラッグで絞り込むのがわかりやすくておすすめです。
$news_query = new WP_Query( array(
'posts_per_page' => 5,
'category_name' => 'news', // カテゴリーのスラッグで指定
) );
カテゴリーIDで指定したい場合は'cat' => 1のように書きます。複数指定する場合はカンマ区切りの文字列か配列を渡します。IDは管理画面でカテゴリーを編集する際のURL(tag_ID=の数値)で確認できます。私はサイトを引き継ぐ可能性を考え、IDより変更に強いスラッグ指定を好んで使っています。
出典:WordPress Developer Resources|Class: WP_Query
get_posts()で手早く新着リストを取得する
サイドバーやフッターに「最近の記事を5件だけ」といった軽い用途なら、get_posts()のほうが手数が少なくて済みます。投稿オブジェクトの配列を返してくれる関数で、内部的にはWP_Queryを使っているためメインループには影響しません。foreachで回す書き方になります。
<dl class="news-list">
<?php
$recent_posts = get_posts( array(
'numberposts' => 5,
'post_status' => 'publish',
) );
foreach ( $recent_posts as $post ) :
setup_postdata( $post ); ?>
<dt><?php echo esc_html( get_the_date( 'Y/m/d' ) ); ?></dt>
<dd><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></dd>
<?php endforeach;
wp_reset_postdata(); ?>
</dl>
件数はnumberpostsで指定します(-1で全件)。古い記事だとget_posts('numberposts=5&category=1')のように文字列でパラメータを渡す書き方を見かけますが、今は上記のように配列で渡すほうが読みやすく、ミスも減らせます。
注意したいのは、ループ内でthe_title()やthe_permalink()といったテンプレートタグを使うためにsetup_postdata( $post )が必要な点です。そしてこちらも処理の最後にwp_reset_postdata()を呼びます。WP_Queryと同じく、リセットは省略できません。
出典:WordPress Developer Resources|get_posts()
コードを書かずにブロックで設置する
テーマファイルを触りたくない、あるいは固定ページや投稿の本文中に新着一覧を差し込みたいだけ、という場合はブロックが手っ取り早いです。
ブロックエディターで挿入ボタン(+)から「最新の投稿」を検索するか、新しい行で/latestと入力すると追加できます。設定パネルからは次のような項目を調整できます。
- 表示件数とカテゴリーによる絞り込み
- リスト表示/グリッド表示の切り替え
- アイキャッチ画像、投稿日、抜粋の表示・非表示
ブロックテーマ(サイトエディター対応のテーマ)を使っているなら、より柔軟な「クエリーループブロック」も選べます。こちらはレイアウトを自分で組み立てられるため、デザインにこだわった一覧も作れます。テンプレート全体を編集できるので、トップページや投稿一覧テンプレートに新着情報を組み込みたいときに便利です。
ちなみに昔ながらの「ウィジェット」にも最近の投稿を表示する機能があり、サイドバーに置くだけなら今でもこれで十分なケースもあります。要するに、コードを書かない選択肢は複数あるということです。「とにかく簡単に出したい」だけなら、まずはブロックを試すのが近道です。
出典:WordPress.org Documentation|Latest Posts block
まとめ:用途で使い分ければ迷わない
新着記事一覧の出力方法を、改めて用途別に整理しておきます。
- テンプレートで柔軟に組むなら
WP_Query。カスタムの一覧表示はこれが基本。迷ったらこれを選んでおけば間違いありません。 - サイドバーなどの軽い新着リストなら
get_posts()。配列をforeachで回すだけで手早く出せます。 - コードを書きたくないなら「最新の投稿」ブロックやクエリーループブロック。ブロックテーマとの相性も良好です。
そして共通の鉄則がひとつ。WP_Queryでもget_posts()でも、サブループの最後には必ずwp_reset_postdata()を呼ぶこと。これさえ守れば、メインループやページネーションが壊れるトラブルはほぼ防げます。
逆に、ネット上で見かけるquery_posts()を使った古いコードは避けてください。動いているように見えても副作用の温床になります。最初に正しい書き方を選んでおくほうが、結局いちばん早道です。