【WordPress】カスタム投稿のシングルページに関連記事を表示する
少しつまづいたというよりも、get_posts()のパラメータで色々と出来ることが分かったので、備忘録をかねて記事に。
get_posts()は、新着記事や関連記事などの投稿データを取得する際に使用しますが、パラメータがたくさん用意されていて、投稿データをかなり絞り込むことができるんですね。
注:タイトルに「カスタム投稿のシングルページ」としていますが、これに限ったわけではなく、どのテンプレートでも基本は問題ないかと思います。以下も「カスタム投稿のシングルページ」に限定した書き方になっていますが、あまり気にしなくてもいいかもしれないです、たぶん。
single-○○○.php に同じカスタム投稿の記事を表示
カスタム投稿タイプを作成して、それに属する記事をsingle.phpとは別のデザインで表示させたい場合、”single-カスタム投稿タイプ名.php”というテンプレートを別で作りますが、そこに関連記事として、(メインループで表示されている投稿記事と)同じカスタム投稿の記事を表示させたい場合です。
<?php
global $post;
$args = array(
'numberposts' => 8, //8件表示(デフォルトは5件)
'post_type' => 'products', //カスタム投稿タイプ名
'orderby' => 'rand', //ランダム表示
'post__not_in' => array($post->ID) //表示中の記事を除外
);
?>
<?php $myPosts = get_posts($args); if($myPosts) : ?>
<?php foreach($myPosts as $post) : setup_postdata($post); ?>
<p><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><?php the_title(); ?></a></p>
<?php endforeach; ?>
<?php else : ?>
<p>関連アイテムはまだありません。</p>
<?php endif; wp_reset_postdata(); ?>
この例では、カスタム投稿タイプ名が”products”となっていますので、テンプレート名はsingle-products.phpとなります。
肝心のループ部分には、サムネイル画像と記事タイトルを表示するようにしていますが、この部分はお好みで。
カスタムタクソノミーが同じ記事を表示
上の例では、同じカスタム投稿タイプというだけの縛りでしたが、今度は同じカスタム投稿でかつ同じタクソノミーに属する記事を取得します。
<?php
global $post;
$args = array(
'numberposts' => 8, //8件表示(デフォルトは5件)
'post_type' => 'products', //カスタム投稿タイプ名
'taxonomy' => 'genres', //タクソノミー名 ←ここが追加
'orderby' => 'rand', //ランダム表示
'post__not_in' => array($post->ID) //表示中の記事を除外
);
?>
<?php $myPosts = get_posts($args); if($myPosts) : ?>
<?php foreach($myPosts as $post) : setup_postdata($post); ?>
<p><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><?php the_title(); ?></a></p>
<?php endforeach; ?>
<?php else : ?>
<p>関連アイテムはまだありません。</p>
<?php endif; wp_reset_postdata(); ?>
“genres”というタクソノミーを限定しています。同一のカスタム投稿タイプにタクソノミーが複数ある場合という状況はあまりないかと思いますので、これのみで使うことはないかもしれませんね。
同じタームの記事を表示
今度は同じカスタム投稿でかつ(同じタクソノミーかつ)同じタームに属する記事を取得します。
<?php
global $post;
$term = array_shift(get_the_terms($post->ID, 'genres')); //←ここが追加
$args = array(
'numberposts' => 8, //8件表示(デフォルトは5件)
'post_type' => 'products', //カスタム投稿タイプ名
'taxonomy' => 'genres', //タクソノミー名
'term' => $term->slug, //ターム名 ←ここが追加
'orderby' => 'rand', //ランダム表示
'post__not_in' => array($post->ID) //表示中の記事を除外
);
?>
<?php $myPosts = get_posts($args); if($myPosts) : ?>
<?php foreach($myPosts as $post) : setup_postdata($post); ?>
<p><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><?php the_title(); ?></a></p>
<?php endforeach; ?>
<?php else : ?>
<p>関連アイテムはまだありません。</p>
<?php endif; wp_reset_postdata(); ?>
この場合、タクソノミーの指定も必要になってきます。また、タームの場合はいくつかの選択肢(分類)があると思うので、直接指定せずに、get_the_termsを使って投稿記事が属するタームを取得しています。
Codexには、tax_queryを使って配列にする方法が紹介されていますが、なぜかうまくいかず、この形になりました。なぜだろう…?
さらにカスタムフィールドで絞り込む
同じ投稿タイプ、同じタクソノミー、同じタームときて、さらにカスタムフィールドで絞り込みます。この場合、当然ですが投稿にカスタムフィールドが追加されている必要があります。
<?php
global $post;
$term = array_shift(get_the_terms($post->ID, 'genres'));
$args = array(
'numberposts' => 8, //8件表示(デフォルトは5件)
'post_type' => 'products', //カスタム投稿タイプ名
'taxonomy' => 'genres', //タクソノミー名
'term' => $term->slug, //ターム名
'meta_key' => 'status', //カスタムフィールドの名前 ←ここが追加
'meta_value' => '販売中', //カスタムフィールドの値 ←ここが追加
'orderby' => 'rand', //ランダム表示
'post__not_in' => array($post->ID) //表示中の記事を除外
);
?>
<?php $myPosts = get_posts($args); if($myPosts) : ?>
<?php foreach($myPosts as $post) : setup_postdata($post); ?>
<p><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?><?php the_title(); ?></a></p>
<?php endforeach; ?>
<?php else : ?>
<p>関連アイテムはまだありません。</p>
<?php endif; wp_reset_postdata(); ?>
カスタムフィールドの”status”というメタキーが”販売中”という値を持つ投稿を取得します。これでかなり絞り込んだ関連記事を取得することが出来ます。
上でも書いていますが、カスタム投稿のシングルページに限らず、他のテンプレートでも使用できますので、色々と応用が効きそうです。個人的に、カスタムフィールドは助かりました。