• register_post_type()は公開範囲とURLを決めてからpublic、has_archive、rewriteを設定する

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と関連引数を選べば、初期値へ意図せず任せる箇所を減らせます。

戻る