WordPress

✅【2025年最新版】初心者でもできる!ACFブロックを使ったカスタムGutenbergブロックの作り方

こんにちは!WordPressサイト制作をしていると、「もっと自由にブロックをカスタマイズしたい」「クライアントが使いやすいブロックを作りたい」と思ったことはありませんか?

Gutenbergブロックを自作するには通常、JavaScriptやReactの知識が必要ですが、Advanced Custom Fields(ACF)Proを使えば、PHPだけでカスタムブロックが作れるんです!🎉

この記事では、ACFブロックを使ったカスタムGutenbergブロックの作り方を、初心者にもわかりやすく解説します。実際のコード例と共に、ステップバイステップで進めていきましょう!

目次[-]

📋 この記事でわかること

  • ACFブロックとは何か、そのメリット
  • 必要なツールと環境設定
  • ステップバイステップでのACFブロックの作り方
  • カスタムブロックの表示カスタマイズ方法
  • よくある問題と解決策
  • ACFブロックの応用例

ACFブロックとは?そのメリットを知ろう🤔

🔷 ACFブロックの基本

ACFブロック(ACF Blocks)は、Advanced Custom Fields Proの機能で、カスタムフィールドの力を活かしてGutenbergブロックを作成できるフレームワークです。

標準のGutenbergブロックとACFブロックの主な違いは以下の通りです:

標準のGutenbergブロックACFブロック
JavaScript/ReactベースPHPベース
開発の学習曲線が高い比較的簡単に始められる
静的なコンテンツに向いている動的なコンテンツに最適
ビルドプロセスが必要直接PHPで書ける
フロントエンド開発の知識が必要PHPとWordPressのテーマ開発の知識があれば十分

🔷 ACFブロックのメリット

  1. PHPだけで作れる: JavaScriptやReactの知識がなくても作成できる
  2. 学習曲線が緩やか: WordPressのテーマ開発と似たアプローチ
  3. カスタムフィールドとの連携: ACFの豊富なフィールドタイプを活用できる
  4. 編集インターフェースの自由度: ユーザーフレンドリーな入力画面を構築できる
  5. 標準機能との互換性: Gutenbergの「配置」「アンカー」などの機能が使える

🔷 実際の使用例

ACFブロックは以下のような場面で特に役立ちます:

  • クライアントサイト向けのカスタム要素(お知らせ、商品紹介など)
  • 複雑なレイアウトを持つセクション(ヒーローエリア、特徴紹介など)
  • 繰り返し要素のあるコンテンツ(よくある質問、スタッフ紹介など)
  • 特定のデザインガイドラインに沿った要素

必要なツールと環境設定🛠️

ACFブロックを作成するには、以下のものが必要です:

  1. WordPress(最新版推奨): 自己ホスティング型のWordPressサイト
  2. Advanced Custom Fields Pro: ACFブロックはPro版の機能です(無料版では使えません)
  3. テーマへのアクセス権: ファイルを編集・追加できる環境
  4. コードエディタ: Visual Studio Codeなどのエディタがあると便利

🔷 ACF Proのインストール

ACF Proは公式サイト(advancedcustomfields.com)から購入してダウンロードできます。インストール方法:

  1. WordPress管理画面から「プラグイン」→「新規追加」→「プラグインのアップロード」
  2. ダウンロードしたZIPファイルを選択してアップロード
  3. 「今すぐインストール」→「プラグインを有効化」

🔷 作業ディレクトリの準備

ACFブロックは以下のいずれかの方法で追加できます:

  1. テーマ内に追加: 現在のテーマまたは子テーマ内にブロックを作成
  2. プラグインとして追加: カスタムプラグインを作成してブロックを追加

初心者の方には、まずテーマ内に追加する方法をおすすめします。この記事では、子テーマを使用する方法を解説します。

ステップバイステップでのACFブロックの作り方👨‍💻

それでは実際に、シンプルな「お客様の声(テスティモニアル)」ブロックを作成してみましょう。

🔷 ステップ1: ブロック用ディレクトリの作成

まず、テーマ内にブロック用のディレクトリを作成します:

  1. テーマのルートディレクトリに移動
  2. blocksディレクトリを作成
  3. 作成するブロック用のディレクトリ(例:testimonial)を作成
your-theme/
├── blocks/
│   └── testimonial/
├── functions.php
└── style.css

