register_post_type()は公開範囲とURLを決めてからpublic、has_archive、rewriteを設定する
公開日: 執筆:佐藤
WordPressでカスタム投稿タイプを作るときは、register_post_type()の引数を先に埋めるのではなく、その内容をどこへ公開するかを決めます。管理画面で編集するか、個別ページを公開するか、サイト内検索へ含めるか、一覧ページを持つか、URLのslugを何にするかを分けてください。
publicは複数の初期値に影響しますが、公開範囲を一項目だけで表す万能の設定ではありません。個別ページと一覧URLを公開する投稿タイプでは、public、has_archive、rewriteの関係を明記します。社内記録のように管理画面だけで使うなら、公開に関わる項目をfalseにして意図をコードへ残します。
publicは管理画面と公開画面の初期値を決める
WordPress 3.8のregister_post_type()では、publicの初期値はfalseです。publicly_queryable、show_ui、show_in_nav_menusを省略すると、publicの値を引き継ぎます。exclude_from_searchは、publicと反対の値を使います。
それぞれの役割は同じではありません。
| 引数 | 決めること | 省略時の関係 |
|---|---|---|
public |
公開利用を意図した投稿タイプか | 初期値はfalse |
publicly_queryable |
公開画面で投稿タイプへのqueryを受けるか | publicを引き継ぐ |
show_ui |
管理画面の編集UIを作るか | publicを引き継ぐ |
show_in_nav_menus |
ナビゲーションメニューの選択肢へ出すか | publicを引き継ぐ |
exclude_from_search |
サイト内検索の結果から外すか | publicの反対になる |
public => trueだけでも公開用の初期値はそろいます。ただし、管理画面には必要だが公開画面には出さない内容や、公開するがサイト内検索には含めない内容では、個別の引数を省略せず指定します。
has_archiveとrewriteは一覧URLと個別URLを分けて考える
has_archiveは投稿タイプの一覧を持つかを決め、初期値はfalseです。trueにすると、rewriteが有効な場合に一覧用のrewrite ruleが作られます。文字列を指定すれば、その文字列を一覧のslugとして使えます。
rewriteは個別ページを含むURLの書き換えを扱います。初期値はtrueで、投稿タイプのキーをslugに使います。配列を渡すと、slug、with_front、feed、ページ分割などを指定できます。falseにすれば、その投稿タイプ用のrewriteを作りません。
一覧ページが必要だからhas_archiveを有効にすることと、公開URLの形をrewriteで決めることは別です。先に次の二つを書き出します。
- 個別ページをどのURLで公開するか
- 投稿タイプの一覧を公開するか。公開するなら、どのURLにするか
slugは公開後のリンク、サイトマップ、外部からの参照に使われます。コードを書き始める前に決め、運用中の都合だけで変更しない方が安全です。
公開用の投稿タイプは意図した初期値をコードへ残す
次は説明用の仮例です。「事例」という投稿タイプを個別ページと一覧ページの両方で公開し、URLの基準をcasesにします。サトラボの実績や実装を示すコードではありません。
add_action( 'init', 'example_register_case_post_type' );
function example_register_case_post_type() {
register_post_type(
'case',
array(
'labels' => array(
'name' => '事例',
'singular_name' => '事例',
),
'public' => true,
'has_archive' => true,
'rewrite' => array(
'slug' => 'cases',
'with_front' => false,
),
'supports' => array( 'title', 'editor' ),
)
);
}
register_post_type()はinit actionから呼び出します。投稿タイプのキーは、この例ではcaseです。WordPress 3.8のcoreではキーをsanitize_key()へ通し、20文字を超える場合はWP_Errorを返します。
この例でpublicから引き継ぐ項目を把握したうえで、個別に変えたい範囲があれば明記します。たとえば、公開用でもサイト内検索へ含めない理由があるなら、exclude_from_search => trueを別に指定します。
管理画面だけで使うなら公開用の引数を明示して止める
管理画面で入力するだけで、個別ページも一覧ページも公開しない投稿タイプなら、公開に関わる値を一つずつ止めます。
register_post_type(
'office_note',
array(
'labels' => array(
'name' => '社内記録',
'singular_name' => '社内記録',
),
'public' => false,
'show_ui' => true,
'publicly_queryable' => false,
'exclude_from_search' => true,
'has_archive' => false,
'rewrite' => false,
'supports' => array( 'title', 'editor' ),
)
);
これも説明用の仮例です。public => falseとshow_ui => trueを組み合わせることで、管理画面は使い、公開queryは受けない意図を示せます。機密情報を守る仕組みを、この設定だけへ任せてはいけません。権限、出力処理、backup、管理画面へのアクセスも別に確認します。
rewrite ruleは登録時ではなく必要な時だけ更新する
WordPress Codexのregister_post_type()に関する説明では、plugin内で投稿タイプを登録する場合、activationとdeactivationのhookでflush_rewrite_rules()を呼ぶ方法を案内しています。実行しない場合は、「設定」からパーマリンク設定を更新してrewrite ruleを作り直します。
register_post_type()を呼ぶたびに、rewrite ruleの更新作業まで繰り返す必要はありません。投稿タイプを登録する処理と、追加または削除したときにrewrite ruleを更新する処理を分けます。
変更後は、管理画面の一覧だけを見て完了にしないでください。公開する投稿タイプなら、個別URL、一覧URL、ページ分割、サイト内検索を確認します。公開しない投稿タイプなら、個別queryと一覧URLが公開されていないことを確認します。
外部の制作者へ実装を任せる場合も、投稿タイプのキー、公開範囲、個別URL、一覧URLはサイト運営側で記録します。実装者が変わっても、既存URLと保存済みデータの意味を判断できる状態にしてください。
最初の一手は、投稿タイプ名を決めることではありません。管理画面、個別ページ、サイト内検索、一覧ページ、ナビゲーションメニューの五つについて、使うか使わないかを一行ずつ決めます。その表からpublicと関連引数を選べば、初期値へ意図せず任せる箇所を減らせます。
関連記事

