本稿ではいよいよGutenbergのブロックタイプについて学んでいこう。Gutenbergではカスタムブロックタイプを登録することができる。このブロックタイプにはいくつか種類があるのだが、まずは一番簡単な「見栄えに関する設定項目だけが存在するブロック」を作ってみよう。
なお、以前の記事ではじめてのカスタムブロックというものがあるのだが、重複するところが多いことをお断りしておく。とはいえ、半年以上前の記事であることと、JSXを採用している点を鑑みると、本稿から学ぶことも多いだろう。
成果物
成果物としては、次のようなアラートボックスを作成することを目指す。アラートボックスには次の2つの要素が存在する。
- スタイル。success, info, warning, dangerの4種類がある。
- メッセージ。これはリッチテキスト(HTML)として編集可能で、strongタグとaタグなどを挿入することができる。
なぜアラートボックスから始めるかというと、動的な要素が絡む場合、話は少し変わるからだ。「Before Gutenberg – ぼくのショートコードを守って」で紹介したような、ユーザーを指定する方法だと、難易度が上がるのである。
ブロックの登録
さて、まずはカスタムブロックcapitalp-block/alert
を登録しよう。ブロック名はスラッシュで区切られた名前空間をつけるのがマナーのようだ。この作業はPHPで行うので、適当なプラグインを作成してregister_block_type
を呼び出してほしい。
/** * Register scripts, css, and block. */ add_action( 'init', function() { $version = '1.0.0'; $base_url = plugin_dir_url( __FILE__ ); // Register alert's script. wp_register_script( 'capital-block-alert', $base_url . 'assets/js/alert.js', [ 'wp-blocks', 'wp-element' ], $version, true ); // Register block style. wp_register_style( 'capital-block-alert', $base_url . 'assets/css/alert.css', [], $version ); // Register block if gutenberg exists. if ( defined( 'GUTENBERG_VERSION' ) ) { register_block_type( 'capital-block/alert', [ 'editor_script' => 'capital-block-alert', 'editor_style' => 'capital-block-alert', ] ); } } );
editor_script
とeditor_style
がそれぞれJSとCSSを読み込んでくれる。なお、wp_regiser_sciprt
で依存関係に指定しているwp-blocks
とwp-element
は前者がブロック用のユーティリティ、後者がReactのエイリアスである。
CSSの内容については割愛する。alert
およびalert-success
といったBootstrap方式のクラスを指定すると上で紹介したようなアラートボックスになると考えてほしい。
それでは、肝心のJSの内容に入ろう。一気に貼り付けるので、順を追って中身を説明していく。ES6の文法に不安がある人は、前回の記事を復習しておいてほしい。
const { registerBlockType } = wp.blocks; const { RichText } = wp.editor; registerBlockType( 'capital-block/alert', { title: 'Alert', icon: 'info', category: 'widgets', attributes: { style: { type: 'string', default: 'info' }, content: { type: 'array', source: 'children', selector: 'p', }, }, edit( { attributes, setAttributes } ) { function onChange(event){ setAttributes({style: event.target.value}); } function onChangeContent(newContent){ setAttributes( { content: newContent } ); } return ( <div className={`alert alert-${attributes.style}`}> <select onChange={onChange}> <option value={'success'}>Success</option> <option value={'info'}>Info</option> <option value={'warning'}>Warning</option> <option value={'danger'}>Danger</option> </select> <RichText tagName="p" onChange={ onChangeContent } value={ attributes.content } /> </div> ) }, save( { attributes } ) { return ( <div className=> </div> <RichText.Content tagName="p" value={ attributes.content } /> ); } } );
まず最初のconst
ブロックは、利用するライブラリにわかりやすい名前をつけている。WordPressではwp
名前空間にすべてのライブラリが格納されていくので、それを以前紹介した分割代入でエイリアス(別名)にしいてる。
const { registerBlockType } = wp.blocks; const { RichText } = wp.editor;
続いて、registerBlockTypeメソッドを利用して、ブロックを登録している。さっきPHPで登録したから2回やらなくていいような気がするのだが、公式ドキュメントに書いてあるのだから仕方がない。次回以降で紹介するダイナミックブロックなどでは必要な処理になるのだろう。1番目にブロック名、2番目がオプションである。
registerBlockType( 'capital-block/alert', {} );
オプションの指定
さて、オプションのうち、簡単なものから見ていこう。
registerBlockType( 'capital-block/alert', { title: 'Alert', icon: 'info', category: 'widget', } );
まず、title
はそのまま、ブロックの名前である。ここは多言語対応できるのだが、それは次回以降で紹介する。続いてicon
であるが、これはdashiconsの接頭辞dashicons-
を除いたものを指定する。dashiconsにないものを指定したい場合はどうするのかというと、インラインでSVGを指定する。マジかという感じである。そしてカテゴリー。これはドキュメントにあるもののほか、フィルターフックで拡張できるようだ。この3つを指定すると、次のようなUIとして表現される。
属性
さて、それでは難しい方のオプションに移ろう。まずはattribures
から。これはブロックの属性値として保存されるものだ。HTMLの一部(たとえば、pタグ内のテキスト)として表現される場合と、コメントとして保持される値(たとえばショートコードの回で説明したユーザーID)がある。前者の場合は次のように指定する。
{ attributes: { content: { type: 'string', source: 'html', selector: 'p', } } }
この場合、ブロック内のp
タグの中身のHTMLがcontent
だよ、ということになる。ここでsource
を指定しなかった場合、属性値はコメントに保存される。
今回はstyle
とcontent
という2つの属性が必要なのでそのように登録した。
registerBlockType( 'capital-block/alert', { attributes: { style: { type: 'string', default: 'info' }, content: { type: 'array', source: 'children', selector: 'p', }, }, });
実は筆者もハマったのだが、content
の属性値がarray
になっているのに気づいただろうか。これはあとで紹介するビデオの中で触れているのだが、リッチテキスト(中でタグを利用可能なテキスト)の場合、「React.DOMの配列」と解釈されるため、配列にする必要があるらしい。rich-text
, text
, html
など色々試したが、複数のタグを利用する場合はarray
かつchildren
でなくてはならないようだ。
edit & save
それでは最難関であるedit
とsave
オプションへ移ろう。これはオプションというより、メソッドである。その名前とは異なり、edit
は編集用画面を描画するメソッド、save
は保存用のHTMLを描画するメソッドである。この2つが似通っていれば問題ないのだが、実際は少し異なる。それぞれ別にみていこう。
editメソッド
今回のアラートボックスはスタイルとコンテンツの2種類の属性を持つ。ちょっとかっこわるいのだが、スタイルはプルダウンで選択させ、コンテンツはリンクや強調を使うこともあると思われるのでリッチテキストとして編集できるようにしよう。
{ edit( { attributes, setAttributes } ) { function onChange(event){ setAttributes({style: event.target.value}); } function onChangeContent(newContent){ setAttributes( { content: newContent } ); } return ( <div className={`alert alert-${attributes.style}`}> <select onChange={onChange}> <option value={'success'}>Success</option> <option value={'info'}>Info</option> <option value={'warning'}>Warning</option> <option value={'danger'}>Danger</option> </select> <RichText tagName="p" onChange={ onChangeContent } value={ attributes.content } /> </div> ) }, }
まず、分割代入によって、ブロックのattributes
と属性を変更するsetAttributes
メソッドを引数にとる。Reactではコンポーネントのプロパティを変更するときに block.attribute = 'new_valeu'
と指定するだけではUIへの変更が伝播されず、必ずメソッドを経由する必要がある。
続いてプルダウンの変更とリッチテキストの変更を検知するメソッドを2つ用意し、それぞれにsetAttributes
を実行させる。
function onChange(event){ setAttributes({style: event.target.value}); } function onChangeContent(newContent){ setAttributes( { content: newContent } ); }
それから、JSXをリターンすることで、UIの描画が完了する。<RichText/>
という見慣れないタグはReactのコンポーネントで、Gutenbergに初めから備わっているものだ。これによってできる見栄えは次のようなものになる。
saveメソッド
ここでは保存すべきHTMLを描画する。もちろん、ショートコードで紹介したような、「ユーザーIDからアバターを表示する」といったことをしたければまた別の方法もあるのだが、今回は管理画面で作成したHTMLをそのままテーマ側でも表示してしまって問題ないように作っているので、edit
からプルダウンを除いたものを保存すればよいだろう。
{ save({attributes}) { return ( <div className={`alert alert-${attributes.style}`}> <RichText.Content tagName={'p'} value={attributes.content}/> </div> ); }, }
edit
との大きな違いとしては、RichText
がRichText.Content
になっていることぐらいだ。これにより、次のようなHTMLが保存されるようになる。
<!-- wp:capital-block/alert {"style":"warning"} --> <div class="wp-block-capital-block-alert alert alert-warning"><p>はじめてのアラートです。<strong>強調</strong>も使えるし、リンクも使えます。</p></div> <!-- /wp:capital-block/alert -->
CSSの読み込み
さて、以上でほとんど終わりなのだが、あとはCSSの読み込みだけだ、最初のPHPファイルにCSSの読み込み処理を書いて終わり。
// Load style. add_action( 'wp_enqueue_scripts', function() { wp_enqueue_style( 'capital-block-alert' ); } );
同じCSSで済めばそれはそれで嬉しいのだが、実際のところ、Gutenbergでは各ブロックに強い詳細度でスタイルが当たってしまっており、今回の例でも「管理画面では文字が黒、公開側では文字が白」という状態になっている。これを解決するためのアイデアもなくはないのだが、それは次回以降に譲ろう。ともあれ、CSSの読み込みがうまくいくと、次のようになる。
とりあえず、以上でカスタムブロック道の入り口に立ったと言えるだろう。それでは、有料会員向けに、以下のコンテンツをお届けする。
- コーディング動画
- ソースコードの全体
続きの 4% を読み、添付されたファイルにアクセスするには、Gumroadでライセンスキーを取得してください!
コメントを残す