wordpress カスタム投稿タイプ

2013年5月21日

概要

独自の投稿タイプ(カスタム投稿タイプ)を追加することにより、「投稿記事」や「固定ページ」とは別にコンテンツを管理でき、カテゴリー形式またはタグ形式で分類することができる。

  • カスタム投稿に固定ページのような親子関係(階層)を持たせるには「hierarchical」を「true」に指定する。
  • 投稿記事と同様に時系列に従ってコンテンツを管理し、親子関係を持たせない場合は「hierarchical」を「false」を指定する。
  • カスタム投稿タイプごとに一覧表示のテンプレートファイルを使うことができる。(archive-post_type.php)
  • 一覧表示(アーカイブ表示)を作成するには has_archive を true にしておく。
  • コンテンツをカスタムタクソノミー(カテゴリー形式またはタグ形式)で分類できる。

カスタム投稿タイプの登録

カスタム投稿タイプを追加するには、register_post_type 関数を使って独自の投稿タイプとその動作を定義する。

register_post_type( $post_type, $args )
パラメータ
$post_type(必須):カスタム投稿タイプ名(スラッグ)
$args(オプション):各種のパラメータを格納した配列(投稿タイプに関する詳細設定) 

functions.php に以下のように記述すると、WordPress の初期化の際に register_post_type 関数が実行される。

function 関数名() {
    register_post_type(カスタム投稿タイプ名, パラメータの配列);
    flush_rewrite_rules();  //パーマリンク設定を再設定
}
add_action('init', 関数名);

flush_rewrite_rules()はパーマリンク設定を再設定するための処理で、この処理を入れないと、カスタム投稿タイプのページに正しくアクセスすることができないことがある。

第1パラメータ(カスタム投稿タイプのスラッグ:必須)

  • 登録したいカスタム投稿タイプの名前を半角英数字で指定 (最大 20 文字)
  • 標準で作成される投稿タイプ「post」「page」「attachment」「revision」は指定できない。
  • この値は生成ページの URL に使用(表示)される。

第2パラメータ(投稿タイプに関する詳細設定:オプション)

