0
Help us understand the problem. What are the problem?

posted at

Organization

ACFを使ったカスタムブロックの作り方

ACFで作成したカスタムブロックの使い方

前置き

WordPress 5.0から追加されているブロックエディタ(Gutenberg)のACFを使ったカスタムブロックの使い方を記載していきます。

対応時のバージョン

WordPress 5.7.2

カスタムブロックの作り方

詳しい作り方は公式のチュートリアルを参照。

チュートリアルを見るとわかるがカスタムブロックは基本的にPHPではなくReactの知識が求められる。

なので、今までJSを全くやってこなかったっていう人にはちょっとハードルが高い感じになっている。

そこでACF Proが提供するACF Blocksを利用することでJS部分は書かずにカスタムのブロックを作ることができる。

ACFを使ったカスタムブロックの作り方

公式ドキュメントからの引用になるが、基本的に以下のコードをfunctions.phpに埋め込んであげればtestimonialというブロックが有効化できる。

functions.php
<?php
add_action('acf/init', 'my_acf_init_block_types');
function my_acf_init_block_types() {

    // Check function exists.
    if( function_exists('acf_register_block_type') ) {

        // register a testimonial block.
        acf_register_block_type(array(
            'name'              => 'testimonial',
            'title'             => __('Testimonial'),
            'description'       => __('A custom testimonial block.'),
            'render_template'   => 'template-parts/blocks/testimonial/testimonial.php',
            'category'          => 'formatting',
            'icon'              => 'admin-comments',
            'keywords'          => array( 'testimonial', 'quote' ),
        ));
    }
}

実際にエディタと投稿ページに表示するにはrender_templateで指定しているテンプレートを作成と登録したブロックにカスタムフィールドを紐づける必要がある。

公式ドキュメントからの引用になるがテンプレートの中身は以下の通り。

template-parts/blocks/testimonial/testimonial.php
<?php

/**
 * Testimonial Block Template.
 *
 * @param   array $block The block settings and attributes.
 * @param   string $content The block inner HTML (empty).
 * @param   bool $is_preview True during AJAX preview.
 * @param   (int|string) $post_id The post ID this block is saved to.
 */

// Create id attribute allowing for custom "anchor" value.
$id = 'testimonial-' . $block['id'];
if( !empty($block['anchor']) ) {
    $id = $block['anchor'];
}

// Create class attribute allowing for custom "className" and "align" values.
$className = 'testimonial';
if( !empty($block['className']) ) {
    $className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
    $className .= ' align' . $block['align'];
}

// Load values and assign defaults.
$text = get_field('testimonial') ?: 'Your testimonial here...';
$author = get_field('author') ?: 'Author name';
$role = get_field('role') ?: 'Author role';
$image = get_field('image') ?: 295;
$background_color = get_field('background_color');
$text_color = get_field('text_color');

?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
    <blockquote class="testimonial-blockquote">
        <span class="testimonial-text"><?php echo $text; ?></span>
        <span class="testimonial-author"><?php echo $author; ?></span>
        <span class="testimonial-role"><?php echo $role; ?></span>
    </blockquote>
    <div class="testimonial-image">
        <?php echo wp_get_attachment_image( $image, 'full' ); ?>
    </div>
    <style type="text/css">
        #<?php echo $id; ?> {
            background: <?php echo $background_color; ?>;
            color: <?php echo $text_color; ?>;
        }
    </style>
</div>

ホワイトリスト形式での利用するブロックのフィルタリング

ブロックのフィルタリングはallowed_block_typesを使うことで可能。

指定できるブロックとしてこちらを参考にした。

下記は一例。

functions.php
add_filter('allowed_block_types', function ($allow) {
    return [
        // テキスト
        'core/paragraph',           // 段落
        'core/heading',             // 見出し
        'core/list',                // リスト
        'core/quote',               // 引用
        'core/table',               // テーブル

        // メディア
        'core/image',               // 画像
        'core/gallery',               // 画像

        // デザイン
        'core/columns',             // カラム
        'core/separator',           // 区切り
        'core/spacer',              // スペーサー

        // ウィジェット
        'core/html',                // カスタムHTML

        // 埋め込み
        'core/embed',               // 埋め込み
        'core-embed/twitter',       // Twitter
        'core-embed/youtube',       // YouTube
        'core-embed/wordpress',     // WordPress
    ];
}, 10, 2);

