カスタム投稿タイプ生成コード

WordPress

ワードプレスでのカスタム投稿タイプやタクソノミー編集メニューを出すためのコード。

ちなみにプラグインだとCustom Post Type UIが使いやすくメジャーなツールかと思います。

カスタム投稿タイプ

以下functions.phpに書き込むカスタム投稿タイプ作成コード

//カスタム投稿タイプ作成コード
function register_custom_post_type(){
    $labels = [
        'name' => '〇〇', //管理画面に表示する名前
        'all_items' => '〇〇一覧',//管理画面の一覧の表記
        'add_new' => '新しい〇〇を追加', //新規追加ボタンの名前(デフォルトは新規追加)
        'add_new_item' => '新しい〇〇を追加', //新規追加ページのタイトル(旧エディター)
        'edit_item' => '〇〇を編集', //編集ページのタイトル(旧エディター)
        'search_items' => '〇〇を検索', //一覧ページの検索ボタンのラベル
        'not_found' =>  '投稿された〇〇はありません', //一覧ページに投稿が見つからなかったときに表示
        'not_found_in_trash' => 'ゴミ箱に〇〇はありません。', //ゴミ箱に何も入っていないときに表示
    ];
    $args = [
        "label" => "〇〇",// 管理画面の表示(labelsのnameが優先)
        "labels" => $labels,//管理画面、編集画面の表記
        "description" => "〇〇とは",//説明文。独自テーマだと表示するためには他の設定が必要だしいらない
        "public" => true,//管理画面上に表示するか
        "show_in_rest" => true,//RESTAPI、新エディターを使う(falseだと旧エディター)
        "rest_base" => "",//RESTAPI URLのベースとなる名前(なければカスタム投稿タイプ名)
        "rest_controller_class" => "WP_REST_Posts_Controller",//RESTAPI 処理コントローラー名(省略OK)
        "has_archive" => true,//アーカイブページを作るかどうか
        "show_in_nav_menus" => true,//ナビゲーションメニューで選択可能にする(なければpublicの値)
        "delete_with_user" => false,//userが消えると記事も消えるようにするかどうか
        "exclude_from_search" => false,//サイト内検索で表示しないようにする
        "map_meta_cap" => true,//詳細なオリジナル権限を作りたいとき
        "capability_type" => 'post', //デフォルトの投稿タイプと同じ権限、オリジナルで作るときはオリジナルのプレフィックスを作る
        "hierarchical" => false,//親記事を設定できる
        "rewrite" => ["slug" => "works", "with_front" => true],//パーマリンクをリライトするか、初期値はtrue,[]でリライト内容を細かく設定できる。
        "query_var" => true,//URLのクエリを変えることができる
        "menu_position" => 5,//管理画面メニューに表示される順番、5は投稿の下
        "supports" => ["title", "editor", "thumbnail", "revisions", "author", "excerpt", "custom-fields", "comments",],// サポートする機能(タイトル、エディター、アイキャッチ画像)
    ];
    register_post_type("works", $args);//カスタム投稿タイプのスラッグ、オプション
}
add_action("init", "register_custom_post_type");

オプションがものすごい量あって大変でした…。まだ全てではないし、ちゃんとわかってないものもあると思います。自分用のメモくらいの意味しかありません。

function register_custom_post_type(){

    //様々なオプション

    register_post_type("works", $args);
}
add_action("init", "register_custom_post_type");

まずregister_custom_post_typeという関数を作って、add_actionでinitフックのタイミングで実行。
実質は中のregister_post_type(“works”, &args);でカスタム投稿タイプを作成しています。

 $labels = [
        'name' => '〇〇', //管理画面に表示する名前
        'all_items' => '〇〇一覧',//管理画面の一覧の表記
        'add_new' => '新しい〇〇を追加', //新規追加ボタンの名前(デフォルトは新規追加)
        'add_new_item' => '新しい〇〇を追加', //新規追加ページのタイトル(旧エディター)
        'edit_item' => '〇〇を編集', //編集ページのタイトル(旧エディター)
        'search_items' => '〇〇を検索', //一覧ページの検索ボタンのラベル
        'not_found' =>  '投稿された〇〇はありません', //一覧ページに投稿が見つからなかったときに表示
        'not_found_in_trash' => 'ゴミ箱に〇〇はありません。', //ゴミ箱に何も入っていないときに表示
    ];

labelsの中に入ってるのは、管理画面の表記設定です。以下のように反映されます

edit_itemなどは、旧エディターにしたときに表示されました。

 $args = [
        "label" => "〇〇",// 管理画面の表示(labelsのnameが優先)
        "labels" => $labels,//管理画面、編集画面の表記
        "description" => "〇〇とは",//説明文。独自テーマだと表示するためには他の設定が必要だしいらない
        "public" => true,//管理画面上に表示するか
        "show_in_rest" => true,//RESTAPI、新エディターを使う(falseだと旧エディター)
        "rest_base" => "",//RESTAPI URLのベースとなる名前(なければカスタム投稿タイプ名)
        "rest_controller_class" => "WP_REST_Posts_Controller",//RESTAPI 処理コントローラー名(省略OK)
        "has_archive" => true,//アーカイブページを作るかどうか
        "show_in_nav_menus" => true,//ナビゲーションメニューで選択可能にする(なければpublicの値)
        "delete_with_user" => false,//userが消えると記事も消えるようにするかどうか
        "exclude_from_search" => false,//サイト内検索で表示しないようにする
        "map_meta_cap" => true,//詳細なオリジナル権限を作りたいとき
        "capability_type" => 'post', //デフォルトの投稿タイプと同じ権限、オリジナルで作るときはオリジナルのプレフィックスを作る
        "hierarchical" => false,//親記事を設定できる
        "rewrite" => ["slug" => "works", "with_front" => true],//パーマリンクをリライトするか、初期値はtrue,[]でリライト内容を細かく設定できる。
        "query_var" => true,//URLのクエリを変えることができる
        "menu_position" => 5,//管理画面メニューに表示される順番、5は投稿の下
        "supports" => ["title", "editor", "thumbnail", "revisions", "author", "excerpt", "custom-fields", "comments",],// サポートする機能(タイトル、エディター、アイキャッチ画像)
    ];

