Gutenbergエディターのツールバーへ独自ショートコードのメニューを追加する方法

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

はじめに

WordPressを長く運営していると自作のショートコードが増え、以下のように「これは何を表示するコードだっけ?」と用途を忘れてしまうことがあります。

以下の記事では、ショートコードにメモを残して管理しやすくする方法が紹介されています。

そこで、本記事ではさらに一歩進めて、WordPressに登録されている自作ショートコード(接頭辞my_が付いたもの)を自動で取得し、Gutenbergエディターのツールバーへ登録します。

ツールバーのメニューにはショートコード名だけでなく「分かりやすい説明文」も一緒に表示されるため、コードの役割が一目で判別できるようになります。

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

完成イメージ

実装手順

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

add_action('enqueue_block_editor_assets', function () {
  // ブロックエディターのスクリプトが読み込まれていない場合は終了
  if (!wp_script_is('wp-edit-post', 'enqueued')) {
    return;
  }

  // 登録済みショートコードを取得
  global $shortcode_tags;

  $shortcodes = [];

  // ショートコードごとの表示名
  $kind_dictionary = [
    'my_coffee_tab' => 'コーヒー一覧タブ表示',
  ];

  // my_で始まるショートコードのみ抽出
  if (!empty($shortcode_tags)) {
    foreach (array_keys($shortcode_tags) as $tag) {
      if (str_starts_with($tag, 'my_')) {
        $label = '';

        // 該当するショートコードに説明を付加
        foreach ($kind_dictionary as $key => $japanese) {
          if (str_contains($tag, $key)) {
            $label = ' ' . $japanese;
            break;
          }
        }

        $display_title = '[' . $tag . ']' . $label;

        $shortcodes[] = [
          'title' => $display_title,
          'code'  => '[' . $tag . ']',
        ];
      }
    }
  }

  // ショートコード一覧をJavaScriptへ渡す
  $inline_data = 'window.myAvailableShortcodes = ' . wp_json_encode($shortcodes) . ';';
  wp_add_inline_script('wp-edit-post', $inline_data, 'before');

  ob_start();
  ?>
  (function() {
    'use strict';

    // ブロックエディターのAPIが利用できない場合は終了
    if (!wp || !wp.element || !wp.blockEditor || !wp.components || !wp.compose || !wp.hooks) {
      return;
    }

    var el          = wp.element.createElement;
    var Fragment    = wp.element.Fragment;
    var blockEditor = wp.blockEditor;
    var components  = wp.components;
    var compose     = wp.compose;
    var hooks       = wp.hooks;

    /**
     * ブロックツールバーにショートコードメニューを追加
     *
     * @param {Function} BlockEdit 元のブロック編集コンポーネント
     * @return {Function} 拡張されたブロック編集コンポーネント
     */
    var addTextBlocksToolbarControl = compose.createHigherOrderComponent(function(BlockEdit) {
      return function(props) {
        // 対象ブロックを設定
        var targetBlocks = ['core/paragraph'];

        // 対象ブロックが選択されていない場合は終了
        if (!targetBlocks.includes(props.name) || !props.isSelected) {
          return el(BlockEdit, props);
        }

        // ショートコード一覧を取得
        var dynamicOptions = window.myAvailableShortcodes || [];

        // ショートコードのメニュー項目を生成
        var menuItems = dynamicOptions.map(function(item) {
          return {
            title: item.title,
            onClick: function() {
              // ショートコードを末尾に追加
              var currentContent = props.attributes.content || '';

              props.setAttributes({
                content: currentContent + item.code
              });
            }
          };
        });

        // ブロックツールバーにショートコードメニューを追加
        return el(
          Fragment, {},
          el(
            blockEditor.BlockControls,
            {},
            el(
              components.ToolbarGroup,
              {},
              el(components.ToolbarDropdownMenu, {
                icon: 'shortcode',
                label: 'カスタムショートコード',
                controls: menuItems
              })
            )
          ),
          el(BlockEdit, props)
        );
      };
    }, 'addTextBlocksToolbarControl');

    // ブロックエディターにショートコードメニューを追加
    hooks.addFilter(
      'editor.BlockEdit',
      'my-theme/text-blocks-toolbar-label',
      addTextBlocksToolbarControl
    );
  })();
  <?php
  wp_add_inline_script('wp-edit-post', ob_get_clean());
}, 99);

補足

コード内の変数$kind_dictionaryにショートコード名と日本語ラベルをセットラベルをセットしておきます。
こうすることで、システムに登録されている味気ない名前ではなく、用途がひと目でわかる親切な「説明文」を追加してメニュー表示できるようになります。

例えば、コード内で以下のように設定します。

$kind_dictionary = [
  'my_coffee_tab' => 'コーヒー一覧タブ表示',
];

さいごに

今回紹介した方法を使えば、増え続ける自作ショートコードを自動で集約し、分かりやすい説明文付きの独自メニューをGutenbergエディターのツールバーへ表示することができます。
これにより、「このコードは何だっけ?」と用途を忘れてしまう問題を一発で解決できます。

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