label
カスタム投稿タイプの名前を指定。(初期値: $post_type)
この値が、管理画面のメニュー、カスタム投稿一覧ページのタイトルに表示される。日本語使用可能。
echo get_post_type_object(get_post_type())->label; で出力できる。
labels
管理画面に表示されるラベルを指定。
「新規追加」「新規投稿を追加」「投稿の編集」などのデフォルトのラベルを変更する場合は指定。
name:カスタム投稿タイプ名(通常複数形)。この値は「label」の値を上書きする。(管理画面のメニュー、カスタム投稿一覧ページのタイトルに表示される文字列)
singular_name:カスタム投稿タイプ名の単数形(翻訳に関連)
menu_name:メニュー(画面の左)に表示するラベル(デフォルト:name の値)。この値を指定すると name の値を上書きする。 
add_new_item:新規作成ページの左上に表示されるタイトル(デフォルト:「新規投稿を追加」)
add_new:メニュー(画面の左)の「新規」の位置に表示するラベル(デフォルト:「新規追加」)
new_item:一覧ページの右上にある新規作成ボタンのラベル(デフォルト:「新規投稿」)
edit_item:編集ページの左上にあるタイトル(デフォルト:「投稿を編集」)
view_item:編集ページの「○○を表示」ボタンのラベル(デフォルト:「投稿を表示」)
search_items:一覧ページの検索ボタンのラベル(デフォルト:「投稿を検索」)
not_found:カスタム投稿を追加していない状態で、カスタム投稿一覧ページを開いたときに表示されるメッセージ
not_found_in_trash :カスタム投稿をゴミ箱に入れていない状態で、カスタム投稿のゴミ箱ページを開いたときに表示されるメッセージ
description
カスタム投稿タイプの概要を指定。
echo get_post_type_object(get_post_type())->description; で出力できる。
public
ユーザーが管理画面で入力する場合は「true」を指定。(初期値: false )
プログラムで内部的に使われ、ユーザーは直接入力しない場合は「false」を指定。
「true」と指定した場合、以下のようにオプションを指定したことになる。
'show_ui' =>true,
'public_queryable' => true,
'exclude_from_search' =>false,
'show_in_nav_menus' =>true
show_ui
管理画面にこのカスタム投稿タイプのページを表示する場合は「true」を指定。
「false」を指定すると、管理画面上でこのカスタム投稿タイプの操作はできなくなる。
初期値(デフォルト)は、public に指定した値。
hierarchical
カスタム投稿に固定ページのような親子関係(階層)を持たせるには「true」を指定。
投稿記事と同様に時系列に従ってコンテンツを管理し、親子関係を持たせない場合は「false」を指定。(初期値: false )
supports
カスタム投稿タイプの編集/新規作成のページに表示する入力欄を、文字列の配列で指定。
例:「supports=>array('title', 'editor')」とすると、タイトルと本文の入力欄が表示される。
title:タイトル
editor:本文(とその編集機能)
authro:作成者
thumbnail:アイキャッチ画像
excerpt:抜粋
comments:コメント一覧
trackbacks:トラックバック送信
custom-fields:カスタムフィールド
revisions:リビジョン
page-attributes :属性(「hierarchical」を「true」に設定している場合のみ指定)
menu_position
カスタム投稿のメニューを追加する位置を整数で指定。(初期値: null – デフォルトはコメントの下 )
5:「投稿」の下に追加
10:「メディア」の下に追加
以後、5刻みで値を増やすと、追加位置は1つずつ下がる
menu_icon
カスタム投稿のメニューに表示するアイコンのURLを指定。 例:'menu_icon' => get_bloginfo('template_url').'/images/wood_icon_s.jpg'
指定しなければデフォルトの「投稿」のアイコン(ピンの絵柄)
rewrite
「true」の場合、(初期値: true )
「http://ブログのアドレス / カスタム投稿タイプ名 / 個々のカスタム投稿のスラッグ / 」でアクセスできる。
「rewrite => array('slug' => 'スラッグ名')」と指定すると
「http://ブログのアドレス / スラッグ名 / 個々のカスタム投稿のスラッグ / 」でアクセスできる。
また、「rewrite => array('slug' => 'スラッグ名', 'with_front' => false)」と指定すると管理画面のパーマリンク設定を無視する。
「with_front」はパーマリンク設定で「投稿」に対して指定した設定をカスタム投稿でも引き継ぐか引き継がないかを指定する。
has_archive
「true」に指定すると投稿した記事の一覧ページ(投稿タイプのトップページ)を作成することができる
public_queryable
カスタム投稿タイプの機能でページを生成するかどうかを指定。「true」で生成し、「false」で生成しなくなる。未指定(省略時)の場合は、public の設定に従う。
exclude_from_search
検索対象に含めないかどうかを指定。「true」で含めず、「false」で含むようになる。未指定(省略時)の場合は、public の設定に従う。
query_var
生成する個別ページのURLを指定。「true」とした場合、「http://サイトのURL/ ?投稿タイプ名=記事のスラッグ」、「false」とした場合、「http://サイトのURL/ ?post_type=投稿タイプ名&p=記事のID」となる。初期値:true
show_in_nav_menus
capability_type
権限を区別するための投稿タイプ名を指定
capabilities
作成する権限を指定。
このとき、投稿記事の権限と対にして「'投稿記事の権限' => '作成する権限'」という形で記述する。
例:「interior」というカスタム投稿タイプの「記事の投稿と編集」の権限を作成する場合、以下のように指定する。
'capabilities' => array(
 'edit_posts' => 'edit_interiors',
 ・・・),
設定できる権限には以下のようなものがあり、post をカスタム投稿タイプ名で置き換える。
edit_posts 記事の投稿と編集
publish_posts 記事の公開
edit_published_posts 公開した記事の編集
edit_others_posts 他のユーザーの記事の編集
read_private_posts 他のユーザーの非公開記事の閲覧
edit_private_posts 他のユーザーの非公開記事の編集
delete_posts 記事の削除
delete_published_posts 公開した記事の削除
delete_others_posts 他のユーザーの記事の削除
delete_private_posts 他のユーザーの非公開記事の削除

カスタム投稿タイプの追加の例

