[WordPress]トップページに複数投稿タイプの最新記事を表示する

最近では当たり前に使われるようになったwordpressのカスタム投稿タイプ。

通常wordpressのトップページでは、デフォルト投稿タイプの最新記事だけがずらりと並びます。けれど、カスタム投稿タイプだって記事を投稿したらトップページに踊り出てきてほしいですよね。

ニュースサイトのように凝った表示にしなくてもいいから、デフォルト投稿タイプと同じようにカスタム投稿タイプの最新記事も並べたい!というときに使えるTipsです。


スポンサーリンク

1. 基本のコード

投稿タイプを指定して表示するコードは以下の通りです。

※2016/11/20追記しました

global $post;
$args=array(
	'post_type' => array('post','tips','nail'), //ここに表示したい投稿タイプを列挙
	'posts_per_page' => 10, //表示する記事の数
	'paged' => $paged, //ページャーを使うための魔法の呪文
	);
$my_posts =get_posts($args);            	
if ( $my_posts ) : 
	foreach($my_posts as $post):setup_postdata($post);
		//ここに記事ループ
	endforeach;
	wp_reset_postdata();
else :
	//ここに記事が見つからなかったときの記述
endif;
  • $args配列に表示する条件をせかせか書く
  • テンプレートタグget_postsで$argsを条件とした投稿オブジェクトを取得
  • 取得した投稿オブジェクトの配列$my_postsを$postにセット(ループ)

このとき、setup_postdata($post)で通常のループと同じように各種テンプレートタグを使えるようになります。

このsetup_postdataは引数としてグローバル変数$postしか使えないけれど、$postをセットはしないという仕様で、事前に$postを宣言→投稿オブジェクトを取得して$postにセット、という手順が必要なのだそうです。

関数リファレンス/setup_postdata

注意点としては、$postを回し終わったらwp_reset_postdataで通常のクエリに戻してあげましょう。経験上ひとつしかループを作らないならなくても困りませんが、そのあとにいろんなループ(カテゴリリストなんかも含まれるのかな?)を置いていると動作がおかしくなったりします。

関数リファレンス/wp_reset_postdata

また、paged=>$pagedを忘れないように記述しましょう。これがないと、ページャーがうまく動きません。(2016/11/20追記)

get_postsは投稿タイプだけでなく色んなパラメータを指定することができるので、「全部の投稿タイプを取ってきたいけどあの投稿タイプだけはこのタクソノミーしかいらない!」なんて要望にも安々と答えてくれます。ブログサイトでないサイトを作ったときはとても重宝しました。

関数リファレンス/get_posts

閑話休題:query_postsは非推奨

同様の動きを実現できるテンプレートタグにquery_postsがあります。けれどこっちはページを読み込んだときに投げたSQLを投げ直して通常のクエリそのものを書き換えてしまう、という動きをするので、想定外の動きをしたり無駄が多くなったりと、なにかと問題児です。Wordpress codexでは決して使うべきではありませんとまで言われています。

2. 「Catch Box」テーマのカスタマイズで実装する

ここからはこのサイトでも使わせて頂いている「Catch Box」テーマでの実装手順を書いていきます。

何も手を加えない状態のトップページに、デフォルト投稿タイプに混じってカスタム投稿タイプの新着記事も並ぶイメージです。というかこのサイトのトップがそうです笑

2-1. home.phpを作成する

トップページを特別な作りにするにはいくつかの方法がありますが、手っ取り早くhome.phpを作りましょう。

Catch Boxにはhome.phpがないので、index.phpをコピーしてhome.phpとリネームします。中身を何も触らずに作ったhome.phpをアップロードすると、見かけ上は何も変わりませんが、内部的にはhome.phpが読み込まれています。

2-2. コードを埋め込む

触る箇所は17行目からの以下の箇所です(空改行は省略しています)。

<?php if ( have_posts() ) : ?>
	<?php /* Start the Loop */ ?>
	<?php while ( have_posts() ) : the_post(); ?>
		<?php get_template_part( 'content', get_post_format() ); ?>
	<?php endwhile; ?>

get_template_partの一行以外はさくっと削除またはコメントアウトしてしまいましょう。

<?php //if ( have_posts() ) : ?>
	<?php /* Start the Loop */ ?>
	<?php //while ( have_posts() ) : the_post(); ?>
		<?php get_template_part( 'content', get_post_format() ); ?>
	<?php //endwhile; ?>

そして、上部に以下のコードを貼り付けます。

<?php global $post;
$args=array(
	'post_type' => array('post','tips','nail'), //表示したい投稿タイプを書いてください
	'posts_per_page' => 10, //表示する記事の数を書いてください
	'paged' => $paged, //ページャーを使うための魔法の呪文
	);
$my_posts =get_posts($args);
if ( $my_posts ) : 
	foreach($my_posts as $post):setup_postdata($post); ?> 

それから、get_template_partの一行を挟んだ下部に以下のコードを貼り付けます。

	<?php endforeach;
	wp_reset_postdata(); ?>

以上です!Catch Boxはコンテンツ部分を別のテンプレートパーツ(content.php)に逃がしているので可変部分がわかりやすいですね。

改変後を単純化すると以下のコードとなります。

<?php
global $post;
$args=array(
	'post_type' => array('post','tips','nail'),
	'posts_per_page' => 10,
	'paged' => $paged,
	);
$my_posts =get_posts($args);
if ( $my_posts ) : 
	foreach($my_posts as $post):setup_postdata($post);
		get_template_part( 'content', get_post_format() );
	endforeach;
	wp_reset_postdata();
?>

17行目のif文から24行目のwhile文まで上記コードを上書きペーストしてもちゃんと動きます(たぶん)。

こんな感じで、ちょっとした小技+Catch boxでのカスタマイズ例をTipsでちょこちょこ書いていけたらなと思います。

この投稿の投稿者は おさみ です。ブックマーク用 パーマリンク

スポンサーリンク