Gutenbergエディタ(ブロックエディタ)にボタンを追加する
WordPressのバージョンが5.0になり、エディタが新しくなりました。
これまでの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側にデータを渡すことも可能です。
下の例ではボタンに表示されるタイトルとクラス名をPHP側から渡せるようにしています。
ここでは「wp_enqueue_script」の依存関係に「wp-element」「wp-rich-text」「wp-editor」を追加します。
後で追加するJavaScriptでこれらを使用するためで、もし他に依存するもの(wp-data や wp-i18n など)を使用する場合はそれらを追加します。
ここで追加した依存関係によってJavaScriptファイルの読み込み順をWordPressが適切に判断してくれるようになります。
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', 'myPluginObj', [
'title' => 'My Plugin',
'class' => 'my-plugin',
] );
} );
CSSを編集
クラスで囲われたかどうかをわかりやすくするため装飾します。
assets/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」を使用します。
ここでは「title」「tagName」「className」「edit」を登録します。
assets/js/editor.js
(function (richText, element, editor) {
const name = 'my-plugin/my-plugin';
richText.registerFormatType(name, {
title: myPluginObj.title,
tagName: 'span',
className: myPluginObj.class,
edit: function (args) {
return element.createElement(editor.RichTextToolbarButton, {
icon: 'admin-customizer',
title: myPluginObj.title,
onClick: function () {
args.onChange(richText.toggleFormat(args.value, {
type: name
}));
},
isActive: args.isActive,
});
},
});
}(
window.wp.richText,
window.wp.element,
window.wp.editor
));
my_plugin.php で wp_localize_script を使用して登録したタイトルとクラス名をそれぞれ
- myPluginObj.title
- myPluginObj.class
として使用しています。
PHPから渡す必要がない場合は直接JavaScriptファイルにタイトルとクラス名を書いても動作します。
editor.RichTextToolbarButton
ToolbarButton
iconに設定するアイコンは以下のページから選択可能です。
ここまでの処理で以下のようにボタンが追加されます。
動作確認
文字を選択した状態でボタンを押すと蛍光ペンを引いたような装飾がされました。
「HTMLとして編集」から確認すると「my-plugin」クラスのspanで囲われていることが確認できます。
装飾されている箇所にカーソルが当たっている状態だとボタンが選択されたような表示になり、この時にボタンを押すと装飾が外れ、「my-plugin」クラスのspanで囲われていたものが外れます。
追記:複数のボタンを追加
コメントで複数追加する場合の質問があったので追記します。
richText.registerFormatType<br>
を使用すればいくつでもボタンを追加ことが可能です。
ただし、同じクラス名や複数のクラス名を指定できません。
まとめ
Reactで作られた新しいエディタでも、ビルド環境を用意することなく割と気軽にエディタへの機能の追加が可能になっていることがわかりました。
ブログのメイン機能と言っても過言ではないエディタへの大きな変更が今後のCMS界隈にどう影響していくのかが気になります。
追記:プラグインを作成しました
通常の方法ではいくつかのボタンをまとめてドロップダウンにしたり複数クラスを指定したりカラーピッカーやフォントサイズピッカーを追加できませんが、このプラグインではそれらが実現可能です。