ACFで作ったブロックを有効化する場合には、namespaceがacfになるのでACFの公式ドキュメント例のブロックだとacf/testimonialを追加する必要がある。

注意点としては実際に絞り込みを行おうとしたときにはcore/embedを許可すると許可していない他の埋め込み系のブロックも出てしまうため、個別でJSでフィルタリングをする必要があった。

JSでフィルタリングする場合は下記例。

example.js
wp.domReady(() => {
  wp.blocks.unregisterBlockVariation( 'core/embed', 'soundcloud' );    // SoundCloud
  wp.blocks.unregisterBlockVariation( 'core/embed', 'spotify' );       // Spotify
  wp.blocks.unregisterBlockVariation( 'core/embed', 'flickr' );        // Flickr
  wp.blocks.unregisterBlockVariation( 'core/embed', 'vimeo' );         // Vimeo
  wp.blocks.unregisterBlockVariation( 'core/embed', 'animoto' );       // Animoto
  wp.blocks.unregisterBlockVariation( 'core/embed', 'cloudup' );       // Cloudup
  wp.blocks.unregisterBlockVariation( 'core/embed', 'crowdsignal' );   // Crowdsignal
  wp.blocks.unregisterBlockVariation( 'core/embed', 'dailymotion' );   // Dailymotion
  wp.blocks.unregisterBlockVariation( 'core/embed', 'imgur' );         // Imgur
  wp.blocks.unregisterBlockVariation( 'core/embed', 'issuu' );         // Issuu
  wp.blocks.unregisterBlockVariation( 'core/embed', 'kickstarter' );   // Kickstarter
  wp.blocks.unregisterBlockVariation( 'core/embed', 'meetup-com' );    // Meetup.com
  wp.blocks.unregisterBlockVariation( 'core/embed', 'mixcloud' );      // Mixcloud
  wp.blocks.unregisterBlockVariation( 'core/embed', 'reddit' );        // Reddit
  wp.blocks.unregisterBlockVariation( 'core/embed', 'reverbnation' );  // ReverbNation
  wp.blocks.unregisterBlockVariation( 'core/embed', 'screencast' );    // Screencast
  wp.blocks.unregisterBlockVariation( 'core/embed', 'scribd' );        // Scribd
  wp.blocks.unregisterBlockVariation( 'core/embed', 'slideshare' );    // Slideshare
  wp.blocks.unregisterBlockVariation( 'core/embed', 'smugmug' );       // SmugMug
  wp.blocks.unregisterBlockVariation( 'core/embed', 'speaker-deck' );  // Speaker Deck
  wp.blocks.unregisterBlockVariation( 'core/embed', 'tiktok' );        // TikTok
  wp.blocks.unregisterBlockVariation( 'core/embed', 'ted' );           // TED
  wp.blocks.unregisterBlockVariation( 'core/embed', 'tumblr' );        // Tumblr
  wp.blocks.unregisterBlockVariation( 'core/embed', 'videopress' );    // VideoPress
  wp.blocks.unregisterBlockVariation( 'core/embed', 'wordpress-tv' );  // WordPress.tv
  wp.blocks.unregisterBlockVariation( 'core/embed', 'amazon-kindle' ); // Amazon Kindle
});

また、Gutenbergにはブロックを組み合わせたテンプレートをパターンという形で登録できますが、既存で登録されているパターンで利用しているブロックを削除した場合には利用できなくなるので注意が必要です。

終わりに

実装をやってる途中で5.8が出たのですがリリースが近かったりでアプデ対応はしていません。

5.8ではtheme.jsonという機能が追加されてブロックエディターのカスタマイズがやりやすくなったようです。

theme.jsonのドキュメントはこちら

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?