オプションについて

label 管理画面の表記ですが、$labels内のnameの方が優先されるし、多分$labelsで細かく決める必要のない人がここで名前を決めればいいんじゃないでしょうか。

labels 細かく管理画面の表記をカスタマイズしたい人用

description 独自テーマでやってるとどこにも表示されない。説明を表示させる関数が別途必要なんだと思います。いらないと思う

public これをtrueにしないと表示されない。デフォルトではfalseなので必要

show_in_rest これをtrueにしないと新エディターのブロックエディターにならないんですが、これをtrueにすると同時にRESTAPIも使えるようになるらしいです。なぜそこが連動しているのか個人的に謎です。

map_meta_cap 詳細なオリジナル権限を使いたいときにtrueにします。投稿と同じ権限で運用したいならfalseでいいと思う

capability_type デフォルトはpostになっていて、元からある投稿の権限と同じものになっています。違うものを作りたい場合はここに”works”とかいれて、別途細かい権限を設定します。

rewrite デフォルトはtrue。パーマリンクのスラッグを変えたりできます。

supports 管理画面や編集画面でメニューが出てくるようになります。

カスタムタクソノミー

カスタム投稿タイプ用のカスタムタクソノミーも作成したいときのコード

//カテゴリーを作成
function register_custom_post_category(){
    $labels = [
        "singular_name" => "ジャンル",
    ];
    $args = [
        "label" => "ジャンル",
        "labels" => $labels,
        "publicly_queryable" => true,//個別ページにアクセスできるか
        "hierarchical" => true,
     "show_in_rest" => true,//これがないとタクソノミー選択項目がでてこない
        "show_in_menu" => true,
        "query_var" => true,
        "rewrite" => ["slug" => "genre", "with_front" => true,],
        "show_admin_column" => true,//タクソノミーを一覧に表示
        "show_in_quick_edit" => true,//タクソノミーをクイック編集できるようにする
    ];
    register_taxonomy("genre", ["works"], $args);//登録するタクソノミーのスラッグ、タクソノミーを関連づける投稿タイプ(またはスラッグ)、オプション配列
}
add_action("init", "register_custom_post_category");

ほぼカスタム投稿タイプと同じような感じ。

show_admin_column タクソノミーをカスタム投稿タイプ一覧で表示

show_in_quick_edit クイック編集でタクソノミーを選択できるようになります。

ベストプラクティス

何をするかによっていろいろ変わってくるとは思うんですが、とりあえず一般的なベストプラクティスを考えてみました。何も補償はないです。

function register_custom_post_type(){
    $labels = [
        'name' => '〇〇',
        'all_items' => '〇〇一覧',
        'add_new' => '新しい〇〇を追加',
    ];
    $args = [
        "label" => "〇〇",
        "labels" => $labels,
        "public" => true,
        "show_in_rest" => true,
        "has_archive" => true,
        "show_in_nav_menus" => true,
        "delete_with_user" => false,
        "exclude_from_search" => false,
        "hierarchical" => false,
        "rewrite" => ["slug" => "works", "with_front" => false],
        "menu_position" => 5,
        "supports" => ["title", "editor", "thumbnail", "author", "custom-fields", "comments",],
    ];
    register_post_type("works", $args);
}
add_action("init", "register_custom_post_type");

function register_custom_post_category(){
    $labels = [
        "singular_name" => "ジャンル",
    ];
    $args = [
        "label" => "ジャンル",
        "labels" => $labels,
        "publicly_queryable" => true,
        "hierarchical" => true,
        "show_in_menu" => true,
        "rewrite" => ["slug" => "genre", "with_front" => false,],
        "show_admin_column" => true,
        "show_in_quick_edit" => true,
    ];
    register_taxonomy("genre", ["works"], $args);
}
add_action("init", "register_custom_post_category");

URLを整えるために

〇カスタム投稿タイプはパーマリンク設定が効かない
/%category%/%post_id%/ としてても出ません。idが出ることはなく、投稿タイトルが出ます。日本語にしてたらURLに日本語が出ます。以下のコードでURLをpost_idが出るようにします。(投稿ID(post_id)は全投稿タイプで通し番号なので被りません)

// カスタム投稿タイプを保存するときに、デフォルトURLは投稿タイトルが
// 出てしまうのでそれをIDに変えます
add_action('save_post', 'custom_price_slug_to_post_id');
function custom_price_slug_to_post_id($post_id) {
    $post = get_post($post_id);

    if ($post->post_type === 'price') {
        // すでに post_name が ID なら更新しない(無限ループ防止)
        if ($post->post_name != $post_id) {
            remove_action('save_post', 'custom_price_slug_to_post_id'); // 一時的に外す

            wp_update_post(array(
                'ID' => $post_id,
                'post_name' => $post_id
            ));

            add_action('save_post', 'custom_price_slug_to_post_id'); // 再登録
        }
    }
}

〇カスタム投稿タイプはデフォルト状態ではワードプレスがそのページをうまく判別できない。

"rewrite" => ["slug" => "works", "with_front" => false],

URLにカスタム投稿タイプを表示させるようにリライトを必ずいれること。これでどの投稿タイプかワードプレスが判断できるようになる