---
title: コンテンツ設計
description: カスタム投稿タイプ、タクソノミー、カスタムフィールドの設計と登録方法。ACF / SCF とコードでの登録の使い分け
---

お知らせ、施工事例、スタッフ紹介など、サイトで扱うコンテンツの種類と項目を、実装の前に決めます。
公開後に投稿タイプやフィールドの構造を変えると、入力済みのデータを移し替える作業が発生するためです。

## カスタム投稿タイプ

標準の「投稿」と項目や一覧ページが異なるコンテンツは、カスタム投稿タイプとして登録します。
登録の方法は、[カスタムフィールド](#カスタムフィールド)と揃えます。
ACF / SCF でフィールドを作る案件では、投稿タイプとタクソノミーも ACF / SCF で登録し、Local JSON で Git 管理します。
コードで登録する場合は、`register_post_type()` を `functions/post-types.php` にまとめます。

```php theme/functions/post-types.php
add_action("init", function () {
  register_post_type("works", [
    "labels" => [
      "name" => "施工事例",
      "singular_name" => "施工事例",
    ],
    "public" => true,
    "has_archive" => true,
    "show_in_rest" => true,
    "menu_icon" => "dashicons-portfolio",
    "supports" => ["title", "editor", "thumbnail", "excerpt"],
    "rewrite" => ["slug" => "works"],
  ]);
});
```

どちらの方法でも、次の点を守ります。

- **投稿タイプ名**：20 文字以内の小文字の英数字とアンダースコアで、URL のスラッグとしても自然な単語にする。`post`・`page` など WordPress が予約している名前は使わない
- **`show_in_rest`**（ACF / SCF では「REST API で表示」）：`true` にする。`false` のままだと、ブロックエディターではなく旧来のエディターが表示される
- **パーマリンク**：投稿タイプを登録・変更したら、管理画面の「設定 > パーマリンク」を開いて保存し、リライトルールを更新する。更新しないと、新しい URL が 404 になる

分類が必要な場合は、専用のタクソノミーを登録します。
標準のカテゴリーやタグを複数の投稿タイプで共有すると、管理画面の一覧に別の投稿タイプ用の項目が混ざるためです。

## カスタムフィールド

カスタムフィールドは、ACF / SCF（プラグイン）とコードでの登録のどちらで実装してもかまいません。
案件の要件と担当者の判断で選び、1 つの案件の中では方法を揃えてください。
同じ案件で混在すると、フィールドの定義を探す場所が 2 か所に分かれるためです。

### ACF / SCF を使う場合

プラグインを使う場合は、[ACF](https://wordpress.org/plugins/advanced-custom-fields/)（Advanced Custom Fields）か [SCF](https://wordpress.org/plugins/secure-custom-fields/)（Secure Custom Fields）のどちらかを使います。

| | ACF | SCF |
| --- | --- | --- |
| 開発元 | WP Engine | WordPress.org |
| 無料版で使えるフィールド | リピーター・フレキシブルコンテンツなどは有料版（ACF PRO）のみ | リピーター・フレキシブルコンテンツなども無料で使える |

SCF は ACF の無料版から分岐したプラグインで、データの保存形式とフィールド定義の JSON に互換性があります。
リピーターなど有料版の機能が必要で、ACF PRO のライセンスを用意しない案件では SCF を選びます。

フィールドの定義は [Local JSON](https://www.advancedcustomfields.com/resources/local-json/) でテーマの `acf-json/` に保存し、Git で管理します。
管理画面で作った定義はデータベースにだけ保存され、環境間で揃えられず、変更の履歴も残らないためです。
フィールドの追加・変更は開発環境で行い、本番環境の管理画面では編集しません。

### コードで登録する場合

プラグインを使わない場合は、`register_post_meta()` でフィールドを登録します。
ブロックエディターのサイドバーやカスタムブロックから値を編集するには、`show_in_rest` を `true` にします。

```php theme/functions/post-types.php
register_post_meta("works", "theme_works_area", [
  "type" => "string",
  "single" => true,
  "show_in_rest" => true,
  "sanitize_callback" => "sanitize_text_field",
  "auth_callback" => function () {
    return current_user_can("edit_posts");
  },
]);
```

メタキーには `theme_` などの接頭辞を付けます。
接頭辞がないと、プラグインが使うメタキーと重複して値が上書きされる場合があります。

## 出力時の注意

カスタムフィールドの値は、ACF / SCF の `get_field()` で取得した場合も `get_post_meta()` で取得した場合も、出力時にエスケープします（[セキュリティ](/wordpress/security#出力時のエスケープ)）。
値が空の場合に見出しだけが残らないよう、出力前に値の有無を確認してください。

```php
<?php $area = get_post_meta(get_the_ID(), "theme_works_area", true); ?>
<?php if ($area): ?>
  <dl class="works-meta">
    <dt>施工エリア</dt>
    <dd><?php echo esc_html($area); ?></dd>
  </dl>
<?php endif; ?>
```
