投稿のカテゴリーリストを独自に作成する方法

カテゴリーによる投稿の絞り込み(カテゴリーアーカイブ)のナビゲーション表示には通常 wp_list_categories() を使用しますが、固定ページ上で絞り込みを行いたい場合には、設定されているカテゴリー名とスラッグを一通り取得して独自にナビゲーションを作成する必要があります。
この場合には get_categories() を利用するのですが、たびたびその方法を忘れるので簡単にですがその覚え書きです。

以下は例として通常の「商品案内」の一覧ページ(アーカイブ)とは別に、「在庫一覧」の固定ページを追加で作成した場合のケースです。

stock01

固定ページのテンプレートを作成

まずは「在庫一覧」の固定ページをスラッグ「stock」で作成し、テーマディレクトリの「page.php」ファイルを複製して「page-stock.php」とリネームします。

「page-stock.php」をテキストエディタで開き、本文エリアを以下のように作成します。

<h1>Stock List</h1>

<!-- カテゴリーリスト -->
<ul id="catList">
<?php
$categories=get_categories();
foreach($categories as $category) { 
	echo '<li><a href="?c='.$category->slug.'" title="'.$category->name.'" '.'>'.$category->name.'</a></li>';
}
?>
</ul>

<!-- 在庫一覧 -->
<div id="stockList">
<?php
$terms = 'newitem';
if( htmlspecialchars($_GET['c']) ) $terms = htmlspecialchars($_GET['c']);
$paged = get_query_var('paged');
$temp = $wp_query;
$wp_query = null;
$args = array(
	'post_type' => 'post',
	'paged' => $paged,
	'posts_per_page' => 50,
	'order' => ASC,
	'tax_query' => array(
		array(
			'taxonomy' => 'category',
			'field'    => 'slug',
			'terms'    => $terms,
		),
	),
);
$wp_query = new WP_Query( $args );
?>
<?php  if ( $wp_query->have_posts() ) : ?>
<?php /* loop */ while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
	<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
		<a href="<?php the_permalink(); ?>" class="img"><?php if(has_post_thumbnail()) the_post_thumbnail( 'thumbnail' ); ?></a>
		<h1 class="entryTitle"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
		<p class="postMeta"><span class="category"><?php if( get_the_terms($post,'category') ){ the_terms($post,'category'); } else { echo '未設定'; } ?></span></p>
		<div class="entryContent">
<?php $total=get_field('unpackaged')+get_field('unpackaged2')+get_field('wrapped')+get_field('wrapped2'); ?>
<?php /* total */ if($total): ?>
			<dl>
<?php if(is_user_logged_in()): ?>
				<dt>未引当</dt><dd><?php echo get_field('unpackaged'); ?>(<?php echo get_field('wrapped'); ?>)</dd>
				<dt>引当済</dt><dd><?php echo get_field('unpackaged2'); ?>(<?php echo get_field('wrapped2'); ?>)</dd>
				<dt>在庫数</dt><dd class="total"><?php echo $total; ?></dd>
<?php else: ?>
				<dt>在庫数</dt><dd class="total"><?php echo $total; ?></dd>
<?php endif; ?>
			</dl>
<?php /* total */ else: ?>
			<p class="sold"><strong>soldout</strong></p>
<?php /* total */ endif; ?>
		</div>
	</article>
<?php /* loop */ endwhile; ?>
<ul class="pageNav">
	<li class="prev"><?php previous_posts_link('<< 前のページ'); ?></li>
	<li class="next"><?php next_posts_link('次のページ >>'); ?></li>
</ul>
<?php else : ?>
<article class="notfound">
	<h1>Not Found</h1>
	<p>お探しの商品は見つかりませんでした。</p>
</article>
<?php endif; ?>
<?php $wp_query = $temp; ?>
</div><!-- #stockList -->

続いて各部の詳細について解説します。

カテゴリーリストのナビゲーション部分

通常カテゴリーリストの出力にはwp_list_categories()を使用しますが、リンク先がカテゴリーアカイブのページになりますので、「在庫一覧」の固定ページ上でカテゴリーの絞り込みを行いたい場合は、独自にカテゴリーリストのナビゲーションを作成する必要があります。

独自にカテゴリーリストを作成する場合には、カテゴリーの「名前」と「スラッグ」が必要になりますので、次のようにget_categories()を使用して投稿のカテゴリー名($category->name)とスラッグ($category->slug)を取得します。

