前回に引き続き Gutenberg のブロックサンプルを作っていきたいと思います。今回は編集可能な備考ブロックを作ります。前回作ったただ文字を表示するブロックに比べれば多少使い道はあるでしょう。
前回は WP-CLI を使ってひな形を作りましたが、今回はスクラッチで作っていきます。ソースコードをGitLabにまとめてあるのでよかったらご覧ください。
プラグインの作成
まずはプラグインの作成からです。名前はなんでもいいですが今回は プラグイン名をmy-note-plugin
、ブロック名を note-block
とします。
wp-content/plugins
に my-note-plugin
フォルダを作って、
$ cd wp-content/plugins $ mkdir my-note-plugin
その中に my-note-plugin.php
を作って、
$ cd my-note-plugin $ vi my-note-plugin.php
中身はこんな感じでいいでしょう。
<?php /** * Plugin Name: My Note Plugin * Version: 0.1 */
ここまでやると WordPress のプラグイン設定画面に作成したプラグインが表示されるので「有効化」します。
HTMLとCSSを作成
ブロックの作成に取り掛かる前に完成形のHTMLとCSSを作ります。これはまだ保存する必要はないですが、ブロックと同時に作るとぐちゃぐちゃになってくるので先に作ってしまいます。
HTMLはこんな感じ
<div class="wp-block-my-note-plugin-note-block"> <p class="wp-block-my-note-plugin-note-block__heading">Note</p> <div class="wp-block-my-note-plugin-note-block__content"> <p>備考本文</p> <p>備考本文</p> </div> </div>
CSSはこんな感じ
.wp-block-my-note-plugin-note-block { background-color: #e8f2f9; border: solid 1px #63a4d2; border-radius: 3px; font-size: 14px; margin-bottom: 16px; } .wp-block-my-note-plugin-note-block__heading { background-color: #63a4d2; color: white; font-weight: bold; margin: 0; padding: 3px 10px; } .wp-block-my-note-plugin-note-block__content { padding: 8px 10px; } .wp-block-my-note-plugin-note-block__content p { margin: 0 0 5px; } .wp-block-my-note-plugin-note-block__content p:last-child { margin: 0; }
完成形はこんな感じです。
ブロックには自動的に wp-block-プラグイン名-ブロック名
というクラスが割り当てられるため、それを元にクラス名、スタイルを付与しています。
CSSファイルとJavaScriptファイルを作成
ブロックの作成に入ります。まずは必要なファイルを作りましょう。先ほど作った my-note-plugin
ディレクトリに note-block
ディレクトリを作って、
$ cd my-note-plugin $ mkdir note-block
style.css
を作って、先ほどのCSSをそのまま保存します。
もう一つ index.js
も作ります。ブロックの処理は基本的にこのファイルに書いていきます。
registerBlockType関数でブロック登録
ブロックは registerBlockType
関数で登録できます。
( function ( wp ) { var el = wp.element.createElement; var name = 'wp-block-my-note-plugin-note-block'; wp.blocks.registerBlockType( 'my-note-plugin/note-block', { title: '備考ブロック', category: 'common', attributes: { heading: { type: 'string', source: 'children', selector: 'p.' + name + '__heading', default: 'Note' }, content: { type: 'array', source: 'children', selector: 'p.' + name + '__content' } }, edit: createEditElement, save: createSaveElement } ); } )( window.wp );
1行目と27行目はグローバル環境を汚さないための記述です。
registerBlockType
関数の第一引数には プラグイン名/ブロック名
を指定します。
第二引数にはブロックの情報を指定します。title
はブロックの表示名。category
はブロックのカテゴリで、Gutenbergエディタではブロックがカテゴリごとに表示されるのでその時使われます。attributes
は一言で説明するのが難しいので興味があればこちらの記事を見てください。edit
と save
はそれぞれエディタ画面と実際の表示画面用にReact要素を出力する関数で、これから実装していきます。
edit関数とsave関数の実装
まずは edit
関数。
function createEditElement( props ) { return el( 'div', { className: name }, [ el( wp.editor.RichText, { tagName: 'p', className: name + '__heading', value: props.attributes.heading, onChange: function( heading ) { props.setAttributes( { heading: heading } ); } } ), el( wp.editor.RichText, { tagName: 'div', className: name + '__content', value: props.attributes.content, multiline: 'p', onChange: function( content ) { props.setAttributes( { content: content } ); } } ) ] ); }
編集可能フィールドを作るには wp.editor.RichText
コンポーネントを使います。今回はタイトルと本文の両方を編集できるようにしたいので2つの RichText
を使っています。
ここで使用している el
関数は実際は wp.element.createElement
関数で、さらに言えば React の createElement
関数とほぼ一緒で、React要素を返しています。
Reactでは createElement
関数はほぼ使わず JSX で記述することが多いので見る人が見れば常軌を逸した書き方になっています。JSXを使った書き方は別の記事にまとめているのでよければそちらもご覧ください。
次に save
関数。
function createSaveElement( props ) { return el( 'div', { }, [ el( wp.editor.RichText.Content, { tagName: 'p', className: name + '__heading', value: props.attributes.heading } ), el( wp.editor.RichText.Content, { tagName: 'div', className: name + '__content', value: props.attributes.content } ) ] ); }
edit
関数と似ていますが、save
関数では RichText
の中身を表示するために wp.editor.RichText.Content
を使用しています。イベントハンドラなどが必要ないのでコード量も少なめです。
最終的に index.js
は以下のようになります。
( function ( wp ) { var el = wp.element.createElement; var name = 'wp-block-my-note-plugin-note-block'; function createEditElement( props ) { return el( 'div', { className: name }, [ el( wp.editor.RichText, { tagName: 'p', className: name + '__heading', value: props.attributes.heading, onChange: function( heading ) { props.setAttributes( { heading: heading } ); } } ), el( wp.editor.RichText, { tagName: 'div', className: name + '__content', value: props.attributes.content, multiline: 'p', onChange: function( content ) { props.setAttributes( { content: content } ); } } ) ] ); } function createSaveElement( props ) { return el( 'div', { }, [ el( wp.editor.RichText.Content, { tagName: 'p', className: name + '__heading', value: props.attributes.heading } ), el( wp.editor.RichText.Content, { tagName: 'div', className: name + '__content', value: props.attributes.content } ) ] ); } wp.blocks.registerBlockType( 'my-note-plugin/note-block', { title: '備考ブロック', category: 'common', attributes: { heading: { type: 'string', source: 'children', selector: 'p.' + name + '__heading', default: 'Note' }, content: { type: 'array', source: 'children', selector: 'p.' + name + '__content' } }, edit: createEditElement, save: createSaveElement } ); } )( window.wp );
PHPの作成
PHP側の設定を行います。PHP側ではスクリプトファイルとスタイルファイルの登録と、ブロックの登録の2つを行います。処理は init
にフックさせます。
my-note-plugin.php
を編集します。
<?php /** * Plugin Name: My Note Plugin * Version: 0.1 */ add_action( 'init', function() { if ( ! function_exists( 'register_block_type' ) ) { return; } $dir = dirname( __FILE__ ); $index_js = 'note-block/index.js'; wp_register_script( 'note-block-block-editor', plugins_url( $index_js, __FILE__ ), array( 'wp-blocks', 'wp-element', ), filemtime( "$dir/$index_js" ) ); $style_css = 'note-block/style.css'; wp_register_style( 'note-block-block', plugins_url( $style_css, __FILE__ ), array(), filemtime( "$dir/$style_css" ) ); register_block_type( 'my-note-plugin/note-block', array( 'editor_script' => 'note-block-block-editor', 'style' => 'note-block-block', ) ); } );
wp_register_script
と wp_register_style
でスクリプトファイルとスタイルファイルの登録、register_block_type
でブロックにスクリプトとスタイルを紐づけています。
Gutenberg エディタで確認
ここまで行うと、画像のように Gutenberg エディタからブロックが追加できるようになっているはずです。
タイトルと本文、ともに編集できます。
記事表示画面でもちゃんと表示できます。
エディタ限定のスタイル
エディタ上ではタイトル部分の文字色が黒くなっていますが、これはGutenbergエディタ内の .edit-post-visual-editor p
に対してスタイルが設定されているためです。
これを解決するためには style.css
と同じ階層に editor.css
を作成し、以下の内容を記述します。
.edit-post-visual-editor .wp-block-my-note-plugin-note-block__heading { color: white; }
note-block.php
にも以下の記述を追加し、
$editor_css = 'note-block/editor.css'; wp_register_style( 'note-block-block-editor', plugins_url( $editor_css, __FILE__ ), array(), filemtime( "$dir/$editor_css" ) );
register_block_type
を修正します。
register_block_type( 'my-note-plugin/note-block', array( 'editor_script' => 'note-block-block-editor', 'editor_style' => 'note-block-block-editor', 'style' => 'note-block-block', ) );
白くなりました。
おわり
全体を理解しようと思ってスクラッチで書いて見ましたが、結構使い回しがきく部分が多いので WP-CLI のひな形から作った方が早いかもしれません。
あと今回は説明のためにエディタ用CSSファイルを作りましたが、この程度の差であれば style.css
に全てひっくるめてもいいと思います。