WordPressのカスタム投稿タイプは「Custom Post Type UI」というプラグインを使えば簡単に作れます。
しかし、それで終わりではなく、サイト上に記事の一覧を表示したり、デザインを変えたりと、カスタマイズしたいケースがあると思います。
この記事では、カスタム投稿タイプやカスタムタクソノミーのカスタマイズ方法を紹介します。
分かりやすいように、具体例として「お知らせ(news)」というカスタム投稿タイプと「お知らせの種類(category_news)」というカスタムタクソノミーを使って説明します。
その部分はご自身の内容に置き換えて考えてください。
事前準備
この記事は、既にカスタム投稿タイプとカスタムタクソノミーがあることを前提に説明しています。
まだ作っていない方や、そもそもカスタム投稿タイプが何か分からない方は、以下の記事を先にお読みください。
URLを変える
カスタム投稿タイプのURLは「Custom Post Type UI」で色々と変えられます。
例えば、以下のように自分で投稿名(%postname%)を入力するURLを作れます。
(例)sample.com/news/oshirase1
しかし、投稿ID(%post_id%)のURLは作れないといった限界もあります。
(例)sample.com/news/245
自分のサイトであれば投稿名で良いでしょうが、例えば依頼を受けて誰かのサイトを作る場合に、投稿名を毎回入力したくない顧客もいるかもしれません。
その場合は、「Custom Post Type Permalinks」というプラグインを使うことで柔軟にURLを変えられます。
プラグインを有効化すると、上のように「設定」⇒「パーマリンク設定」にカスタム投稿タイプのパーマリンク設定が追加されます。投稿IDのURLを設定することもできますし、投稿タイプごとに異なるURLにすることも可能です。
テンプレートファイルを変える
カスタム投稿タイプのテンプレートファイルを変える方法です。
通常の投稿とは別にカスタム投稿タイプ専用のテンプレートファイルを用意することで、表示する内容やデザインなどを変えることができます。
テンプレートファイルを新しく作るわけですが、そのときのファイル名が決まっており、それに従わないと読み込まれません。
その理由は、WordPressには「テンプレート階層」という仕組みがあるからです。簡単に説明すると、テンプレートファイルの優先順位があらかじめ決まっていて、最初に見つかったファイルが読み込まれます。
例えば、投稿の個別ページは以下のテンプレート階層です。
- single-{post_type}.php(例)single-news.php
- single.php
- singular.php
- index.php
上から順番にファイルを探して、最初に見つかったファイルが読み込まれます。最後のindex.phpはテーマに必須のファイルで、上の3種類は任意のファイルです。
そのため、カスタム投稿タイプのテンプレートファイルを作るときは、ファイル名を「single-{post_type}.php」という形式にする必要があります。この形式が最も優先順位が高いので、このファイルを用意しておけばそれが読み込まれます。
テンプレートファイルを作る手順としては、まずはレンタルサーバーに空のファイルを作ります。そして、「single.php」や「singular.php」など優先順位が下のファイルが既にテーマに存在するか調べて、あればその中身をコピーして貼り付けます。
後は修正したい部分だけを変えていけば、白紙の状態からテンプレートファイルを作るよりも作業が簡単になります。
修正する内容は様々ですが、例えば後述するようにサイドバーを変更したり、カスタム投稿タイプ専用の入力項目を表示したりといったことがあります。
同様の手順で個別ページ以外のテンプレートファイルも作成できます。
- archive-{post_type}.php(例)archive-news.php
- archive.php
- index.php
- taxonomy-{taxonomy}-{term}.php(例)taxonomy-category_news-holiday.php
- taxonomy-{taxonomy}.php (例)taxonomy-category_news.php
- taxonomy.php
- archive.php
- index.php
カスタムタクソノミーの一覧ページに関しては、タームごとにテンプレートファイルを分けたいときは一番上の形式で、カスタムタクソノミーごとに分けたいときは二番目の形式で作ってください。全てのカスタムタクソノミーは共通で良いなら三番目のtaxonomy.phpになります。
- single-news.php(個別ページ)
- archive-news.php(一覧ページ)
- taxonomy-category_news.php(カスタムタクソノミーの一覧ページ)
これまでの内容をまとめると、カスタム投稿タイプを作成したときは、必要に応じて上記のようなテンプレートファイルを作ってカスタマイズできます。
サイドバーを変える
カスタム投稿タイプ専用のサイドバーを作る方法です。
例えば、上のようにカスタム投稿タイプの最新記事とカテゴリー(カスタムタクソノミー)をサイドバーに表示するケースを考えます。
やり方はいくつかありますが、ここではカスタム投稿タイプ専用のウィジェットエリアを作成します。
// HTML、クラス、説明などは既存のサイドバーを参考にしながら自由に変えてください
function create_custom_sidebar() {
register_sidebars(1,
array(
'name' => 'サイドバーお知らせ',
'id' => 'sidebar-news',
'description' => 'お知らせのサイドバーのウィジットエリアです。',
'before_widget' => '<aside id="%1$s" class="widget widget-sidebar widget-sidebar-standard %2$s">',
'after_widget' => '</aside>',
'before_title' => '<h3 class="widget-sidebar-title widget-title">',
'after_title' => '</h3>',
));
}
add_action('widgets_init', 'create_custom_sidebar');
上のようにfunctions.phpの中でregister_sidebarsという関数を使うと、「外観」⇒「ウィジェット」に新しくウィジェットエリアが追加されます。
この段階では空のウィジェットエリアです。ここにサイドバーに表示したいウィジェットを設定していきます。
カスタム投稿タイプのウィジェットを設定するためには、例えば「Custom Post Type Widgets」というプラグインを使います。
プラグインを有効化すると、上のようにカスタム投稿タイプ専用のウィジェットを設定できるようになります。種類は、最新の投稿、カテゴリー、検索などのウィジェットがあります。投稿タイプ(ポストタイプ)の選択欄があるので、そこでカスタム投稿タイプを選んでください。
これまでの手順で、カスタム投稿タイプのウィジェットエリアを追加して、そこに最新記事とカテゴリーを表示するウィジェットを設定しました。後は、このウィジェットの情報をサイトに表示させます。
テーマによって最適なやり方は異なりますが、一例を紹介します。
まずは、「sidebar-news.php」のようにカスタム投稿タイプのスラッグを付けたサイドバーのテンプレートファイルを作成します。既存の「sidebar.php」があれば、中身をコピーするのが良いと思います。
ウィジェットの情報を表示するには、以下のようにsidebar-news.phpの中でdynamic_sidebarという関数を使います。
<?php dynamic_sidebar( 'sidebar-news' ); ?>
パラメータには表示したいサイドバーのIDを指定します。具体的には、register_sidebarsに記述した「id」になります。
最後に、sidebar-news.phpをテンプレートファイルから呼び出します。
<?php get_sidebar( 'news' ); ?>
get_sidebarはサイドバーのテンプレートを呼び出す関数です。パラメータを渡すと、sidebar-XXX.phpの「XXX」がパラメータに一致するファイルを呼び出します。
この処理をカスタム投稿タイプのサイドバーを表示したいテンプレート全てに書きます。例えば、個別ページ(single-news.php)、一覧ページ(archive-news.php)、カスタムタクソノミーの一覧ページ(taxonomy-category_news.php)といったファイルに書きます。
今までの手順をまとめると、上のような流れになります。
一覧ページを変える
カスタム投稿タイプを作るときに「アーカイブあり」でTrueを選択すれば、自動でカスタム投稿タイプの一覧ページが作成されます。
標準では上のように投稿日付が新しい記事から順番に表示されます。これを色々とカスタマイズしてみます。
記事の並び順を変える
まずは、投稿日付ではなく、更新日付が新しい記事から表示するように修正します。
function custom_main_query($query) {
if(is_admin() || !$query->is_main_query())
return;
if(is_post_type_archive('news')) {
$query->set('orderby', 'modified');
$query->set('order', 'DESC');
return;
}
}
add_action( 'pre_get_posts', 'custom_main_query' );
一覧ページのデータは、自分でプログラムを書かなくてもWordPressが自動で取得してくれます。これを「メインクエリ」と呼び、メインクエリの取得方法を修正するときは、functions.phpの中のpre_get_postsというアクションに記述します。
上の例では、「orderby」と「order」という2つの条件を追加しており、orderbyには「modified(更新日付)」、orderには「DESC(新しいものから)」を設定しています。
is_post_type_archiveはカスタム投稿タイプの一覧ページを表示するか判定する関数です。頻繁に使うので覚えておきましょう。
- is_singular('news'):カスタム投稿タイプの個別ページか判定
- is_post_type_archive(‘news’):カスタム投稿タイプの一覧ページか判定
- is_tax('category_news'):カスタムタクソノミーの一覧ページか判定
記事の数を変える
次は、一つのページに表示する記事の数を修正します。標準では「設定」⇒「表示設定」⇒「1ページに表示する最大投稿数」によって決まりますが、ここではカスタム投稿タイプだけ一つのページに2件の記事を表示するように変えてみます。
$query->set('posts_per_page', 2);
表示する記事の数は、メインクエリのposts_per_pageで修正できます。先ほどと同じようにpre_get_postsの中に書いてください。また、数字の部分は書き換えてください。
記事の絞り込みを行う
最後は、記事に割り当てられているカスタムタクソノミーのタームで絞り込みをします。
$tax_query = array(array(
'taxonomy' => 'category_news',
'field' => 'slug',
'terms' => 'holiday'
));
$query->set('tax_query', $tax_query);
メインクエリのtax_queryを使うとカスタムタクソノミーで絞り込みができます。この例では、「holiday」というタームが割り当てられている記事のみを取得しています。
記事一覧を表示する
自動で作成される一覧ページ以外に、トップページなど任意の場所にカスタム投稿タイプの記事一覧を表示する方法です。
例として、上のように記事の日付とリンクを一覧で表示します。
<?php
$args = array(
'post_type' => 'news',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC'
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ): $the_query->the_post();
?>
<article>
<div><?php the_time('Y年n月j日'); ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></div>
</article>
<?php
endwhile;
wp_reset_postdata();
else :
?>
<p>お知らせはありません。</p>
<?php endif; ?>
※カスタム投稿タイプのスラッグなどは自由に書き換えてください。HTMLやCSSは省略しています。
投稿日付が新しい順に最大で5つの記事を表示するプログラムです。WP_Queryのオブジェクトにpost_typeのパラメータを渡してカスタム投稿タイプの情報を取得しています。
記事一覧を表示したい場所に上記のプログラムを書いてください。トップページに表示する場合には、front-page.phpやindex.phpなどのテンプレートファイルになります。
次は、カスタムタクソノミーで絞り込みを行います。例えば、お知らせの個別ページにおいて、そのお知らせに割り当てられているタームと同じものを割り当てられているお知らせの一覧を関連記事として表示させます。
<?php
$news_terms = get_the_terms(get_the_ID(), 'category_news');
foreach ( $news_terms as $term ) {
$news_term_slugs[] = $term->slug;
}
$args = array(
'post_type' => 'news',
'posts_per_page' => 5,
'post__not_in' => array(get_the_ID()),
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array(
array(
'taxonomy' => 'category_news',
'field' => 'slug',
'terms' => $news_term_slugs,
'operator' => 'IN'
)
)
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ): $the_query->the_post();
?>
<article>
<div><?php the_time('Y年n月j日'); ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></div>
</article>
<?php
endwhile;
wp_reset_postdata();
else :
?>
<p>お知らせはありません。</p>
<?php endif; ?>
※new WP_Query以下のプログラムは先ほどと全く同じです。
※カスタム投稿タイプのスラッグなどは自由に書き換えてください。HTMLやCSSは省略しています。
まずは、get_the_termsという関数で現在表示しているお知らせに割り当てられているタームを取得します。そして、tax_queryのパラメータでそのタームが含まれるものを抽出しています。また、関連記事なのでpost__not_inのパラメータで現在表示しているお知らせは除外して取得しています。
入力項目を増やす
カスタム投稿タイプの記事の編集画面で入力する項目を増やす方法です。
例えば、上のように「お知らせ」の記事の編集画面だけに、お知らせを目立たせる「強調表示」の選択欄を追加します。
「強調表示させる」が選択されたときだけ、赤字で「重要!」という文字を表示します。
入力項目を新たに追加するには「カスタムフィールド」というWordPressの機能を使います。
「Advanced Custom Fields」という便利なプラグインを使ってカスタムフィールドを作っていきます。詳細は以下の記事をお読みください。
作成するカスタムフィールドは以下の通りです。
- フィールドラベル:強調表示
- フィールド名:do_emphasis
- フィールドタイプ:ラジオボタン
- 説明:重要なお知らせで目立たせたいときは「強調表示させる」を選択してください
- 必須か?:はい
- 選択肢:
0 : 強調表示させない
1 : 強調表示させる - デフォルト値:0
- レイアウト:水平
- 返り値:Value
重要な点は、以下のように「位置のルール」を設定するときにカスタム投稿タイプを選ぶところです。
以上の手順でカスタムフィールドを作れば、カスタム投稿タイプの編集画面だけに「強調表示」の選択欄が追加されているはずです。
最後に、「強調表示させる」が選択されたときに「重要!」という文字を表示するプログラムを書きます。
<?php
$args = array(
'post_type' => 'news',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC'
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ): $the_query->the_post();
$emphasis_label = '';
$do_emphasis = get_post_meta(get_the_ID(), 'do_emphasis', true);
if($do_emphasis == 1) $emphasis_label = ' <span style="color: red;">重要!</span>';
?>
<article>
<div><?php the_time('Y年n月j日'); ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php echo $emphasis_label; ?></div>
</article>
<?php
endwhile;
wp_reset_postdata();
else :
?>
<p>お知らせはありません。</p>
<?php endif; ?>
※カスタム投稿タイプのスラッグなどは自由に書き換えてください。HTMLやCSSは省略しています。
get_post_metaという関数でカスタムフィールドの値を取得しています。そして、それが「1(強調表示させる)」のときだけ強調表示のラベルを設定しています。
割り当てられたタームを表示する
カスタム投稿タイプの記事に割り当てられたタームを表示する方法です。
上の例では、「プレゼント」と「休み」というタームが記事に割り当てられており、それをサイトに表示しています。リンクをクリックすると、カスタムタクソノミーの一覧ページが表示されます。
<?php
$taxonomy_name = 'category_news';
$taxonomy_object = get_taxonomy($taxonomy_name);
if($taxonomy_object) {
echo $taxonomy_object->label.':';
$terms = get_the_terms(get_the_ID(), $taxonomy_name);
if(!$terms || is_wp_error($terms)) {
echo 'なし';
}else {
foreach($terms as $term) {
echo '<a href="'.get_term_link($term->slug, $taxonomy_name).'">'.$term->name.'</a> ';
}
}
}
?>
※$taxonomy_nameなどは自由に書き換えてください。
get_taxonomyという関数で「お知らせの種類」というカスタムタクソノミーの名称を取得し、get_the_termsという関数で割り当てられたタームの名称やスラッグを取得しています。
プログラムを記述する場所は、例えばsingle-news.phpなどカスタム投稿タイプの個別ページのテンプレートです。
様々なテンプレートで同じプログラムを使う場合には、functions.phpに関数化して呼び出すのがおすすめです。
検索対象を変える
カスタム投稿タイプ専用の検索ボックスを作る方法です。
WordPressでは「外観」⇒「ウィジェット」などに検索ボックスが用意されていますが、標準では投稿タイプに関係なく全ての記事が検索の対象になります。
お知らせの記事のサイドバーに設置してある検索ボックスを使ったのに、お知らせ以外の記事が表示されたら違和感があります。
そこで、カスタム投稿タイプの記事だけを検索の対象にするようにカスタマイズします。
やり方は簡単で、「Custom Post Type Widgets」というプラグインを有効化すると、上のように「検索(カスタム投稿タイプ)」というウィジェットが新たに追加されます。
タイトルを入力して、検索の対象とするカスタム投稿タイプ(ポストタイプ)を選択すれば、設定は完了です。
実際に使ってみれば分かりますが、選択したカスタム投稿タイプの記事しか検索結果に表示されていないはずです。
検索結果ページを変える
検索結果ページの表示内容やデザインをカスタム投稿タイプに応じて変える方法です。
WordPressで検索を行うと、「search.php」または「index.php」というテンプレートファイルが読み込まれて、検索結果ページが表示されます。
つまり、「検索対象を変える」の手順で特定のカスタム投稿タイプに絞って検索したとしても、検索結果ページは通常の投稿タイプと同じになるわけです。
検索結果ページが共通だと以下のような問題が発生します。
例えば、上のように通常の投稿ではサイドバーに「最新の投稿」を表示していて、お知らせのカスタム投稿タイプでは「最新のお知らせ」を表示しているケースを考えます。
このとき、お知らせのサイドバーにある検索ボックスで検索を行うと、検索結果ページは通常の投稿と共通なので「最新の投稿」が表示されてしまいます。
対処方法としては、search.phpの中にif文を書いて投稿タイプに応じて読み込むサイドバーを変える方法もありますが、ここでは検索結果ページのテンプレートファイル自体をカスタム投稿タイプによって変える方法を紹介します。
テンプレートファイルを分けることで、サイドバーの問題だけではなく、検索結果として表示させる項目をカスタマイズすることも容易になります。
検索結果ページのテンプレート階層は以下の通りです。
- search.php
- index.php
ただし、これだと全ての投稿タイプで「search.php」または「index.php」が読み込まれてしまうため、カスタム投稿タイプに応じて検索結果ページを変えられません。そこで、以下のプログラムを使って読み込むテンプレートファイルを変更します。
function custom_template($template) {
if(is_search()) {
$post_type = get_query_var('post_type');
if(!empty($post_type)) {
$templates[] = "search-{$post_type}.php";
}
$templates[] = 'search.php';
$templates[] = 'index.php';
$template = get_query_template('search', $templates);
}
return $template;
}
add_filter('template_include', 'custom_template');
get_query_varは、カスタム投稿タイプのクエリ変数を取得する関数です。
「Custom Post Type Widgets」のプラグインを使わずに標準の検索ボックスを使うと、カスタム投稿タイプのクエリ変数には「any」が設定されます。プラグインを使えば、クエリ変数には「news」などカスタム投稿タイプのスラッグが入ります。
- search-{post_type}.php(例)search-news.php
- search.php
- index.php
先ほどのプログラムでは、上記の優先順位で子テーマ、親テーマの直下を順番に探して、最初に見つかったテンプレートファイルが読み込まれます。
そこで、カスタム投稿タイプ用の検索結果ページを表示させる「search-news.php」といったテンプレートファイルと、標準の投稿用の「search.php」の2種類を作れば、それぞれ検索結果ページの内容を変えられます。
例えば、プラグインを使わないと一つ目は「search-any.php」になりますが、そのようなファイルは存在しないのでsearch.phpが読み込まれます。また、万が一存在しないカスタム投稿タイプのスラッグが設定されたときも、同じくsearch.phpが読み込まれます。
最後のindex.phpに関してはプログラム中になくても良いのですが、search.phpがなかったときに画面が真っ白になることを防ぐために追加しています。search.phpを必ず作成して削除しないのであれば、index.phpのプログラムは削除しても構いません。
作成したカスタム投稿タイプの検索結果ページからは、カスタム投稿タイプ専用のサイドバーを呼び出しましょう。
管理画面の記事一覧を変える
WordPressの管理画面の記事一覧に表示する項目を変える方法です。
具体例として、上のように管理画面のお知らせの一覧ページにお知らせの種類を表示して、日付を非表示にします。
function set_custom_edit_news_columns($columns) {
$columns['category_news'] = 'お知らせの種類';
unset($columns['date']);
return $columns;
}
add_filter( 'manage_news_posts_columns', 'set_custom_edit_news_columns' );
function custom_news_column($column_name, $post_id) {
if($column_name == 'category_news') {
$terms = get_the_term_list($post_id, $column_name, '', ',', '');
echo $terms;
}
}
add_action( 'manage_news_posts_custom_column' , 'custom_news_column', 10, 2 );
manage_〇〇_posts_columnsというフィルターで管理画面の項目を編集します。〇〇の部分には、カスタム投稿タイプのスラッグが入ります。
表示する項目を追加する場合は$columnsという変数に代入します。既存の項目を非表示にする場合はunsetという関数を使います。
次に、manage_〇〇_posts_custom_columnというアクションで表示内容を設定します。
上の例では、新しく追加した「category_news」という項目のときに、get_the_term_listという関数でタームのリンクを表示しています。
このように、表示したい内容をechoで出力すれば、投稿のデータやカスタムフィールドなど、様々な情報を管理画面に表示できます。
カスタムタクソノミーのタームを管理画面に表示する場合は、Custom Post Type UIの「管理画面でカラムを表示」でTrueを選択すれば、プログラミングをしなくても表示されます。
まとめ
今回の記事では、カスタム投稿タイプの様々なカスタマイズ方法を紹介してきました。
最初は難しいと感じる内容もあると思いますが、理解できればこれまでよりも高機能なサイトを作れるようになるはずです。
なお、手順やプログラムなどは利用しているテーマによっても変わることがあります。記事の内容について正確性は保証できませんので、ご自身の責任で参考にしてください。
コメント(現在、質問は受け付けていません)