🔷 ステップ2: block.jsonファイルの作成

最新の方法では、block.jsonファイルを使ってブロックを定義します。testimonialディレクトリ内にblock.jsonファイルを作成してください:

{
  "name": "acf/testimonial",
  "title": "お客様の声",
  "description": "お客様からのフィードバックを表示するブロック",
  "category": "formatting",
  "icon": "format-quote",
  "keywords": ["testimonial", "quote", "feedback"],
  "acf": {
    "mode": "preview",
    "renderTemplate": "template.php"
  },
  "supports": {
    "align": true,
    "mode": false,
    "jsx": true,
    "color": {
      "background": true,
      "text": true
    }
  },
  "example": {
    "attributes": {
      "mode": "preview",
      "data": {
        "preview_image_help": "screenshot.png"
      }
    }
  },
  "style": "file:./style.css"
}

このJSONファイルでは以下の内容を設定しています:

  • name: ブロックの一意の名前(名前空間/ブロック名)
  • title: エディターに表示されるブロック名
  • description: ブロックの説明
  • category: ブロックの分類カテゴリー
  • icon: ブロックのアイコン
  • acf: ACF固有の設定
    • mode: エディターでの表示モード
    • renderTemplate: テンプレートファイルのパス
  • supports: ブロックがサポートする機能
  • example: エディターでのプレビュー設定
  • style: ブロックのスタイルシート

🔷 ステップ3: カスタムフィールドの設定

ACF管理画面から、テスティモニアルブロック用のフィールドを作成します:

  1. 「カスタムフィールド」→「フィールドグループを追加」をクリック
  2. グループ名を「テスティモニアルブロック」などに設定
  3. 以下のフィールドを追加:
    • フィールド名:testimonial_text、タイプ:テキストエリア、ラベル:「お客様の声」
    • フィールド名:customer_name、タイプ:テキスト、ラベル:「お客様名」
    • フィールド名:customer_position、タイプ:テキスト、ラベル:「役職・所属」(任意)
    • フィールド名:customer_image、タイプ:画像、ラベル:「お客様画像」(任意)
  4. 「表示条件」を設定:
    • 「ブロック」→「次と等しい」→「お客様の声」を選択
  5. 「公開」をクリックして保存

🔷 ステップ4: テンプレートファイルの作成

testimonialディレクトリ内にtemplate.phpファイルを作成し、ブロックのHTMLを記述します:

<?php
/**
 * テスティモニアルブロックのテンプレート
 *
 * @param array $block ブロックの設定と属性
 * @param string $content ブロックの内容
 * @param bool $is_preview プレビューモードかどうか
 * @param int $post_id 現在の投稿ID
 */

// ブロッククラスの作成
$className = 'testimonial';
if (!empty($block['className'])) {
    $className .= ' ' . $block['className'];
}
if (!empty($block['align'])) {
    $className .= ' align' . $block['align'];
}

// カスタムフィールドの値を取得
$testimonial_text = get_field('testimonial_text');
$customer_name = get_field('customer_name');
$customer_position = get_field('customer_position');
$customer_image = get_field('customer_image');

// ブロックID(アンカー)
$id = 'testimonial-' . $block['id'];
if (!empty($block['anchor'])) {
    $id = $block['anchor'];
}

// ブロックのスタイル属性
$block_style = '';
if (!empty($block['backgroundColor'])) {
    $block_style .= 'background-color: var(--wp--preset--color--' . $block['backgroundColor'] . ');';
}
if (!empty($block['textColor'])) {
    $block_style .= 'color: var(--wp--preset--color--' . $block['textColor'] . ');';
}
?>

<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>" style="<?php echo esc_attr($block_style); ?>">
    <?php if ($is_preview && !$testimonial_text) : ?>
        <p class="testimonial-placeholder">お客様の声を入力してください</p>
    <?php else : ?>
        <div class="testimonial-content">
            <?php if ($testimonial_text) : ?>
                <blockquote class="testimonial-text">
                    <?php echo esc_html($testimonial_text); ?>
                </blockquote>
            <?php endif; ?>
            
            <div class="testimonial-meta">
                <?php if ($customer_image) : ?>
                    <div class="testimonial-image">
                        <img src="<?php echo esc_url($customer_image['url']); ?>" alt="<?php echo esc_attr($customer_name); ?>">
                    </div>
                <?php endif; ?>
                
                <div class="testimonial-info">
                    <?php if ($customer_name) : ?>
                        <cite class="testimonial-name">
                            <?php echo esc_html($customer_name); ?>
                        </cite>
                    <?php endif; ?>
                    
                    <?php if ($customer_position) : ?>
                        <span class="testimonial-position">
                            <?php echo esc_html($customer_position); ?>
                        </span>
                    <?php endif; ?>
                </div>
            </div>
        </div>
    <?php endif; ?>
