「タブ見出しボックス」ブロックの見出しを目次に反映する方法

Cocoonカスタマイズ集
この記事は約7分で読めます。
記事内に広告が含まれています。

はじめに

以下をCocoonで実現します。

「タブ見出しボックス」ブロックの見出しを、設定パネルの内容に応じて H2~H6に変更し、目次に表示できるようにします。

この記事では、この方法について説明します。

「タブ見出しボックス」ブロックの見出しを変更する場合、必ず直前に「見出しH2」ブロックが1つ存在している必要があります。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// 「タブ見出しボックス」ブロックを変更
add_filter('render_block_cocoon-blocks/tab-caption-box-1', function ($content, $block) {
  $class = isset($block['attrs']['className']) ? $block['attrs']['className'] : '';

  if (!preg_match('/my-h([2-6])/', $class, $matches)) {
    return $content;
  }

  $h = 'h' . $matches[1];

  $pattern = '/<span class="(tab-caption-box-label-text.*?)">(.*?)<\/span>/s';
  $replacement = '<' . $h . ' class="$1" style="all: unset;">$2</' . $h . '>';

  return preg_replace($pattern, $replacement, $content);
}, 10, 2);


// エディター用JS・CSSを追加
add_action('enqueue_block_editor_assets', function () {
  ob_start();
  ?>
  (function(wp) {
    // エディター関連のオブジェクトが存在するか確認
    if (!wp.blockEditor && !wp.editor) {
      return;
    }

    const { addFilter } = wp.hooks;
    const { createElement, Fragment } = wp.element;
    const { InspectorControls } = wp.blockEditor || wp.editor;
    const { PanelBody, SelectControl } = wp.components;
    const { createHigherOrderComponent } = wp.compose;
    const { __ } = wp.i18n;

    // 対象とするブロックのスラッグを指定
    const allowedBlocks = ['cocoon-blocks/tab-caption-box-1'];

    /**
     * 見出しレベルコントロールを追加する高階コンポーネント
     *
     * @param {Function} BlockEdit ブロック編集コンポーネント
     * @return {Function} 拡張されたコンポーネント
     */
    const withHeadingLevelControl = createHigherOrderComponent(function(BlockEdit) {
      return function(props) {
        // 対象外のブロックの場合はそのまま返す
        if (!allowedBlocks.includes(props.name)) {
          return createElement(BlockEdit, props);
        }

        const attributes = props.attributes;
        const setAttributes = props.setAttributes;
        let className = attributes.className || '';

        // 現在の選択値(デフォルト)を設定
        let current = 'default';
        const match = className.match(/my-h([2-6])/);

        if (match) {
          current = 'h' + match[1];
        }

        // エディターのサイドバーにコントロールを追加
        return createElement(
          Fragment,
          null,
          createElement(BlockEdit, props),
          createElement(
            InspectorControls,
            null,
            createElement(
              PanelBody,
              { title: '見出しレベル', initialOpen: true },
              createElement(SelectControl, {
                label: 'Hタグを選択',
                value: current,
                options: [
                  { label: 'デフォルト', value: 'default' },
                  { label: 'H2', value: 'h2' },
                  { label: 'H3', value: 'h3' },
                  { label: 'H4', value: 'h4' },
                  { label: 'H5', value: 'h5' },
                  { label: 'H6', value: 'h6' },
                ],
                onChange: function(value) {
                  // 既存の見出しクラスを削除
                  className = className.replace(/\bmy-h[2-6]\b/, '').trim();

                  // デフォルト以外の場合は新しいクラスを追加
                  if (value !== 'default') {
                    className = (className + ' my-' + value).trim();
                  }

                  // 属性を更新して保存
                  setAttributes({ className: className || undefined });
                }
              })
            )
          )
        );
      };
    }, 'withHeadingLevelControl');

    // ブロック編集画面にフィルターをフック
    addFilter(
      'editor.BlockEdit',
      'my-plugin/my-tab-caption-box',
      withHeadingLevelControl
    );
  })(window.wp);
  <?php

  $handle = 'tab-caption-box';

  wp_register_script($handle, false, ['wp-block-editor', 'wp-components', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-compose'], false, true);
  wp_enqueue_script($handle);
  wp_add_inline_script($handle, ob_get_clean());
});

さいごに

今回紹介した方法を使えば、「タブ見出しボックス」ブロックの見出しを目次に反映できるようになります。
H2~H6の見出しタグを選択できるようになるため、サイト内の目次表示やSEO対策にも対応可能です。

タイトルとURLをコピーしました