<ul id="catList">
<?php
$categories=get_categories();
foreach($categories as $category) { 
	echo '<li><a href="?c='.$category->slug.'" title="'.$category->name.'" '.'>'.$category->name.'</a></li>';
}
?>
</ul>

カスタムタクソノミーの場合

上記は通常の投稿(post)のカテゴリー(category)の場合ですが、カスタムタクソノミーのリストを作成する場合には次のようにget_categories()のパラメータを設定します。

<ul id="catList">
<?php
$args = array(
	'taxonomy' => '【カスタムタクソノミーのスラッグ】',
); 
$categories=get_categories($args);
foreach($categories as $category) { 
	echo '<li><a href="?c='.$category->slug.'" title="'.$category->name.'" '.'>'.$category->name.'</a></li>';
}
?>
</ul>

その他、並び順の設定や記事の無いカテゴリーの除外などパラメータの詳細設定については、公式マニュアルをご参照ください。

在庫一覧の表示部分

固定ページ上に任意のループ(カスタムループ)を表示する場合には、WP_Queryクラスを使用します。

まずWP_Queryで任意のデータを取得するためのパラメータを下記のように設定します。

<?php
$paged = get_query_var('paged'); // 現在のページ送り番号を取得
$temp = $wp_query; // メインクエリ($wp_query)を一旦$tempに格納
$wp_query = null; // $wp_queryを初期化
// WP_Queryで取得したいクエリを設定
$args = array(
	'post_type' => 'post', // 投稿タイプ(デフォルト値:post)
	'paged' => $paged, // 現在のページ番号
	'posts_per_page' => 50, // 表示件数
	'order' => ASC, // ソート(昇順)
 	// タクソノミーの絞り込み条件を設定
	'tax_query' => array(
		array(
			'taxonomy' => 'category', // タクソノミーのスラッグ
			'field'    => 'slug', // タームの絞り込み条件(スラッグ)
			'terms'    => 'newitem', // タームのスラッグ
		),
	),
);
$wp_query = new WP_Query( $args ); // $wp_queryにカスタムクエリを上書き
?>

次にループ部分です。

<?php  if ( $wp_query->have_posts() ) : ?>
<?php /* loop */ while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
【ループ内容】
<?php /* loop */ endwhile; ?>
<ul class="pageNav">
<li class="prev"><?php previous_posts_link('&lt;&lt; 前のページ'); ?></li>
<li class="next"><?php next_posts_link('次のページ &gt;&gt;'); ?></li>
</ul>
<?php else : ?>
【取得する記事が無い場合の記述】
<?php endif; ?>

最後に$tempに一旦格納していたメインクエリを$wp_queryに書き戻しします(リセット)。

<?php $wp_query = $temp; ?>

(参考)ページテンプレート – 公式マニュアル

カテゴリーの絞り込み

カテゴリーリストのリンク先に設定した「?c=カテゴリースラッグ」のクエリ文字列からカテゴリーの絞り込みを次のように行います。

// タームの初期値を設定
$terms = 'newitem';
// クエリ文字列から絞り込むタームを設定
if( htmlspecialchars($_GET['c']) ) $terms = htmlspecialchars($_GET['c']);

以上のように絞り込み条件のタームのスラッグを変数$termsに設定した上で、WP_Queryのパラメータ設定でタームのスラッグを次のように変更します。

$args = array(
	'post_type' => 'post',
	'paged' => $paged,
	'posts_per_page' => 50,
	'order' => ASC,
	'tax_query' => array(
		array(
			'taxonomy' => 'category',
			'field'    => 'slug',
			'terms'    => $terms, // タームのスラッグ
		),
	),
);

カスタム投稿タイプに応用する際の留意点

WP_Queryを使用したカスタムループは、パラメータの設定値を「‘post_type’ => ‘カスタム投稿タイプのスラッグ’」とすることでカスタム投稿タイプにも応用可能ですが、「‘posts_per_page’ => 50」の設定値は一般設定の表示件数が優先されてしまうため、投稿タイプごとに表示件数を変えたい場合はfunctions.phpに以下の記述を追加する必要があります。

function customize_display_articles( $query ) {
	if ( is_admin() || ! $query->is_main_query() )
		return;
	if ( is_post_type_archive( '【カスタム投稿タイプのスラッグ】' ) ) {
		$query->set( 'posts_per_page', 50 );
		return;
	}
}
add_action( 'pre_get_posts', 'customize_display_articles', 1 );

 

PR

DO WP 管理人