前回、ブロックエディタのカスタマイズとして、カラーバリエーションの選択ボタンをインスペクターに追加する方法について解説しましたが、今回はインスペクターに独自の data 属性を付与する入力欄を追加する方法について解説します。

これも、前回と同じく Node.js のインストールなどは不要で、プレーンな JavaScript のみで動作します。

使用バージョン:WordPress 6.8

カスタマイズ方法

今回は例として、見出しブロック(H1~H6)を対象に、data-enという名前の data 属性を付けられるようにするコードを紹介します。以下のような、日本語と英語が併記された見出しを想定しています。

JavaScript ファイルの作成と読み込み

まず、JavaScript のファイルを作成し、そのファイルをブロックエディタに読み込むようにします。今回は、テーマフォルダ/js/custom-editor.jsにファイルを作成します。作成したら、functions.phpに以下のように追加します。

add_action('enqueue_block_editor_assets', function() {
  wp_enqueue_script('custom-editor', get_template_directory_uri() . '/js/custom-editor.js');
});

これで、準備はOKです。

インスペクターに入力欄を追加するコード

次に、インスペクターに入力欄を追加するコードです。custom-editor.jsに以下のコードを記述します。

// インスペクターに入力欄を追加
wp.hooks.addFilter(
  'editor.BlockEdit',
  'my-plugin/heading-data-en-control',
  wp.compose.createHigherOrderComponent(
    (BlockEdit) => (props) => {
      // 見出し以外ならそのまま返す
      if (props.name !== 'core/heading') return wp.element.createElement(BlockEdit, props);

      const { attributes, setAttributes } = props;
      const { dataEn } = attributes;

      return wp.element.createElement(
        wp.element.Fragment,
        null,
        wp.element.createElement(BlockEdit, props),
        wp.element.createElement(
          wp.blockEditor.InspectorControls,
          null,
          wp.element.createElement(
            wp.components.PanelBody,
            {
              title: 'タイムスタンプ属性',
              initialOpen: true // デフォルトで開いているかどうか
            },
            wp.element.createElement(wp.components.TextControl, {
              label: 'data-en 属性',
              value: dataEn,
              onChange: (value) => setAttributes({ dataEn: value }),
              help: 'data-en 属性が追加されます',
            })
          )
        )
      );
    },
    'headingDataEnControl'
  )
);

これで、ブロックエディタで見出しを選択した際に、インスペクターに入力欄が表示されるようになりました。

ブロックコメントに情報を追加するコード

このままだと、入力した値はどこにも保存されません。次に、値を保存できるように、ブロックコメントに情報を追加するコードをcustom-editor.jsに追記します。

// ブロックコメントに入力した情報を保存
wp.hooks.addFilter(
  'blocks.registerBlockType',
  'my-plugin/heading-data-en-add-comment',
  function(settings, name) {
    if (name === 'core/heading') {
      settings.attributes = {
        ...settings.attributes,
        dataEn: {
          type: 'string',
          default: '',
        },
      };
    }
    return settings;
  }
);

これで、入力した値がdataEnという名前でブロックコメントに保存されるようになりました。

<!-- wp:heading {"dataEn":"RECOMMEND"} -->
<h2 class="wp-block-heading">オススメ!</h2>
<!-- /wp:heading -->

出力されるタグに data 属性を反映するコード

次に、ブロックコメントに保存した値を、出力されるタグに反映するコードを追記します。

前回のクラスを追加するコードではblocks.getSaveContent.extraPropsというフィルターを使用しましたが、今回はblocks.getSaveElementというフィルターを使用します。

これは、WordPress のブロックエディタは、保存されたブロックの HTML が定義と一致しているかを検証していて、blocks.getSaveContent.extraPropsdata-en属性を追加しても、それは元から定義されているものではないので「このブロックには、想定されていないか無効なコンテンツが含まれています」と、検証エラーになってしまうためです。

// タグに data 属性を追加(検証エラーを回避)
wp.hooks.addFilter(
  'blocks.getSaveElement',
  'my-plugin/heading-data-en-add-tag',
  function(element, blockType, attributes) {
    if (blockType.name === 'core/heading' && attributes.dataEn) {
      return wp.element.cloneElement(element, {
        ...element.props,
        'data-en': attributes.dataEn,
      });
    }
    return element;
  }
);

これで、入力した値が実際に出力される HTML に反映されるようになりました。

<!-- wp:heading {"dataEn":"RECOMMEND"} -->
<h2 class="wp-block-heading" data-en="RECOMMEND">オススメ!</h2>
<!-- /wp:heading -->

ブロックエディタ内の要素に属性を反映するコード

最後に、ブロックエディタ内に表示される要素に data 属性を反映するコードです。

// ブロックエディタ内の要素に data 属性を追加
wp.hooks.addFilter(
  'editor.BlockListBlock',
  'my-plugin/add-data-en-add-editor',
  function (BlockListBlock) {
    return (props) => {
      if (props.name === 'core/heading') {
        const { dataEn } = props.attributes;
        const extraProps = {
          ...props,
          wrapperProps: {
            ...props.wrapperProps,
            ...(dataEn ? { 'data-en': dataEn } : {}),
          },
        };
        return wp.element.createElement(BlockListBlock, extraProps);
      }

      return wp.element.createElement(BlockListBlock, props);
    };
  }
);

これで、ブロックエディタ内の要素にも data 属性が付くようになりました。

あとは、CSS でスタイルを整えれば完成です!

ブロックエディタ上の要素にも data 属性が反映されているため、編集画面用の CSS を作成すればサイト側と表示を合わせることもできます。

ブロックエディタに CSS を読み込んでサイト側の見た目と合わせる方法については過去の記事で解説しているので、よかったらそちらもご参照ください!