function new_post_type() {
  //news(ニュース)というカスタム投稿タイプを登録
  register_post_type(
    'news',//投稿タイプ名(識別子)
    array(
      'label' => 'ニュース',  //カスタム投稿タイプの名前(これが管理画面のメニューに表示される)
      'labels' => array(  //管理画面に表示されるラベルを指定
        'add_new_item' => '新規ニュースを追加',
        'edit_item' =>'ニュースの編集',
        'view_item' =>  'ニュースを表示',
        'search_items' => 'ニュースを検索',
        'not_found' => 'ニュースは見つかりませんでした。',
        'not_found_in_trash' => 'ゴミ箱にニュースはありませんでした。',
      ),
      'public' => true,// 管理画面に表示しサイト上にも表示する
      'hierarchicla' => false,//コンテンツを階層構造にするかどうか(投稿記事と同様に時系列に)
      'has_archive' => true,//trueにすると投稿した記事の一覧ページを作成
      'supports' => array(//記事編集画面に表示する項目を配列で指定することができる
        'title',//タイトル
        'editor',//本文(の編集機能)
        'thumbnail',//アイキャッチ画像
        'excerpt'//抜粋
      ),
      'menu_position' => 5//「投稿」の下に追加
    )
  );

  flush_rewrite_rules();
}
add_action('init', 'new_post_type');

カスタム投稿の一覧表示

  • 第2パラメータの’has_archive’ を true に指定する。
  • アーカイブページのテンプレートファイルを使用する。
    優先順位は archive-post_type.php → archive.php → index.php の順。
    この場合、個別(シングル)ページとの間に親子関係があるので、メニューでは「current_page_parent」などのクラスが利用できる。
    (訂正:2014/6/3 長い間すみません)
  • または、固定ページを作成して表示する。
    優先順位は customname.php(カスタムテンプレートファイル) → page-slug.php → page.php の順。
    この場合、個別(シングル)ページとの間に親子関係がないので、メニューでは「current_page_parent」などのクラスが利用できない。
  • 固定ページを使うと、カスタムフィールドやアイキャッチ画像が利用できる。

関連ページ:カスタム投稿タイプの一覧ページの作成

カスタムメニューを使う場合

バージョン3.5の時点では、カスタムメニューでカスタム投稿の一覧ページの選択肢が表示されないので以下を検討する必要がある。

  • 固定ページで一覧ページを作成してそのページを選択する。
  • 「カスタムリンク」でアドレス(URL)とラベルを入力して追加する。
  • プラグイン「Custom Post Type Archive in Nav Menus」をインストールして有効化する。
  • 一覧ページの選択肢は表示されないが、カスタム分類を作成するとそれらは表示されるので、カスタム分類を利用する。taxonomy-taxonomy.php, taxonomy-taxonomy-term.php

カスタム投稿の一覧ページ(archive-post_type.php)がうまく表示されない場合

カスタム投稿の一覧ページのリンクをクリックして「404エラー」になったり、うまく表示されない場合は、管理画面でパーマリンクの設定を空更新(設定を変えずに保存)してみるか、パーマリンクをデフォルトから変更してみる。

カスタム投稿の個別ページのテンプレート階層

個々のカスタム投稿ページを出力する際は、以下のテンプレート階層に沿って、テンプレートが選ばれる

  1. single-カスタム投稿タイプ名.php
  2. single.php
  3. index.php

例えば「news」というカスタム投稿タイプを登録した場合、個々のカスタム投稿タイプのページを出力する際は、「single-news.php」→「single.php」→「index.php」の順にテンプレートが検索される。

投稿タイプ(スラッグ)の取得

get_post_type($the_post)
パラメータ
$the_post:投稿タイプを取得したい投稿の ID または投稿オブジェクト。未指定の場合は現在の投稿が対象。
戻り値
投稿タイプ(文字列)。パラメータ$the_postで指定した投稿オブジェクトまたは投稿IDが無効の場合はfalseを返す。
//カスタム投稿(スラッグ)をクラスとして出力する例
<p class="<?php echo esc_attr(get_post_type()); ?>">

投稿タイプ(オブジェクト)の取得

get_post_type_object($post_type)
パラメータ
$post_type :投稿タイプ(スラッグ)を指定。
戻り値
パラメータ $post_type で指定された投稿タイプ(オブジェクト)。指定した投稿タイプが見つからなかった場合は null。

投稿タイプには、「カスタム投稿タイプ(スラッグ)」,「post」,「page」,「attachment」,「revision」,「nav_menu_item」が指定できる。

取得した投稿タイプ(オブジェクト)のフィールド(メンバー変数)はほぼ register_post_type() で設定する項目と同じ。

