WordPress5から搭載された新エディタ「Guternberg」で採用されている「ブロック」という概念。
正直まだ慣れないことの方が多いですが、使いこなせるとかなーり便利だと思います。
というのも、標準で用意されているブロックだけでなく、好きなフォーマットでブロックを追加することができるんです。
そんな「カスタムブロック」の追加方法について、今回はまとめていこうと思います。
これからは投稿ページだけでなく、ウィジェット機能などもこの「ブロック」に置き換わっていくようですし、今のうちにカスタマイズ方法に慣れておきましょう!
参考になる教材
僕がカスタムブロックの追加方法について学ぶ際にお世話になった教材をまずは紹介しておこうと思います。
まず何より、公式ページです。
英語なので正直意味がわからない部分も多いですが、ここに紹介されているコードを実際に試していくことで、なんとなく理解が深まると思います。
また、ここのチュートリアルでのコードを実際にプラグイン化してくれたものがあります。
この中の01~05と番号のついたJSファイルを参考にすると良いと思います!
あとは、GutenbergはReactで動いているようなのでReactの基礎的なことを学習するのもいいかもしれません。
準備:カスタマイズ用のファイルを読み込む
ブロックエディタをカスタマイズするためのJSファイルとCSSファイルを読み込んでおきましょう。
'enqueue_block_editor_assets'というアクションフック で必要なファイルを読み込むことができます。
ブロックエディタカスタマイズ用のファイルを読み込む
function add_my_assets_to_block_editor() {
wp_enqueue_style( 'block-style', get_stylesheet_directory_uri() . '/assets/css/block_style.css' );
wp_enqueue_script( 'block-custom', get_stylesheet_directory_uri() . '/assets/js/block_custom.js',array(), "", true);
}
add_action( 'enqueue_block_editor_assets', 'add_my_assets_to_block_editor' );
以下、CSSやJSは上記のファイルに記述するものとします。
カスタムブロックを追加するコードの概要
カスタムブロックを追加するコードのざっくりとした構成をまずは紹介しておきます。
カスタムブロックを追加するコードの概要
(function () {
//使用するメソッド
var el = wp.element.createElement,
blocks = wp.blocks;
// カスタムブロックの追加
blocks.registerBlockType('名前空間/ブロックID', {
title: 'ブロックの表示名',
icon: 'Dashiconsからアイコンを指定できる',
category: '追加する場所(ブロックカテゴリー名)',
attributes: {
//このブロックで保持する変数データ
},
edit: function () {
// エディタでのこのブロックのHTMLソースをreturnする
},
save: function () {
// 実際に出力されるHTMLソースをreturnする
},
});
})();
wp.blocks.registerBlockType
というメソッドでカスタムブロックは追加できます。
冒頭でel
という変数に代入しているwp.element.createElemen
というメソッドでDOM要素を作成していきます。
ちなみに、wp.element.createElemen
はReact.createElement
のエイリアスです
また、複雑なカスタムブロックを扱いようになってくるとかなり重要になってくるのがattributes
でしょう。
PHPメインでやってるとかなり苦戦するかもしれませんが、これは個々のブロックが保持することのできる動的なデータです。
categoryについて
作成したカスタムブロックがどのカテゴリーに属するかをregisterBlockType
内のcategory
オプションにて指定できます。
どんなカテゴリーがあるのか?というのは以下の記事をご覧ください。
また、オリジナルのブロックカテゴリーを追加することも簡単です。
iconについて
Dashicons : Developer Resources で用意されているアイコン画像を指定することができます。
アイコン名がdashicons-hogehoge
のアイコンを使いたい場合はhogehoge
だけを指定します。
オリジナルアイコンの指定の仕方は、また後日調べておこうと思います。
カスタムブロックを追加してみる(基礎編)
では、簡単なカスタムブロックを追加してみましょう。
サンプル01(静的ブロック)
まずは動的なデータを持たない、静的なブロックを追加してみます。
サンプルブロック01を追加
(function () {
//使用するメソッド
var el = wp.element.createElement,
blocks = wp.blocks;
// カスタムブロックの追加
blocks.registerBlockType('my-plugin/sample-block01', {
title: 'サンプルブロック01',
icon: 'wordpress-alt',
category: 'layout',
edit: function () {
return el(
'div',
{
className: "example-1",
style: {
backgroundColor: '#900',
color: '#fff',
padding: '1em',
}
},
'エディタ側ではDIVタグだよ'
);
},
save: function () {
return el(
'p',
{
className: "example-1",
style: {
backgroundColor: '#008000',
color: '#fff',
padding: '1em',
}
},
'サイト表示側ではPタグだよ'
);
},
});
})();
上記のコードを保存したら、以下のように「サンプルブロック01」が追加されているはずです。
このブロックを選択すると、
このように背景が赤色のブロックが挿入されます。
動的データをもたせていないので、コンテンツの編集はできません。
保存してサイトの表示を確認してみましょう。
このように、エディタとは別の背景が緑色のブロックが出力されています。
Guternbergでは、エディタで表示されるHTMLと、実際に出力されるHTMLは別物!
ということが、このサンプル01ではわかっていただけたかと思います。
ブロックの出力をvar_dumpで確認
また、表示側の見た目は先ほど確認しましたが、出力内容も確認しておきましょう。
サンプルブロック01の出力内容
<!-- wp:my-plugin/sample-block01 -->
<p class="wp-block-my-plugin-sample-block01 example-1" style="background-color:#900;color:#fff;padding:1em">サイト表示側ではPタグ</p>
<!-- /wp:my-plugin/sample-block01 -->
また、ブロックごとに何やらコメントが付属していますね。
Guternbergでは、これらのコメントによって各ブロックの情報が保存されています。(今は静的ブロックなので、ブロック名くらいしか見えませんが)
el(wp.element.createElement)の使い方について
el('タグ名', {属性データ}, コンテンツ);
というのが基本になってきます。
先ほどのサンプル01での例
el(
'タグの名前',
{
className: クラス名
style: {スタイルの指定}
},
"表示するテキスト"
);
サンプル02(編集可能ブロック)
次は、コンテンツの内容を編集できるブロックを作成してみます。
(function () {
var el = wp.element.createElement,
blocks = wp.blocks,
RichText = wp.editor.RichText;
blocks.registerBlockType('my-plugin/sample-block02', {
title: 'サンプルブロック02',
icon: 'wordpress-alt',
category: 'layout',
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'div',
},
},
edit: function (props) {
var nowContent = props.attributes.content;
return el(
RichText,
{
tagName: 'div',
className: "sample2",
style: {
background: '#f7f7f7'
},
value: nowContent,
onChange: function (changedContent) {
props.setAttributes({ content: changedContent });
},
}
);
},
save: function (props) {
return el(RichText.Content, {
tagName: 'div',
className: "sample2",
style: {
background: '#f7f7f7'
},
value: props.attributes.content,
});
},
});
})();
上記のコードを保存したら、以下のように「サンプルブロック02」が追加されているはずです。
このブロックを選択すると、
このように、背景が薄いグレーの編集可能ブロックが挿入されます。
好きなようにテキストを入力して保存・確認してみてください。
編集可能なブロックを作成するためのポイント1 - RichText
サンプル01ではelメソッドの第一引数には直接タグ名を指定していました。
しかし、サンプル02では、edit側ではRichTexts
、save側ではRichText.Content
となっており、タグ名は第二引数のオブジェクトにて指定しています。(RichText = wp.editor.RichTextとしている点に注意)
wp.editor.RichTextを使用することで、編集可能なブロックが作成可能!
編集可能なブロックを作成するためのポイント2- データの保持
ただ、編集可能な状態にするだけではその内容が保存されません。
そのため、ブロックに入力されたテキストを保持するためのデータとして、attributes
にcontent
プロパティを定義して上げる必要があります。
以下で「contentという名前のデータを扱うよ」と宣言している
/* ... */
attributes{
content: {
type: 'array',
source: 'children',
selector: 'div', //save側でRichText.Contentとしてこのデータを使用する要素
},
},
/* ... */
このcontent
という名前は好きな名前で大丈夫です。
slector
では、このデータを使用する要素を指定します。
上記の例では'div'
とタグ名を指定していますが、クラス名で'.hoge'
のようにしてもOKです。
edit側の要素を指定するのかな?と思ったのですが、save側とタグを分けて検証したところ、save側の要素に対してselector
をしないといけないっぽいです。selector
で指定したタグがsave側のRichText.Content
のタグと一致していないとエラーとなることを確認しています。
また、type と source の組み合わせが'array'
と'children'
となっていますが、内部でタグを使いたい場合など、ReactのDOMの扱い的に配列で保存させておく必要があるみたいです。
(使ってみた感じ、単純なテキストデータなら'string'
と'html'
でも動作的には問題ないっぽかったですが...。)
ポイント3 - 保持したデータへのアクセス
edit側・save側の両方で、attributes
のプロパティにアクセスするためにはprops.attributes.プロパティ名
とします。
そして、elメソッドで作成する要素のvalue
プロパティには、このattributes
で保存されているデータをセットするようにします。
ポイント4 - onChangeで編集内容を保存する
エディター側でブロックに入力したテキストを随時props.attributes.content
と連携させるため、onChangeプロパティに編集内容を保存する処理を加えてあげます。
attributesのデータを保存するメソッド
props.setAttributes({ プロパティ名: 保存する値 });
おまけ1:attributesデータの中身を確認してみる
edit側で、以下のようにしてattributesデータを吐き出して見ると挙動が分かりやすいかと思います。
attributesの確認コード
console.log(props.attributes);
ブロックの中身が編集されるたび、データが出力され、contentプロパティの中身が変化していくのが分かると思います。
その他にも、右側設定パネル内の「追加 CSS クラス」などでクラスを追加してみると、className
というプロパティがattributesに追加されていく様子も見れると思います。
おまけ2:save側はこれでもOK
こんな使い方がいいのかは不明ですが、以下のようにしても問題なく入力した内容が出力されました。
save側のreturnでRichText.Contentを使わないバージョン
/* ... */
return el('div', {
className: "sample2",
style: {
background: '#f7f7f7'
},
},
props.attributes.content
);
/* ... */
サンプル03(multilineの指定)
最後に、リスト系のカスタムブロックを作成してみましょう。
olやulタグの子要素であるliタグは、複数挿入できないといけませんよね。
一つの親要素に対して同じタグの子要素を複数配置したい場合、edit側で作成する要素にmultilineプロパティを使用します。
サンプルコード03
(function () {
var el = wp.element.createElement,
blocks = wp.blocks,
RichText = wp.editor.RichText;
blocks.registerBlockType('my-plugin/sample-block03', {
title: 'サンプルブロック03',
icon: 'wordpress-alt',
category: 'layout',
attributes: {
content: {
type: 'array',
source: 'children',
selector: '.point_list',
},
},
edit: function (props) {
var content = props.attributes.content;
return el(
RichText,
{
tagName: 'ol',
multiline: 'li',
className: 'point_list',
value: content,
onChange: function (newContent) {
props.setAttributes({ content: newContent });
}
}
);
},
save: function (props) {
return el(RichText.Content, {
tagName: 'ol',
className: 'point_list',
value: props.attributes.content,
});
},
});
})();
上記のコードによって、以下のようなカスタムブロックが使用できるようになります。
おわりに
いかがだったでしょうか?
今回はかなり基本的なカスタムブロックだけを扱ってみましたが、まだまだいろんな使い方ができるので応用編も記事にしていこうと思います。
カスタムブロック機能が扱えるかどうかはこれからのWordPress開発において非常に重要になってくると思いますので、ぜひ今のうちから勉強しておきましょう!