「お知らせとは別に、施工事例を一覧で出したい」「サービスごとに決まった項目を入力させたい」。この段階でカスタム投稿タイプの話が出てきます。作ること自体は難しくありません。register_post_type() を1回呼べば、管理画面に新しいメニューが増えます。厄介なのはその手前で、投稿タイプの名前と入力項目の名前は、公開して運用が始まったあとで変えると、テンプレートも既存データも巻き込んで壊れます。実際に名前を変えることになった案件と、運用に乗ってから困った案件を並べながら、決める順番を書きます。
何を分けたいのかで、作るものが決まる
カスタム投稿タイプは「投稿とは別の入れ物」です。入れ物を分ける理由は、だいたい4つに整理できます。一覧の見せ方が違う、入力させたい項目が違う、編集する人や更新の頻度が違う、検索やアーカイブの対象を分けたい。このどれにも当てはまらないなら、既存の投稿にカテゴリを1つ足すだけで足ります。判断の分かれ目は固定ページ・投稿・カスタム投稿タイプのどれで作るかの側に書いています。
これまで作ったもので言えば、スマートフォンの修理店で「症状の一覧」を投稿とは別に持たせたケース、店舗紹介サイトで「店舗」を投稿タイプにして評価項目を並べたケース、社内向けのマニュアルサイトで「マニュアル」を投稿タイプ、「マニュアル分類」をタクソノミーにしたケースがあります。いずれも、同じ形の情報が今後も増え続けることが分かっていました。増え続けるかどうかは、判断材料としてかなり強いほうです。
後から変えられないものを、先に決める
先に決めるべきは、投稿タイプ名、URLに出るスラッグ、そして入力項目のフィールド名です。この3つは、公開後に変えると影響が広い場所に散らばります。
症状の一覧を作った案件では、着手後に投稿タイプ名を symptoms から trouble へ変更することになりました。文字を置き換えるだけに見えますが、実際にはテンプレートのファイル名(single-symptoms.php や archive-symptoms.php)、投稿タイプ判定で分けていたCSS、サイト内のリンク、そして登録済みの投稿が持っている投稿タイプの値まで、まとめて直すことになります。この変更のために追加の作業と費用が発生しました。名前は着手前に確定させる、というのはこの手戻りから来ています。
フィールド名はさらに厄介で、運用が始まってから変えると、保存済みのデータが表示されなくなります。入力欄に付いている見出し(ラベル)は自由に変えて構いませんが、フィールド名は触らない。カスタムフィールドを納品するときには、この一文を必ず添えるようにしています。運用側が管理画面をいじって最初に壊すのが、ほぼここだからです。
技術的な制約も先に確認しておきます。投稿タイプ名は20文字以内で、英小文字・数字・アンダースコア・ハイフンだけ。post page attachment revision nav_menu_item といったWordPressが使っている名前は予約済みで使えません。URLに出したい文字列と投稿タイプ名は分けられるので、内部名は短く、URLは読みやすく、という決め方ができます。
登録の実装で押さえる引数
<code>register_post_type( 'trouble', array( 'label' => '症状', 'public' => true, 'has_archive' => true, 'menu_position'=> 5, 'supports' => array( 'title', 'editor', 'thumbnail', 'custom-fields', 'page-attributes' ), 'show_in_rest' => true, 'rewrite' => array( 'slug' => 'trouble', 'with_front' => false ), ) );</code>
呼び出しは init フックです。supports は何を出すかの指定ですが、実務では「何を出さないか」のほうが効きます。本文エディタを使わせずカスタムフィールドだけで入力させたいなら editor を外す。並び順を手で決めたいなら page-attributes を入れる。アイキャッチを使うなら thumbnail を入れる。ここを絞っておくと、運用者が迷う場所が減ります。
show_in_rest を true にしないと、その投稿タイプはブロックエディタになりません。旧来のエディタで運用したい場合は逆に外します。has_archive を有効にした直後は、そのままだと一覧URLが404になります。設定のパーマリンクの画面を一度開いて保存すれば、リライトルールが更新されて通るようになります。忘れたまま「作ったのに表示されない」と悩む定番の場所です。
置き場所はテーマではなくプラグインを勧めます。投稿タイプは見た目ではなくコンテンツの器なので、テーマを乗り換えたときに消えると、記事だけが残って表示できない状態になります。店舗を扱った案件では、一覧を表示するウィジェットがテーマ名を冠した作りになっていて、テーマを替えるとその機能ごと失われる形でした。表示部分はテーマ、データの定義はプラグイン、という分け方をしておくと後で困りません。
分類が必要ならタクソノミーを register_taxonomy() で登録します。階層を持たせるかどうかは hierarchical の指定で、階層を作る場合の設計はカスタムタクソノミーで階層を作るときの設計にまとめました。テンプレートは archive-{投稿タイプ}.php、single-{投稿タイプ}.php、taxonomy-{タクソノミー}.php の順に探されます。
作った直後にハマるところ
いちばん見落とされるのが、サイト内検索です。新しい投稿タイプを追加すると、既定では既存の記事と混ざって検索結果に出ます。修理店の案件でも、症状の一覧と店舗ブログが同じ検索結果に並びました。検索対象を投稿タイプで絞る処理は、投稿タイプを追加したときの標準の確認項目にしています。一覧ページと検索結果で、出るものが揃っているか。作った直後に一度確認するだけで済みます。
専用のCSSを読み込ませるときは、投稿タイプの判定で読み込みを限定します。全ページで読ませると、無関係なページのレイアウトに影響が出ます。同じ理由で、テンプレートに直接書いた色やアイコンも後で問題になります。店舗の案件では、表示に使うアイコンをテーマファイルの中に直接書いていたため、変更のたびに開発側の作業が必要になっていました。指摘を受けて管理画面から変えられる構造に作り直しています。運用者が変えたくなる場所は、最初から管理画面に出しておくのが結局は安上がりです。
項目の数も、固定で作ると必ず「増やしたい」「消したい」が来ます。店舗の案件では、アイコン・ラベル・評価・コメントの4つを1行として、行そのものを増減でき、並べ替えもできる構造に変更しました。個別の要望に個別に応えるのではなく、構造のほうを可変にする。この変更を入れてから、同じ種類の依頼は来なくなりました。入力項目をどう設計するかは入力項目を追加するときのフィールド設計の側で詳しく扱っています。
逆に、自由度を上げすぎた例もあります。「画像を自由に入れたい」という要望に対して、サブタイトル単位でHTMLを自由に書ける欄を用意したところ、サイズも位置も制限がなくなりました。入力次第でレイアウトは崩れます。この場合は「崩れたときの復旧はどちらの責任か」を納品前に決めておかないと、後から食い違います。
名前と項目、変えられるものと変えられないもの
| 決めるもの | 後から変えられるか | 変えたときに影響する場所 |
|---|---|---|
| 投稿タイプ名(内部名) | 実質できない | テンプレート名、登録済みデータの紐付け、絞り込み条件 |
| URLのスラッグ | 変えられるがリダイレクトが必要 | 既存URL、外部からのリンク、検索結果 |
| 管理画面の表示名 | いつでも変えられる | なし |
| フィールド名(キー) | 実質できない | 保存済みデータの表示が消える |
| フィールドのラベル | いつでも変えられる | なし |
| タクソノミー名 | 実質できない | 一覧テンプレート、分類URL |
| 並び順・表示位置 | 変えられる | なし |
渡したあとに効いてくること
マニュアルサイトの案件では、投稿一覧の画面に分類の列を追加しました。件数が増えたときに、管理画面で目的の記事を探せるかどうかは運用のしやすさに直結します。作る側は一覧をあまり見ませんが、使う側は毎日そこを開きます。
同じ案件で、専用のヘッダーを header-manual.php として分離しておいたことが後で効きました。配色とロゴの変更依頼が来たとき、1ファイルの修正で済んでいます。分けずに条件分岐で書いていたら、共通ヘッダーを触ることになり、他のページの確認まで必要でした。
運用ルールも一緒に渡します。編集してよいのは文言と画像の置き換えまで、レイアウトを壊す編集からの復旧は別作業になる、公開前にプレビューで確認する。この3点を納品時に書面で渡しておくと、その後の問い合わせが軽いものに収まります。分類の設計では、スマートフォンのメニューに並ぶ大項目は4つ程度が限界で、細かい分類は子の階層へ落とす、といった制約も先に確認しておくほうが安全です。実際に作ってから「メニューに入りきらない」と分かると、分類の付け直しになります。
構築の相談を受けるときは、この記事に書いた順番、つまり分ける理由、名前、項目、運用ルールの順で確認しています。開発の相談でも、コードを書き始める前のこの部分に時間を使ったほうが、結果として短く終わります。
よくある質問
管理画面から投稿タイプを作れるプラグインを使ってもいいですか
使えます。ただし、そのプラグインを止めると投稿タイプの定義も消え、記事が管理画面から見えなくなります。データが消えるわけではありませんが、表示できない状態になります。長く使うサイトなら、最終的にはコードで登録して、プラグインへの依存を減らすほうが安全です。プラグインで作ったものをコードに移す作業自体は難しくありません。
運用を始めてから投稿タイプ名を変えたくなりました
投稿タイプ名はデータベースの各投稿に保存されているので、変更するなら既存データの一括更新が必要です。加えてテンプレート名、絞り込み条件、URLも直します。件数が少ないうちなら現実的ですが、記事が数百件あり外部からリンクされている状態なら、旧URLからのリダイレクトも設計に入れることになります。名前を先に決める理由がここにあります。
投稿タイプは何個くらいまで作っていいですか
個数の上限はありませんが、増やすほど管理画面のメニューが縦に伸び、運用側が迷います。判断としては、入力する項目が同じなら分けず、タクソノミーで分類するほうが扱いやすくなります。項目そのものが違うときにだけ投稿タイプを分ける、という基準で決めています。
投稿タイプと入力項目の設計は、手を動かす前に決めた分だけ後が楽になり、運用が始まってから直すほど高くつきます。今ある情報をどう分けるべきか迷っている段階でも、構成の案をお出しできます。