カスタム投稿の一覧ページ(archive-post_type.php)や、query_posts のループでそのカスタム投稿のラベルや説明を出力するには、以下のように記述する。

//カスタム投稿のラベル
echo esc_html(get_post_type_object(get_post_type())->label);  
//カスタム投稿の説明
echo esc_html(get_post_type_object(get_post_type())->description);

get_post_type()(パラメータなし)で、現在の投稿の投稿タイプ(スラッグ)を取得して、それをパラメータに渡してフィールドの値を取得する。

投稿タイプ(オブジェクト)または投稿タイプの名前の取得

get_post_types($args, $output, $operator)
パラメータ
$args(配列:オプション):投稿タイプを識別する値(ほぼ register_post_type() で設定する項目と同じ)。デフォルト:なし
$output(文字列:オプション):戻り値のタイプ(オブジェクトまたは名前)を指定。「names」か「objects」のどちらか。デフォルトは「names」
$operator(文字列:オプション):$args を複数指定する場合の条件(「かつ」「または」)「and」か「or」のどちらか。デフォルトは「and」
戻り値(配列)
パラメータ $output で指定された投稿タイプ(オブジェクト)または投稿タイプ名(スラッグ)のリスト(配列)。

カスタム投稿タイプのみの情報を抽出する例

get_post_types のパラメータに「’_builtin’ => false」を指定し標準の投稿タイプ(post, page など)を除外することで、カスタム投稿タイプのみを取得できる。

<?php query_posts(array(
  'post_type' => get_post_types(array('_builtin' => false)),
  'paged' => $paged
)); ?>

カスタム投稿の一覧ページへのリンクを出力する例

<ul>
//カスタム投稿タイプのスラッグを取得して、取得したデータ(配列)を「$mycpts」に代入
<?php $mycpts = get_post_types(array('_builtin' => false)); ?>
//foreach を使って個々の投稿タイプのスラッグを「$mycpt」に取り出す
<?php foreach($mycpts as $mycpt): ?>
  //スラッグからカスタム投稿タイプのアーカイブページへのリンクの値を取得して出力
  <li><a href="<?php echo get_post_type_archive_link($mycpt); ?>">
    //スラッグからカスタム投稿タイプのラベルの値を取得して出力
    <?php echo esc_html(get_post_type_object($mycpt)->label); ?></a>
    //カスタム投稿タイプの説明を出力
    <p><?php echo esc_html(get_post_type_object($mycpt)->description); ?></p>
</li>
<?php endforeach; ?>
</ul>
get_post_type_archive_link( $post_type )
パラメータ
$post_type(文字列:必須):投稿タイプ名(スラッグ)
戻り値(文字列)
指定した投稿タイプのアーカイブページへのリンク(permalink)

最近のカスタム投稿タイプの投稿を表示する例

ウィジェットに用意されたメニューではカスタム投稿タイプの記事のメニューを出力することができない(通常の投稿には「最近の投稿」メニューがある)。以下は「sidebar-blog.php」にメニューの設定を記述する例。

「posts_type」パラメータで、get_post_type() と指定して表示中の記事と同じ投稿タイプの記事を取得する。

<div id="sidebar">
  <ul id="menu">
    <li><h2>最近の投稿</h2>
      <ul>
      <?php
        $args = array(
          'posts_per_page' => 7,
          'post_type' => get_post_type(),  //表示中の記事と同じ投稿タイプの記事を取得
        );
        $my_query = new WP_Query($args);
      ?>
      <?php if($my_query->have_posts()): while($my_query->have_posts()): $my_query->the_post(); ?>
        <li><a href="<?php the_permalink(); ?>">
        <?php the_title(); ?></a></li>
      <?php endwhile; endif; ?>
      <?php wp_reset_postdata(); ?>
      </ul>
    </li>
  </ul>
</div><!-- end of #sidebar -->

カスタム投稿名からカスタム分類のスラッグを取得

カスタム投稿「event」にカスタム分類「eventinfo」を登録してある場合の例。
(カスタム投稿タイプとカスタム分類が1対1の場合)

$taxes = get_object_taxonomies( 'event' );
echo $taxes[0];   //eventinfo が出力される。

反対に、カスタム分類のスラッグからカスタム投稿名を取得するには、

$post_types = get_taxonomy( 'eventinfo' )->object_type;
echo $post_types[0];   // event が出力される。