</div>

🔷 ステップ5: スタイルシートの作成

testimonialディレクトリにstyle.cssファイルを作成してスタイルを追加します:

.testimonial {
    padding: 2rem;
    margin-bottom: 2rem;
    border-radius: 0.5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.testimonial-placeholder {
    padding: 2rem;
    text-align: center;
    font-style: italic;
    color: #666;
    background-color: #f5f5f5;
    border: 1px dashed #ccc;
}

.testimonial-text {
    font-size: 1.2rem;
    line-height: 1.6;
    margin: 0 0 1.5rem;
    position: relative;
    font-style: italic;
    color: inherit;
}

.testimonial-text::before {
    content: """;
    font-size: 3rem;
    position: absolute;
    left: -1.5rem;
    top: -1rem;
    opacity: 0.2;
}

.testimonial-meta {
    display: flex;
    align-items: center;
}

.testimonial-image {
    margin-right: 1rem;
}

.testimonial-image img {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    object-fit: cover;
}

.testimonial-info {
    display: flex;
    flex-direction: column;
}

.testimonial-name {
    font-weight: bold;
    font-style: normal;
}

.testimonial-position {
    font-size: 0.9rem;
    opacity: 0.8;
}

🔷 ステップ6: プレビュー画像の追加(オプション)

簡単なプレビュー画像を追加することで、ブロック選択時の見た目が良くなります。testimonialディレクトリにscreenshot.pngという名前で画像ファイルを追加しましょう。

🔷 ステップ7: ブロックの登録

最後に、functions.phpにブロックを登録するコードを追加します:

/**
 * ACFブロックの登録
 */
function register_acf_blocks() {
    // ACFが有効化されているか確認
    if (function_exists('register_block_type')) {
        // ブロックの登録
        register_block_type(get_template_directory() . '/blocks/testimonial');
    }
}
add_action('init', 'register_acf_blocks');

複数のブロックを登録する場合は、以下のように書けます:

function register_acf_blocks() {
    if (function_exists('register_block_type')) {
        // 複数のブロックを登録
        $blocks = [
            'testimonial',
            'team-member',
            'feature-box',
            // 他のブロックも追加できます
        ];
        
        foreach ($blocks as $block) {
            register_block_type(get_template_directory() . '/blocks/' . $block);
        }
    }
}
add_action('init', 'register_acf_blocks');

これで完成です!WordPress管理画面でページやブロックエディターを開き、ブロック挿入メニューから「お客様の声」ブロックを選択できるようになりました。

カスタムブロックの表示カスタマイズ方法🎨

作成したACFブロックの見た目や機能をさらにカスタマイズしてみましょう。

🔷 ブロックスタイルの追加

block.jsonstylesプロパティを追加することで、エディター上で選択できるスタイルバリエーションを追加できます:

{
  "name": "acf/testimonial",
  "title": "お客様の声",
  // 他の設定...
  "styles": [
    {
      "name": "default",
      "label": "デフォルト",
      "isDefault": true
    },
    {
      "name": "bordered",
      "label": "枠線あり"
    },
    {
      "name": "card",
      "label": "カード型"
    }
  ]
}

そして、style.cssにスタイルごとのCSSを追加します:

/* デフォルトスタイル(既存のCSS) */

/* 枠線ありスタイル */
.testimonial.is-style-bordered {
    border: 2px solid #e0e0e0;
    box-shadow: none;
}

/* カード型スタイル */
.testimonial.is-style-card {
    background-color: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    padding: 2.5rem;
}

.testimonial.is-style-card .testimonial-text {
    font-size: 1.3rem;
}

🔷 ブロックパターン(バリエーション)の追加

block.jsonvariationsプロパティを追加することで、同じブロックの異なるバージョンを作成できます:

{
  "name": "acf/testimonial",
  "title": "お客様の声",
  // 他の設定...
  "variations": [
    {
      "name": "simple",
      "title": "シンプル",
      "description": "シンプルなスタイルのお客様の声",
      "isDefault": true
    },
    {
      "name": "with-image",
      "title": "画像付き",
      "description": "お客様の画像付きのお客様の声",
      "isActive": ["customer_image"]
    }
  ]
}

テンプレートファイルで、バリエーションに基づいて表示を変更できます:

<?php
// バリエーションの取得
$variation = isset($block['variation']) ? $block['variation'] : 'simple';
$className .= ' is-variation-' . $variation;

// テンプレートの内容...
?>

🔷 インナーブロックの追加

ACFブロック内にさらに他のGutenbergブロックを配置できるようにするには、block.jsonsupportsjsxを追加し、テンプレートでInnerBlocksを使用します:

{
  "name": "acf/testimonial",
  "title": "お客様の声",
  // 他の設定...
  "supports": {
    "jsx": true,
    // 他のサポート設定...
  }
}

そして、テンプレートを修正:

<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
    <!-- 他のコンテンツ... -->
    
    <?php if ($is_preview && !$testimonial_text) : ?>
        <p class="testimonial-placeholder">お客様の声を入力してください</p>
    <?php else : ?>
        <!-- テスティモニアルのコンテンツ... -->
        
        <!-- インナーブロックのための場所 -->
        <div class="testimonial-additional">
            <InnerBlocks />
        </div>
    <?php endif; ?>
</div>

よくある問題と解決策⚠️

ACFブロックを作成する際によくある問題とその解決策を紹介します。

🔷 ブロックが表示されない

問題: ブロックがエディターに表示されない、またはエラーが発生する

解決策:

  1. block.jsonのシンタックスエラーを確認(カンマやクォーテーションマークなど)
  2. ACF Proが正しくインストール・有効化されているか確認
  3. register_block_type関数のパスが正しいか確認
  4. ブラウザのコンソールでJavaScriptエラーを確認

🔷 フィールドの値が取得できない

問題: get_field()で値が取得できない

解決策:

  1. フィールド名が正確に一致しているか確認
  2. フィールドグループの表示条件が正しく設定されているか確認
  3. get_field()の前にデバッグコードを追加:
<?php
// デバッグ
error_log('Block fields: ' . print_r(get_fields(), true));
$testimonial_text = get_field('testimonial_text');
// 以降のコード...

🔷 スタイルが適用されない

問題: CSSスタイルがエディターや前面で適用されない

解決策:

  1. block.jsonstyleパスが正しいか確認
  2. ブラウザの開発者ツールでCSSが読み込まれているか確認
  3. セレクターの詳細度(specificity)が十分か確認

🔷 エディターとフロントエンドの表示が異なる

問題: エディターでの表示と実際の公開ページでの表示が異なる

解決策:

  1. エディター専用のスタイルを分離:
// エディター用のスタイル
if (is_admin()) {
    add_action('admin_enqueue_scripts', function() {
        wp_enqueue_style(
            'testimonial-editor-style',
            get_template_directory_uri() . '/blocks/testimonial/editor.css'
        );
    });
}
  1. フロントエンド用とエディター用で条件分岐:
<?php if (is_admin()) : ?>
    <!-- エディター専用の表示 -->
<?php else : ?>
    <!-- フロントエンド専用の表示 -->
<?php endif; ?>

ACFブロックの応用例と発展的な使い方💡

ACFブロックの可能性をさらに広げる応用例と発展的な使い方を紹介します。

🔷 リピーターフィールドを活用したスライダーブロック

ACFのリピーターフィールドを使って、複数のスライドを管理できるスライダーブロックを作成できます:

  1. リピーターフィールド「slides」を作成し、その中に「image」「title」「description」などのサブフィールドを追加
  2. テンプレートファイルでリピーターの値をループして表示:
<?php if (have_rows('slides')) : ?>
    <div class="slider">
        <?php while (have_rows('slides')) : the_row(); 
            $image = get_sub_field('image');
            $title = get_sub_field('title');
            $description = get_sub_field('description');
        ?>
            <div class="slide">
                <?php if ($image) : ?>
                    <img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($title); ?>">
                <?php endif; ?>
                
                <div class="slide-content">
                    <?php if ($title) : ?>
                        <h3><?php echo esc_html($title); ?></h3>
                    <?php endif; ?>
                    
                    <?php if ($description) : ?>
                        <p><?php echo esc_html($description); ?></p>
                    <?php endif; ?>
                </div>
            </div>
        <?php endwhile; ?>
    </div>
    
    <script>
        // Slick Sliderなどのスライダーライブラリを初期化するコード
        jQuery(document).ready(function($) {
            $('.slider').slick({
                arrows: true,
                dots: true,
                autoplay: true
            });
        });
    </script>
<?php endif; ?>

🔷 条件分岐を使ったフレキシブルブロック

条件分岐を使って、1つのブロックで複数のレイアウトを切り替えられます:

  1. 「layout」というラジオボタンフィールドを作成し、「left」「right」「centered」などのオプションを設定
  2. テンプレートで選択値に基づいて表示を変更:
<?php
$layout = get_field('layout') ?: 'left';
$className .= ' layout-' . $layout;
?>

<div class="<?php echo esc_attr($className); ?>">
    <?php if ($layout === 'left') : ?>
        <!-- 左寄せレイアウト -->
    <?php elseif ($layout === 'right') : ?>
        <!-- 右寄せレイアウト -->
    <?php else : ?>
        <!-- 中央寄せレイアウト -->
    <?php endif; ?>
</div>

🔷 外部APIと連携したダイナミックブロック

外部APIからデータを取得して表示するブロックも作成できます:

<?php
// APIキーをフィールドから取得
$api_key = get_field('api_key');
$location = get_field('location') ?: 'Tokyo';

// キャッシュキーを作成
$cache_key = 'weather_' . sanitize_title($location) . '_' . date('Ymd');
$weather_data = get_transient($cache_key);

// キャッシュがなければAPIリクエスト
if (false === $weather_data) {
    $api_url = "https://api.weatherapi.com/v1/current.json?key={$api_key}&q={$location}";
    $response = wp_remote_get($api_url);
    
    if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
        $weather_data = json_decode(wp_remote_retrieve_body($response), true);
        set_transient($cache_key, $weather_data, 3 * HOUR_IN_SECONDS);
    }
}

// データを表示
if ($weather_data && isset($weather_data['current'])) :
    $current = $weather_data['current'];
?>
    <div class="weather-widget">
        <h3><?php echo esc_html($location); ?>の天気</h3>
        <div class="weather-info">
            <img src="<?php echo esc_url($current['condition']['icon']); ?>" alt="<?php echo esc_attr($current['condition']['text']); ?>">
            <div class="temperature"><?php echo esc_html($current['temp_c']); ?>°C</div>
            <div class="condition"><?php echo esc_html($current['condition']['text']); ?></div>
        </div>
    </div>
<?php else : ?>
    <div class="weather-widget error">
        <p>天気データを取得できませんでした</p>
    </div>
<?php endif; ?>

まとめ:ACFブロックを活用して制作効率アップ!🚀

ACFブロックを使うことで、JavaScriptやReactの知識がなくても、独自のGutenbergブロックを作成できることがわかりました。PHPとWordPressのテーマ開発の知識があれば、クライアントに最適化されたカスタムブロックを提供できます。

ACFブロックの主なメリットをおさらいしましょう:

  • 開発の容易さ: PHPだけで作成できるため、学習コストが低い
  • 高いカスタマイズ性: ACFの豊富なフィールドタイプを活用できる
  • 再利用性: 一度作成したブロックを複数のサイトで活用できる
  • 保守性: 標準的なWordPressテーマ開発のアプローチでメンテナンスしやすい

クライアントに特化したサイト制作や、独自の機能が必要なプロジェクトでは、ACFブロックは非常に強力なツールとなります。この記事で学んだ知識をもとに、あなただけのカスタムブロックを作成してみてください!

以下に、今後チャレンジしてみるとよいACFブロックのアイデアをいくつか紹介します:

  • チーム紹介ブロック: メンバーの写真、名前、役職、自己紹介などを表示
  • 料金表ブロック: 複数のプラン、機能一覧、料金を比較表示
  • ステップブロック: 手順や流れを番号付きで表示
  • タブコンテンツブロック: 複数のタブでコンテンツを切り替え表示
  • アコーディオンブロック: よくある質問など、開閉するコンテンツを表示

参考リンク

hisa

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA