Gutenbergエディタ(ブロックエディタ)にボタンを追加する

WordPress

WordPressのバージョンが5.0になり、エディタが新しくなりました。

新しい Gutenberg 編集エクスペリエンス
コードネームは「Gutenberg」、WordPress の新しい編集エクスペリエンスが現在開発中です。詳細をお読みの上、テストしてみてください。

これまでのTinyMCEとは異なりReactを利用したモダンな実装になっており、エディタへの機能の追加方法も大きく変わりました。

ここでは選択した文字列を特定のクラスを持ったspanで囲うボタンの追加方法を紹介します。

実装するもの

PHPとJavaScript、CSSを編集します。

PHP側は適当に作成したプラグインのmy_plugin.php、JavaScriptとCSSはそのプラグイン配下に作成することを想定しています。

今回はReactを使用しない方法になります。

そのためフロントエンドのビルド環境の用意は必要ありません

JavaScriptやCSSを登録

TinyMCEの時はJavaScriptとCSSの登録は別々でしたが、Gutenbergでは「enqueue_block_editor_assets」アクションをフックして「wp_enqueue_style」や「wp_enqueue_script」を使用して登録します。

「wp_localize_script」でJavaScript側にデータを渡すことも可能です。

ここでは「wp_enqueue_script」の依存関係に「wp-element」「wp-rich-text」「wp-editor」を追加しておきます。

my_plugin.php

add_action( 'enqueue_block_editor_assets', function () {
   wp_enqueue_style( 'my_plugin', plugins_url( 'assets/css/editor.css', __FILE__ ) );
   wp_enqueue_script( 'my_plugin', plugins_url( 'assets/js/editor.js', __FILE__ ), [
      'wp-element',
      'wp-rich-text',
      'wp-editor',
   ] );
   wp_localize_script( 'my_plugin', 'my_plugin_obj', [
      'title' => 'My Plugin',
      'class' => 'my-plugin',
   ] );
} );

CSSを編集

クラスで囲われたかどうかをわかりやすくするため装飾します。

editor.css

.my-plugin {
    display: inline;
    background-position: left -100% center;
    background-repeat: repeat-x;
    background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 50%, #ff6 50%);
    background-size: 200% .6em;
    font-weight: bold;
    padding-bottom: .6em;
}

ここではクラスで囲われた箇所に蛍光ペンを引いたような装飾をつけています。

この装飾はエディタ用です。

実際にフロント側で何かデザインをつけるためには別途フロント用のCSSを用意して読み込ませるようにする必要があります。

JavaScriptを編集

先ほど依存関係に登録した「wp-element」「wp-rich-text」「wp-editor」はそれぞれ「window.wp.element」「window.wp.richText」「window.wp.editor」として使用できます。

以下のように短い名前で使用できるようにしておきます。

(function (richText, element, editor) {
    
}(
    window.wp.richText,
    window.wp.element,
    window.wp.editor
));

ボタンを追加するには「richText」の「registerFormatType」を使用します。

WordPress/gutenberg
The Block Editor project for WordPress and beyond. Plugin is available from the official repository. - WordPress/gutenberg

ここでは「title」「tagName」「className」「edit」を登録します。

editor.js

(function (richText, element, editor) {
    const name = 'my-plugin/my-plugin';
    richText.registerFormatType(name, {
        title: my_plugin_obj.title,
        tagName: 'span',
        className: my_plugin_obj.class,
        edit: function ({isActive, value, onChange}) {
            return element.createElement(editor.RichTextToolbarButton, {
                icon: 'admin-customizer',
                title: my_plugin_obj.title,
                onClick: function () {
                    onChange(richText.toggleFormat(value, {
                        type: name
                    }));
                },
                isActive: isActive,
            });
        },
    });
}(
    window.wp.richText,
    window.wp.element,
    window.wp.editor
));

editor.RichTextToolbarButton

WordPress/gutenberg
The Block Editor project for WordPress and beyond. Plugin is available from the official repository. - WordPress/gutenberg

ToolbarButton

WordPress/gutenberg
The Block Editor project for WordPress and beyond. Plugin is available from the official repository. - WordPress/gutenberg

iconに設定するアイコンは以下のページから選択可能です。

Dashicons | WordPress Developer Resources
WordPress/gutenberg
The Block Editor project for WordPress and beyond. Plugin is available from the official repository. - WordPress/gutenberg

ここまでの処理で以下のようにボタンが追加されます。

動作確認

文字を選択した状態でボタンを押すと蛍光ペンを引いたような装飾がされました。

「HTMLとして編集」から確認すると「my-plugin」クラスのspanで囲われていることが確認できます。

装飾されている箇所にカーソルが当たっている状態だとボタンが選択されたような表示になり、この時にボタンを押すと装飾が外れ、「my-plugin」クラスのspanで囲われていたものが外れます。

多言語化

プラグインを公開する場合は多言語化対応が必要です。

  • 依存関係に「wp-i18n」を追加
  • wp_set_script_translationsを使用して翻訳データを登録
  • window.wp.i18n を使用して多言語対応

Classic Editorへの対応

多くの人がプラグインを使用して今までのエディタを使用することを選択するでしょう。

Classic Editor
Enables the previous "classic" editor and the old-style Edit Post screen with TinyMCE, Meta Boxes, etc. Supports all plugins that extend thi …

またGutenbergエディタからも「フォーマット」⇒「クラシック」から今までのエディタをブロックとして利用することが可能です。

したがってプラグイン開発者はどちらのエディタにも対応する必要があります。

特に「admin_head-post.php」や「admin_head-post-new.php」をフックしてTinyMCEに渡す変数を埋め込んでいた場合に、Gutenbergで「block_editor_preload_paths」をフックして同じ名前で変数を渡すとバッティングしてしまいます。

同じ変数でもそれぞれ別の名前で渡すようにするか、Gutenbergエディタの場合は「block_editor_preload_paths」だけで変数を渡すようにするとよいかもしれません。

Gutenbergエディタかクラシックエディタかの判定は以下のようなコード行うことができます。

$current_screen = get_current_screen();
if ( ( method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) || ( function_exists( 'is_gutenberg_page' ) && is_gutenberg_page() ) ) {
   // Gutenberg Editor
} else {
   // Classic Editor
}

まとめ

Reactで作られた新しいエディタでも、ビルド環境を用意することなく割と気軽にエディタへの機能の追加が可能になっていることがわかりました。

ブログのメイン機能と言っても過言ではないエディタへの大きな変更が今後のCMS界隈にどう影響していくのかが気になります。

コメント