
目次 & インサイト
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
WordPressのACFとは?カスタムフィールドから柔軟コンテンツまで実践的に解説
はじめに:WordPressを「更新しやすいWebサイト」にするために
WordPressでWebサイトを制作するとき、見た目のデザインと同じくらい重要なのが、公開後の更新のしやすさです。
例えば、企業サイトを制作した場合、クライアントは次のような情報を定期的に更新するかもしれません。
- トップページのキャッチコピー
- サービスの紹介文や画像
- 制作実績や導入事例
- スタッフのプロフィール
- よくある質問
- 営業時間やお問い合わせ先
これらを更新するたびにHTMLやPHPを編集する必要があれば、Webサイトの管理は制作会社に依存してしまいます。
一方、管理画面に必要な入力項目が用意されていれば、クライアント自身が内容を変更できます。
こうした仕組みを構築するときに役立つのが、**ACF(Advanced Custom Fields)**です。
第8回では、カスタム投稿タイプとタクソノミーを使ったコンテンツ設計について解説しました。
今回は、さらに一歩進んで、ACFを使った情報管理とオリジナルテーマへの実装方法を紹介します。
1. ACF(Advanced Custom Fields)とは?
ACFは、WordPressの投稿・固定ページ・カスタム投稿タイプなどに、独自の入力フィールドを追加できるプラグインです。
WordPressには標準でカスタムフィールドの仕組みが用意されていますが、ACFを利用すると、入力項目をより直感的に管理できます。
例えば、スタッフ紹介ページを作成する場合を考えてみましょう。
通常の投稿タイトルや本文に加えて、次のような項目を用意できます。
| 項目 | フィールドタイプ |
|---|---|
| 氏名 | テキスト |
| 役職 | テキスト |
| プロフィール | テキストエリア |
| 顔写真 | 画像 |
| 入社年 | 数値 |
| SNSリンク | URL |
こうした入力欄を管理画面に用意しておけば、更新担当者は項目に沿って情報を登録するだけで済みます。
ACFの役割は、単に入力欄を増やすことではありません。
Webサイトで管理する情報を整理し、入力する内容と表示デザインを分離できることが大きなメリットです。
2. ACFの無料版とPRO版の違い
ACFには無料版と有料のACF PROがあります。
基本的なテキスト・画像・選択項目などのフィールドは、無料版でも利用できます。
一方、複雑なコンテンツ構成に対応する機能は、主にPRO版で提供されています。
| 機能 | 無料版 | PRO版 |
|---|---|---|
| テキスト・テキストエリア | ○ | ○ |
| 画像・URL・数値 | ○ | ○ |
| セレクト・チェックボックス | ○ | ○ |
| 真偽・カラーピッカー | ○ | ○ |
| リピーターフィールド | — | ○ |
| 柔軟コンテンツ | — | ○ |
| ギャラリーフィールド | — | ○ |
| オプションページ機能 | — | ○ |
| クローンフィールド | — | ○ |
※機能やライセンスの提供条件はバージョン・プランによって変更される場合があります。導入時には公式情報を確認してください。
小規模なサイトであれば無料版でも十分に活用できます。
ただし、複数のコンテンツを繰り返し登録したり、ページ構成を管理画面から変更したりする場合は、ACF PROが非常に便利です。
3. ACFの基本:フィールドグループを作成する
ACFでは、複数の入力項目を「フィールドグループ」として管理します。
例えば、固定ページのトップページに次のようなフィールドグループを作成します。
フィールドグループ名:トップページ設定
| フィールドラベル | フィールド名 | タイプ |
|---|---|---|
| メインタイトル | hero_title | テキスト |
| 説明文 | hero_description | テキストエリア |
| メイン画像 | hero_image | 画像 |
| ボタンリンク | hero_link | リンク |
フィールドグループには表示ルールを設定できるため、例えば「固定ページがトップページの場合」にだけ入力欄を表示することもできます。
これによって、ページごとに必要な編集項目だけを用意できます。
フィールド名の付け方も重要
ACFでは、フィールドラベルとフィールド名を区別します。
フィールドラベルは管理画面に表示する名称で、フィールド名はPHPから値を取得するときに使用する識別子です。
例えば次のように設定します。
- フィールドラベル:メインタイトル
- フィールド名:
hero_title
フィールド名は、英小文字とアンダースコアを組み合わせた、わかりやすい命名にしておくと管理しやすくなります。
特に複数人で開発する場合や、後から機能を追加する場合は、命名ルールを統一しておくことが大切です。
4. get_field()でACFの値を取得する
ACFで登録した値をPHPテンプレートから取得するときは、get_field() を使用します。
例えば、メインタイトルを表示する場合は次のように記述します。
<?php
$hero_title = get_field( 'hero_title' );
?>
<?php if ( $hero_title ) : ?>
<h1>
<?php echo esc_html( $hero_title ); ?>
</h1>
<?php endif; ?>
get_field() で値を取得し、入力がある場合にだけHTMLを表示しています。
このようにしておけば、フィールドが未入力の場合に空の見出しが出力されることを防げます。
テキストエリアの改行を反映する
テキストエリアに入力した改行をHTMLに反映する場合は、nl2br() を利用できます。
<?php
$hero_description = get_field( 'hero_description' );
?>
<?php if ( $hero_description ) : ?>
<p>
<?php
echo nl2br(
esc_html( $hero_description )
);
?>
</p>
<?php endif; ?>
ここでは、esc_html() で文字列を安全に処理してから、nl2br() で改行を <br> に変換しています。
なお、ACFのWYSIWYGエディターなど、HTMLを含むフィールドを表示する場合は、フィールドの用途に応じて適切な出力方法を選びます。
5. 画像フィールドを使う
ACFの画像フィールドでは、画像を次の形式で取得できます。
- 画像配列
- 画像URL
- 画像ID
オリジナルテーマ制作では、画像のURLや代替テキストを扱いやすい「画像配列」が便利です。
画像フィールドの返り値を「画像配列」に設定した場合、次のように記述できます。
<?php
$hero_image = get_field( 'hero_image' );
?>
<?php if ( ! empty( $hero_image['url'] ) ) : ?>
<img
src="<?php echo esc_url( $hero_image['url'] ); ?>"
alt="<?php echo esc_attr( $hero_image['alt'] ?? '' ); ?>"
width="<?php echo esc_attr( $hero_image['width'] ); ?>"
height="<?php echo esc_attr( $hero_image['height'] ); ?>"
>
<?php endif; ?>
画像配列には、URL・代替テキスト・画像サイズなどの情報が含まれます。
画像の代替テキストはアクセシビリティにも関わるため、適切に設定しておきたい項目です。
また、WordPressの画像サイズやレスポンシブ画像の仕組みを活用したい場合は、画像IDを取得して wp_get_attachment_image() を利用する方法もおすすめです。
6. リピーターフィールドで繰り返し項目を管理する
ここからはACF PROの機能を紹介します。
リピーターフィールドは、同じ構成の入力項目を繰り返し追加できる機能です。
例えば、サービス紹介セクションを考えてみましょう。
各サービスに次の項目を用意します。
- サービス名
- 説明文
- 画像
サービスの数はサイトによって異なるため、あらかじめ3件や4件に固定するより、管理画面から追加できる方が便利です。
このような場合にリピーターフィールドが役立ちます。
リピーターの設定例
親フィールド名:service_list
子フィールド:
| フィールド名 | タイプ |
|---|---|
service_title | テキスト |
service_description | テキストエリア |
service_image | 画像 |
PHPでリピーターを出力する
<?php if ( have_rows( 'service_list' ) ) : ?>
<div class="service-list">
<?php while ( have_rows( 'service_list' ) ) : the_row(); ?>
<?php
$title = get_sub_field( 'service_title' );
$description = get_sub_field( 'service_description' );
$image = get_sub_field( 'service_image' );
?>
<article class="service-item">
<?php if ( ! empty( $image['ID'] ) ) : ?>
<?php
echo wp_get_attachment_image(
(int) $image['ID'],
'large'
);
?>
<?php endif; ?>
<?php if ( $title ) : ?>
<h3><?php echo esc_html( $title ); ?></h3>
<?php endif; ?>
<?php if ( $description ) : ?>
<p>
<?php echo nl2br( esc_html( $description ) ); ?>
</p>
<?php endif; ?>
</article>
<?php endwhile; ?>
</div>
<?php endif; ?>
※画像フィールドの返り値は「画像配列」を想定しています。
ここで使用している関数は、次の3つです。
have_rows():繰り返しデータが存在するか確認するthe_row():次の行へ進むget_sub_field():現在の行にある子フィールドの値を取得する
リピーターを使うと、カード型のコンテンツやFAQ、スタッフ一覧などを効率よく管理できます。
7. 柔軟コンテンツ(Flexible Content)とは?
ACF PROの中でも、オリジナルテーマ制作で特に便利なのが柔軟コンテンツです。
柔軟コンテンツは、あらかじめ定義した複数のレイアウトを、管理画面から自由に追加・並び替えできる機能です。
例えば、次のようなレイアウトを用意します。
- HERO:メインビジュアル
- ABOUT:会社紹介
- SERVICE:サービス紹介
- GALLERY:画像ギャラリー
- FAQ:よくある質問
- CTA:お問い合わせ誘導
クライアントは、これらのレイアウトを必要に応じて組み合わせられます。
一般的なページビルダーのようにすべてのデザインを自由に変更する仕組みではありません。
制作側が設計したデザインを維持しながら、コンテンツの構成や順番を変更できることが特徴です。
これは、ブランドイメージを維持したい企業サイトや、デザインの統一性が重要なWebサイトに適しています。
8. 柔軟コンテンツをPHPで出力する
柔軟コンテンツのフィールド名を page_sections とします。
その中に、次のレイアウトを用意したとします。
| レイアウト名 | 内容 |
|---|---|
hero | メインビジュアル |
about | 会社紹介 |
service | サービス紹介 |
faq | よくある質問 |
PHPでは、get_row_layout() を使用して現在のレイアウトを判定できます。
<?php if ( have_rows( 'page_sections' ) ) : ?>
<?php while ( have_rows( 'page_sections' ) ) : the_row(); ?>
<?php if ( get_row_layout() === 'hero' ) : ?>
<?php
$title = get_sub_field( 'hero_title' );
?>
<section class="hero-section">
<?php if ( $title ) : ?>
<h1><?php echo esc_html( $title ); ?></h1>
<?php endif; ?>
</section>
<?php elseif ( get_row_layout() === 'about' ) : ?>
<?php
$title = get_sub_field( 'about_title' );
?>
<section class="about-section">
<?php if ( $title ) : ?>
<h2><?php echo esc_html( $title ); ?></h2>
<?php endif; ?>
</section>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
この方法でも実装できますが、レイアウトが増えてくるとPHPファイルが長くなってしまいます。
そのため、実務ではテンプレートパーツとして分割する方法がおすすめです。
9. 柔軟コンテンツとテンプレートパーツを組み合わせる
例えば、テーマ内に次のようなディレクトリを用意します。
my-theme/
├── functions.php
├── page.php
│
└── template-parts/
└── sections/
├── hero.php
├── about.php
├── service.php
├── gallery.php
├── faq.php
└── cta.php
page.php などのテンプレートでは、柔軟コンテンツのレイアウトに応じてテンプレートパーツを読み込みます。
<?php
if ( have_rows( 'page_sections' ) ) :
$allowed_layouts = array(
'hero',
'about',
'service',
'gallery',
'faq',
'cta',
);
while ( have_rows( 'page_sections' ) ) :
the_row();
$layout = get_row_layout();
if ( in_array( $layout, $allowed_layouts, true ) ) {
get_template_part(
'template-parts/sections/' . $layout
);
}
endwhile;
endif;
?>
各レイアウトの表示処理は、それぞれのPHPファイルに分離します。
例えば template-parts/sections/about.php には、ABOUTセクションのHTMLとACFの取得処理だけを記述します。
この構成には、次のようなメリットがあります。
- ページ全体のコードが整理される
- レイアウトごとに修正しやすい
- 同じレイアウトを複数ページで使用できる
- デザイン変更時の影響範囲を把握しやすい
- チーム開発でも役割分担しやすい
特に、セクション数の多い企業サイトでは、このようなテンプレート分割が保守性の向上につながります。
10. オプションページでサイト共通の情報を管理する
ACF PROでは、オプションページを利用してサイト全体で共通する情報を管理できます。
例えば、次のような情報です。
- 会社名
- 電話番号
- 住所
- SNSリンク
- ヘッダーのロゴ
- フッターの説明文
- 共通CTAの文章
これらを各ページに個別登録すると、情報を変更するたびに複数のページを修正する必要があります。
オプションページにまとめておけば、1か所の編集で共通情報を更新できます。
オプションページを登録する
function aquacube_register_options_page() {
if ( function_exists( 'acf_add_options_page' ) ) {
acf_add_options_page(
array(
'page_title' => 'サイト共通設定',
'menu_title' => 'サイト共通設定',
'menu_slug' => 'theme-general-settings',
'capability' => 'manage_options',
'redirect' => false,
)
);
}
}
add_action(
'acf/init',
'aquacube_register_options_page'
);
この例では、ACFの初期化後にオプションページを登録しています。
ACFが有効でない場合にも配慮し、function_exists() で関数の存在を確認しています。
オプションページの値を取得する
例えば、電話番号を company_phone というフィールド名で登録した場合は、次のように取得できます。
<?php
$company_phone = get_field(
'company_phone',
'option'
);
?>
<?php if ( $company_phone ) : ?>
<p>
TEL:
<?php echo esc_html( $company_phone ); ?>
</p>
<?php endif; ?>
通常の get_field() との違いは、第2引数に 'option' を指定している点です。
これにより、投稿や固定ページではなく、オプションページに保存した情報を取得できます。
※実際に電話リンクを生成する場合は、表示用の電話番号と tel: URL用の値を適切に処理してください。
11. 真偽フィールドで表示やアニメーションを切り替える
ACFの真偽フィールド(True / False)は、表示・非表示などを切り替える際に便利です。
例えば、特定の画像に回転アニメーションを適用するかどうかを、管理画面で選択できるようにします。
フィールド名を enable_animation とした場合、次のように記述できます。
<?php
$enable_animation = get_field( 'enable_animation' );
$image_class = $enable_animation
? 'image-animation'
: '';
?>
<div class="image-wrapper <?php echo esc_attr( $image_class ); ?>">
<!-- 画像 -->
</div>
CSSでは、次のように設定できます。
.image-animation {
animation: rotate-image 20s linear infinite;
}
@keyframes rotate-image {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.image-animation {
animation: none;
}
}
これにより、クライアントはPHPやCSSを編集せずにアニメーションの有無を切り替えられます。
同様の方法で、次のような設定にも応用できます。
- セクションの表示・非表示
- 背景画像の有効・無効
- ボタンの表示切り替え
- 装飾要素の表示切り替え
ただし、すべての要素に設定項目を用意すると管理画面が複雑になります。
実際に更新する可能性がある項目を見極めることが重要です。
12. カラーピッカーでデザインの一部を調整する
ACFにはカラーピッカーフィールドも用意されています。
例えば、見出しの色を管理画面から変更できるようにする場合です。
フィールド名を title_color とすると、次のように記述できます。
<?php
$title = get_field( 'section_title' );
$title_color = sanitize_hex_color(
(string) get_field( 'title_color' )
);
$title_color = $title_color ?: '#10302A';
?>
<?php if ( $title ) : ?>
<h2 style="color: <?php echo esc_attr( $title_color ); ?>;">
<?php echo esc_html( $title ); ?>
</h2>
<?php endif; ?>
ここでは、取得した色を sanitize_hex_color() で検証しています。
色が未設定の場合には、デフォルトカラーを使用するようにしています。
このような仕組みは便利ですが、自由に色を変更できるようにすると、ブランドカラーとの統一性が崩れる可能性もあります。
そのため、実務では編集できる色の範囲や、デフォルト値をあらかじめ設計しておくと安心です。
13. ACFとブロックエディターはどう使い分ける?
WordPressには、標準でブロックエディターが搭載されています。
そのため、すべてのページをACFで構築する必要はありません。
それぞれの特徴を整理すると、次のようになります。
| 比較項目 | ACF中心の構成 | ブロックエディター中心の構成 |
|---|---|---|
| 入力方法 | 専用フィールドに入力 | ブロックを配置・編集 |
| デザインの自由度 | 制作側で制御しやすい | 編集者が調整しやすい |
| 更新のしやすさ | 定型情報に強い | 自由な文章構成に強い |
| 複雑なデータ管理 | 得意 | 構成による |
| レイアウト変更 | 柔軟コンテンツなどで対応 | ブロックの追加・並び替え |
| 適した用途 | 企業情報・制作実績・定型ページ | ブログ・記事・自由なコンテンツ |
例えば、ブログ記事の本文はブロックエディターで編集し、制作実績の詳細情報はACFで管理する、といった併用も可能です。
また、ACF PROではACF Blocksを使い、ACFフィールドを持つ独自ブロックを開発する方法もあります。
重要なのは、どちらか一方に統一することではなく、コンテンツの性質に応じて適切な方法を選ぶことです。
14. 実務で考えたい「編集しやすさ」と「デザインの維持」
クライアント向けのWebサイトでは、編集の自由度が高ければ高いほど良いとは限りません。
例えば、見出しのサイズや余白、背景色、カラム数などをすべて自由に変更できる場合、意図しない操作でデザインが崩れてしまう可能性があります。
反対に、編集できる項目が少なすぎると、少し文章を追加するだけでも制作会社への依頼が必要になります。
そこで大切なのが、編集する情報と、制作側が管理するデザインを適切に分けることです。
私がオリジナルテーマを設計する際にも、次のような考え方が重要だと感じています。
クライアントが編集するもの
- 見出しや説明文
- 写真や画像
- リンク先
- サービスや事例の追加
- FAQなどの定型コンテンツ
- 必要に応じたセクションの並び替え
制作側で管理するもの
- 基本レイアウト
- レスポンシブ対応
- アニメーションの実装
- アクセシビリティ
- セキュリティ
- パフォーマンス
- サイト全体のデザインルール
もちろん、サイトの目的によって最適な編集範囲は変わります。
重要なのは、公開後に誰が何を更新するのかを、制作前に明確にしておくことです。
ACFは、その設計を具体的な管理画面として実現するための有力な選択肢です。
15. ACFを長く安全に運用するための注意点
最後に、ACFを利用する際に意識しておきたいポイントを紹介します。
フィールド名の変更に注意する
PHPテンプレートでは、フィールド名を指定してデータを取得します。
そのため、公開後にフィールド名を変更すると、既存のコードで値を取得できなくなる場合があります。
フィールド名は、できるだけ初期設計の段階で決めておきましょう。
未入力の場合を想定する
ACFの値が常に登録されているとは限りません。
未入力の場合や、画像が削除された場合も想定し、条件分岐を使って安全に出力することが重要です。
出力時のエスケープを忘れない
ACFの値をHTMLに表示する際は、用途に応じて適切にエスケープします。
代表的な関数は次のとおりです。
| 関数 | 主な用途 |
|---|---|
esc_html() | 通常のテキスト |
esc_attr() | HTML属性 |
esc_url() | URL |
wp_kses_post() | 許可されたHTMLを含む文章 |
入力フィールドを用意するだけでなく、出力側の安全性も考慮する必要があります。
更新前にはバックアップと動作確認を行う
ACFはWordPress本体やテーマと連携して動作します。
そのため、ACFやWordPress本体、PHPのバージョンを更新する際は、互換性を確認し、必要に応じてバックアップや検証環境でのテストを行いましょう。
特にリピーターや柔軟コンテンツを多用したサイトでは、更新後に管理画面とフロントエンドの両方を確認することが大切です。
フィールドグループの管理方法を統一する
複数人でテーマを開発する場合、ACFの設定を管理画面だけで行うと、開発環境と本番環境で設定に差が生じることがあります。
ACFにはLocal JSONなどの仕組みがあり、フィールドグループの設定をファイルとして管理できます。
継続的な保守やチーム開発では、こうした機能を活用することで、設定変更を追跡しやすくなります。
まとめ:ACFはWordPressを「運用しやすいCMS」にするための重要なツール
今回は、ACFの基本から実務で役立つ機能までを紹介しました。
ACFを利用すると、WordPressの標準機能だけでは管理しにくい情報を、わかりやすい入力項目として整理できます。
特に、リピーターや柔軟コンテンツ、オプションページを組み合わせることで、複雑な企業サイトでも管理しやすい構成を作れます。
ただし、ACFの機能を多く使うこと自体が目的ではありません。
大切なのは、Webサイトの目的や更新担当者に合わせて、必要な情報を適切な形で管理できるようにすることです。
見た目の美しさと更新のしやすさ、そして保守性。
この3つを両立させるために、ACFはオリジナルテーマ制作において非常に有効なツールだといえるでしょう。
次回予告|第10回
WordPressのブロックテーマとは?クラシックテーマとの違いと、これからのテーマ制作
WordPressのテーマ制作は、従来のPHPテンプレートを中心としたクラシックテーマから、ブロックエディターやサイトエディターを活用するブロックテーマへと選択肢が広がっています。
次回は、theme.json、サイトエディター、ブロックパターンなどの仕組みを整理しながら、オリジナルテーマ制作ではどちらを選ぶべきか、実務的な視点で考えていきます。
参考資料
- Advanced Custom Fields 公式ドキュメント
- ACF:get_field()
- ACF:get_sub_field()
- ACF:Repeater
- ACF:Flexible Content
- ACF:Options Pages
- ACF:Local JSON
- WordPress Developer Resources:Escaping Data
- WordPress Theme Handbook
※この記事のコードは、ACFのフィールド設定と返り値の形式が一致していることを前提とした実装例です。実際のサイトでは、利用するテーマやプラグイン構成に合わせて調整してください。