はじめに
WordPressのブロックエディタで使える「ブロック」を自作する方法をまとめる😊
ゴール
✅最小構成のブロックが作れるようになる。
この記事で解決したいこと
✅ブロック開発がはじめての人でも、簡単なブロックが作れるようになる!
まず本記事で基礎を理解してから、詳細を読むとより理解が深まる😊
結論
✅ブロックを作るには「PHP」と「JavaScript」が必要
✅ブロックは「投稿編集ページ用の見た目(管理者が見るところ)」と「ユーザーが閲覧するページ用の見た目(ユーザーが見るところ)」の2つを定義する必要がある。
✅ReactのJSXを使うこともできる。(使わなくてもOKだが、JSXの方がコードを楽に書くことができる!)
前提知識
ブロックは2種類に分けられる
- 静的ブロック ・・・ 事前にアップした画像やテキストなど、内容が変化しないブロック
- 動的ブロック ・・・ 最新の投稿を表示するなど、動的に内容が変化するブロック
「JSXを使う開発」と「JSXを使わない開発」の2種類ある
JSXを使うと
⭕️コードが簡潔に書くことができる
❌環境構築やビルドが必要
JSXを使わないと
⭕️環境構築やビルドが不要
❌コードが複雑になる
JSXの有無によるコードの比較
✅具体的な違いは後で解説するが、JSXを使った方が簡潔なことが分かる!
JSXあり
import { registerBlockType } from '@wordpress/blocks';
registerBlockType(
"my-blocks/sample-block-jsx",
{
title: "サンプルブロック",
icon: "heart",
description: "これはテスト用のブロックです",
category: "common",
example: {},
// ✅JSXを使った書き方
edit: () => <h2>これはサンプルブロックです。(edit)</h2>,
save: () => <div>これはサンプルブロックです。(save)</div>
}
);
JSXなし
(function (blocks, element) {
var el = element.createElement;
blocks.registerBlockType(
"my-blocks/sample-block",
{
title: "サンプルブロック",
icon: "heart",
description: "これはテスト用のブロックです",
category: "common",
example: {},
// ✅JSXなし
edit: () =>
el(
"h2",
{},
[
"これはサンプルブロックです。(edit)",
]
),
save: () =>
el(
"div",
{},
[
"これはサンプルブロックです。(save)",
]
),
}
);
})(window.wp.blocks, window.wp.element);
ブロックの仕組みとReactとの関係
✅投稿編集画面でブロックを生成 = Reactのコンポーネントを使ってHTMLを生成
もう少し詳しくブロックの仕組みを解説
- 投稿編集ページでブロックを生成する = 裏側でHTMLを作っている
ブロックを生成すると裏側では以下のようなコードができている。
- ブロックを作るというのは、裏側で生成されるHTMLを事前に定義しておくこと。
この定義にReactのコンポーネントを使っている。
💡ブロックを登録するregisterBlockType
という関数は、言い換えると「コンポーネントを登録する関数」。
この関数はJSXを使わない場合でも使用するので、JSXの有無に関わらずReactの仕組みが内部で使われている。 - 投稿編集ページでブロックを生成するという操作は、裏側でReactのコンポーネントを使ってHTMLを作っているだけ。
参考サイト
最小構成のブロックを作る
必要な環境・知識
開発環境
- WordPressの開発環境
知識
- functions.phpを編集する知識
- JavaScriptの知識
- 【JSXを使って書く場合】Reactの基礎知識
筆者もReact未経験で最低限のコードを書くことができた😊
これから作るブロック
✅固定の文字を表示するだけのブロックを作る。
投稿編集ページ
サイトでの見え方
ブロックを作る流れ
2ステップでブロックを作ることができる😊
✅JavaScriptのblocks.registerBlockType( … )
でブロックを定義し、
✅PHPのenqueue_block_editor_assetsフックでJavaScriptを読み込む。
【ステップ1】JavaScriptのblocks.registerBlockType( … )
でブロックを定義
✅ブロックを挿入したとき、裏側でどのようなHTMLを生成するか定義する。
✅書き方は「JSXを使わないパターン」「JSXを使うパターン」の2種類がある。
また公式で紹介されているコードもJSXありのものが多く参考にしやすい。
【ステップ1 - JSXを使わないパターン】
ファイル構成
全体のファイル構成は以下のようになる。
wp-content
└─ themes
└─ SampleTheme //独自テーマのディレクトリ
├── functions.php // ✅JavaScriptを読み込む
├── index.php
├── ...
└─ js
└─ sample_block.js // ✅ブロックを登録
ブロックを定義するコード
js フォルダに以下のようなブロックを定義する JavaScript のファイルを作成する。
/js/sample_block.js
(function (blocks, element) {
var el = element.createElement; // React要素を作成するためのヘルパー関数
// ✅カスタムブロックの登録
blocks.registerBlockType(
"my-blocks/sample-block", // 任意の名前空間 / ブロック名
{
// ✅各種設定
title: "サンプルブロック", // タイトル(エディタ上で表示される)
icon: "heart", // アイコン(https://developer.wordpress.org/resource/dashicons/#heart から選べる)
description: "これはテスト用のブロックです", // 説明
category: "common", // カテゴリ(ブロックを選択するときの分類)
example: {}, // プレビューを表示する設定
// ✅投稿編集ページでの見え方:<h2 style="省略">これはサンプルブロックです。(edit)</h2>
edit: () =>
el(
// h2タグで囲む
"h2",
// h2タグの属性
{
style: {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
},
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
),
// ✅サイトに表示されるときの見え方:<div>これはサンプルブロックです。(save)</div>
save: () =>
el(
// divタグで囲む
"div",
// divタグの属性
{
style: { margin: "100px 0 100px 0" },
},
// divタグの中身
[
"これはサンプルブロックです。(save)",
]
),
}
);
})(window.wp.blocks, window.wp.element);
コードの解説
✅カスタムブロックの登録
// ✅カスタムブロックの登録
blocks.registerBlockType(
// 中略
)
registerBlockType
は独自のブロックを登録する関数。(Reactのコンポーネントの登録に相当する。)
✅各種設定
// ✅各種設定
title: "サンプルブロック", // タイトル(エディタ上で表示される)
icon: "heart", // アイコン(https://developer.wordpress.org/resource/dashicons/#heart から選べる)
description: "これはテスト用のブロックです", // 説明
category: "common", // カテゴリ(ブロックを選択するときの分類)
example: {}, // プレビューを表示する設定
registerBlockType
の第二引数。
ブロックの基本的な情報を設定している。
✅投稿編集ページでの見え方
// ✅投稿編集ページでの見え方:<h2 style="省略">これはサンプルブロックです。(edit)</h2>
edit: () =>
el(
// h2タグで囲む
"h2",
// h2タグの属性
{
style: {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
},
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
),
アロー関数ではなくfunction文で書き換えた場合
edit: function() {
return el(
// h2タグで囲む
"h2",
// h2タグの属性
{
style: {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
},
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
)
},
registerBlockType
の第二引数。
プロパティedit
は投稿編集ページでの見た目を定義するところ。
上記のようにel()
を使って書く。
https://www.webdesignleaves.com/pr/wp/wp_block_basic.html#h5_index_9
✅サイトに表示されるときの見え方
// ✅サイトに表示されるときの見え方:<div>これはサンプルブロックです。(save)</div>
save: () =>
el(
// divタグで囲む
"div",
// divタグの属性
{
style: { margin: "100px 0 100px 0" },
},
// divタグの中身
[
"これはサンプルブロックです。(save)",
]
),
アロー関数ではなくfunction文で書き換えた場合
save: function() {
return el(
// divタグで囲む
"div",
// divタグの属性
{
style: { margin: "100px 0 100px 0" },
},
// divタグの中身
[
"これはサンプルブロックです。(save)",
]
)
},
registerBlockType
の第二引数。
プロパティsave
はサイトでの見え方を定義するところ。
上記のようにel()
を使って書く。
https://www.webdesignleaves.com/pr/wp/wp_block_basic.html#h5_index_9
出力されるHTML
✅投稿編集ページ(edit)
<h2 style="background-color: rgba(255, 131, 0, 0.23); color: black; line-height: 200px; text-align: center; font-size: 20px; margin: 100px 0px; position: relative;">これはサンプルブロックです。(edit)</h2>
✅サイトでの表示(save)
<div style="margin:100px 0 100px 0" class="wp-block-my-blocks-sample-block">これはサンプルブロックです。(save)</div>
クラス名は
wp-block-名前空間-ブロック名
となる。※名前空間とブロック名とは、registerBlockTypeの第一引数の値のこと。
【ステップ1 - JSXを使うパターン】
✅JSXを使うと、edit と save が簡潔になる!
具体的にはel()
を使わずにHTMLっぽい直感的な書き方ができるようになる。
ブロックを定義するコード
JSXを使うとeditとsaveが簡潔になる!
import { registerBlockType } from '@wordpress/blocks';
const editorStyle = {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
};
const frontStyle = { margin: "100px 0 100px 0" };
registerBlockType(
"my-blocks/sample-block-jsx", // 任意の名前空間 / ブロック名
{
title: "サンプルブロック", // タイトル(エディタ上で表示される)
icon: "heart", // アイコン(https://developer.wordpress.org/resource/dashicons/#heart から選べる)
description: "これはテスト用のブロックです", // 説明
category: "common", // カテゴリ(ブロックを選択するときの分類)
example: {}, // プレビューを表示する設定
// ✅投稿編集ページでの見え方(JSXで記述)
edit: () => <h2 style={ editorStyle }>これはサンプルブロックです。(edit)</h2>,
// ✅サイトに表示されるときの見え方(JSXで記述)
save: () => <div style={ frontStyle }>これはサンプルブロックです。(save)</div>
}
);
JSXの有無の比較
✅投稿編集ページでの見え方
JSXなし
edit: () =>
el(
// h2タグで囲む
"h2",
// h2タグの属性
{
style: {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
},
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
),
JSXあり
const editorStyle = {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
};
// 中略
edit: () => <h2 style={ editorStyle }>これはサンプルブロックです。(edit)</h2>,
https://www.webdesignleaves.com/pr/wp/wp_block_basic_jsx.html#h4_index_9
✅サイトに表示されるときの見え方
JSXなし
save: () =>
el(
// divタグで囲む
"div",
// divタグの属性
{
style: { margin: "100px 0 100px 0" },
},
// divタグの中身
[
"これはサンプルブロックです。(save)",
]
),
JSXあり
const frontStyle = { margin: "100px 0 100px 0" };
// 中略
save: () => <div style={ frontStyle }>これはサンプルブロックです。(save)</div>
https://www.webdesignleaves.com/pr/wp/wp_block_basic_jsx.html#h4_index_9
出力されるHTML
「JSXを使わないパターン」と同じ
JSXを使うためには環境構築とビルドが必要
JSXを使えば簡潔に書くことができるのは分かった!
でもメリットだけではなく、環境構築とビルドが必要というデメリットもある。
https://www.webdesignleaves.com/pr/wp/wp_block_basic_jsx.html#h3_index_2
【ステップ2】PHPのenqueue_block_editor_assetsフックでこのJavaScriptを読み込む
✅先ほど書いたJavaScriptを読み込む。
functions.php
function add_sample_block() {
//ブロック用のスクリプトを登録し、出力用のキューに入れる
wp_enqueue_script(
'sample_block_script', //スクリプトを識別するためのハンドル名
get_stylesheet_directory_uri() . '/js/sample_block.js', //スクリプトの URL
array( 'wp-blocks', 'wp-element' ) //✅依存スクリプト
);
}
// ✅アクションフックに登録
add_action( 'enqueue_block_editor_assets', 'add_sample_block' );
✅依存スクリプト
今回はregisterBlockType や createElement を使用するため、 wp-blocks と wp-element が必要。
wp_enqueue_script(
'sample_block_script', //スクリプトを識別するためのハンドル名
get_stylesheet_directory_uri() . '/js/sample_block.js', //スクリプトの URL
array( 'wp-blocks', 'wp-element' ) //✅依存スクリプト
);
定義するブロックの内容に応じて必要な依存スクリプトを指定する必要がある。
https://www.webdesignleaves.com/pr/wp/wp_block_basic.html#h5_index_4
✅アクションフックに登録
ブロック用のスクリプトはenqueue_block_editor_assets
フックに登録する。
// ✅アクションフックに登録
add_action( 'enqueue_block_editor_assets', 'add_sample_block' );
※ブロックの定義(JavaScript)は投稿編集ページでのみ必要。
※投稿編集ページでブロックを生成したとき裏側ではHTMLが生成されており、ユーザーが閲覧するときは単純に保存されているHTMLが表示される仕組み。(ブロックは意識しなくていい)
ステップ1でJSXを使っている場合は一部を変数で書くことができる!
✅wp_enqueue_script
第三引数(依存スクリプト)に、ビルドで自動生成されるアセットファイル(〇〇.asset.php)の値を指定する。
✅wp_enqueue_script
第四引数(バージョン)に、ビルドで自動生成されるアセットファイル(〇〇.asset.php)の値を指定する。
function my_first_block_ads_jsx_enqueue() {
//✅アセットファイルをインクルードして変数に保存
$asset_file = include( get_theme_file_path('/my-blocks/build/wdl-block-01.asset.php'));
//ブロック用のスクリプトを登録し出力用のキューに入れる
wp_enqueue_script(
'my_first_block_ads_jsx-script', //スクリプトのハンドル名
get_stylesheet_directory_uri() . '/my-blocks/build/wdl-block-01.js', //スクリプトの URL
$asset_file['dependencies'], //✅依存スクリプトの配列
$asset_file['version'] //✅バージョン
);
}
//エディターでのみブロックのアセットをエンキューするためのフック
add_action( 'enqueue_block_editor_assets', 'my_first_block_ads_jsx_enqueue' );
アセットファイルについてはこちら
よく使いそうなカスタマイズ
自作ブロックにCSSを当てる
【方法1】JavaScriptの中に直接スタイルを書く
✅edit
やsave
の中で直接styleを指定できる。
JSXなしの場合
el()
の第二引数でstyleを指定すればOK!
(function (blocks, element) {
var el = element.createElement; // React要素を作成するためのヘルパー関数
blocks.registerBlockType(
"my-blocks/sample-block", // 任意の名前空間 / ブロック名
{
title: "サンプルブロック", // タイトル(エディタ上で表示される)
icon: "heart", // アイコン(https://developer.wordpress.org/resource/dashicons/#heart から選べる)
description: "これはテスト用のブロックです", // 説明
category: "common", // カテゴリ(ブロックを選択するときの分類)
example: {}, // プレビューを表示する設定
edit: () =>
el(
// h2タグで囲む
"h2",
// h2タグの属性
{
// ✅CSSを設定
style: {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
},
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
),
save: () =>
el(
// divタグで囲む
"div",
// divタグの属性
{
// ✅CSSを設定
style: { margin: "100px 0 100px 0" },
},
// divタグの中身
[
"これはサンプルブロックです。(save)",
]
),
}
);
})(window.wp.blocks, window.wp.element);
JSXありの場合
タグの中にsytleを指定すればOK!
import { registerBlockType } from '@wordpress/blocks';
// ✅CSSの内容を事前に定義
const editorStyle = {
backgroundColor: "#ff83003b",
color: "black",
lineHeight: "200px",
textAlign: "center",
fontSize: "20px",
margin: "100px 0 100px 0",
position: "relative",
};
const frontStyle = { margin: "100px 0 100px 0" };
registerBlockType(
"my-blocks/sample-block-jsx", // 任意の名前空間 / ブロック名
{
title: "サンプルブロック", // タイトル(エディタ上で表示される)
icon: "heart", // アイコン(https://developer.wordpress.org/resource/dashicons/#heart から選べる)
description: "これはテスト用のブロックです", // 説明
category: "common", // カテゴリ(ブロックを選択するときの分類)
example: {}, // プレビューを表示する設定
// ✅style属性にCSSを設定
edit: () => <h2 style={ editorStyle }>これはサンプルブロックです。(edit)</h2>,
save: () => <div style={ frontStyle }>これはサンプルブロックです。(save)</div>
}
);
backgroundColor: "#ff83003b",
のように キャメルケース かつ 区切りはカンマ にすること。
【方法2】フックを使ってCSSを読み込む
✅別途CSSファイルを用意し、functions.phpで読み込むこともできる。
ただしどのページでCSSが必要かによって使うフックが変わる。
フック名 | 動作するページ |
---|---|
enqueue_block_editor_assets | ・投稿編集ページ(管理画面) |
enqueue_block_assets | ・投稿編集ページ(管理画面) ・サイトでの表示(ユーザーが閲覧するページ) |
例:投稿編集ページ のみCSSを読み込む
✅フックは「enqueue_block_editor_assets」
functions.php
// 投稿編集ページ(管理画面) でのみCSSを読み込む
function add_sample_block() {
wp_enqueue_script(
'sample_block_css_editor',
get_stylesheet_directory_uri() . '/js/sample_block_editor.css'
);
}
add_action( 'enqueue_block_editor_assets', 'add_sample_block' );
例:投稿編集ページ +サイトでの表示 でCSSを読み込む
✅フックは「enqueue_block_assets」
functions.php
// 投稿編集ページ(管理画面) とフロントエンド(ユーザーが閲覧するページ)でCSSを読み込む
function add_sample_block() {
wp_enqueue_script(
'sample_block_css',
get_stylesheet_directory_uri() . '/js/sample_block.css'
);
}
add_action( 'enqueue_block_assets', 'add_sample_block' );
例:サイトでの表示 のみCSSを読み込む
✅フックは「enqueue_block_assets」
✅is_adminで条件分岐する
functions.php
// フロントエンド(ユーザーが閲覧するページ)でのみCSSを読み込む
function add_sample_block() {
//フロントのみに適用するので、!is_admin() の場合のみ読み込む
if(! is_admin()) {
wp_enqueue_script(
'sample_block_css',
get_stylesheet_directory_uri() . '/js/sample_block.css'
);
}
}
add_action( 'enqueue_block_assets', 'add_sample_block' );
【補足】CSSを書くときに使うクラス名はどのように指定する?
✅「投稿編集ページでの表示edit
」 や「サイトでの表示 save
」でクラス名を指定するだけ😊
- JSXを使わない場合
el()
の第二引数にclassName: “hoge”
のように指定する。
edit: () =>
el(
// h2タグで囲む
"h2",
// h2タグの属性
{
// ✅クラス名を指定
className: “hoge”
},
// h2タグの中身
[
"これはサンプルブロックです。(edit)",
]
),
- JSXを使う場合
JSXの中にclassName: “hoge”
のように指定する。
edit: () => <h2 className="hoge">これはサンプルブロックです。(edit)</h2>,
ブロックに任意のデータを持たせる
✅edit()
及び save()
で受け取りたいデータを attributes プロパティで定義することができる。
どのようなときに使う?
attributesはデータを保持するためのものなので、「ユーザーが何かしら入力するブロック」と合わせて使うことが多い!
使用イメージ
例:リッチテキストに入力した文字「あいうえお」を保存して、サイトに「あいうえお」を表示する。
コード
詳細を知りたい方はこちらを参照。
( function( blocks, element, blockEditor ) {
var el = element.createElement;
var RichText = blockEditor.RichText ;
blocks.registerBlockType(
'my-blocks/my-first-block-richtext',
{
title: 'リッチテキストのサンプルブロック',
icon: 'smiley',
category: 'layout',
example: {},
attributes: {
// ✅入力された値を保存するプロパティ「myText」を設定
myText: {
type: 'string',
default: ''
}
},
edit: function( props ) {
//プロパティ「myText」に値をセット
function onChangeContent( newText ) {
//myText の値を更新
props.setAttributes( { myText: newText } );
}
return el(
RichText,
{
//✅イベントハンドラを設定(入力値が変更されたとき、プロパティ「myText」にも値をセットする)
onChange: onChangeContent,
//投稿編集ページに再アクセスしたときに myText の値が表示されるようにする
value: props.attributes.myText
}
);
},
save: function( props ) {
return el(
//RichText のコンテンツを保存するために RichText.Content が必要
RichText.Content,
{
//子要素に myText の値を保存する
value: props.attributes.myText,
}
);
},
}
);
}(
window.wp.blocks,
window.wp.element,
window.wp.blockEditor
) );
どのようにコードを書く?
✅以下のような書き方が多い。
- プロパティを定義しておいて、
- 投稿編集ページで入力されたとき、プロパティに入力値をセットし、
- プロパティの値をサイトに表示する。
プロパティを定義
✅JavaScriptのregisterBlockType()
の第二引数でattributesを指定するだけでOK😊
例:プロパティ「myText」を定義する
(function (blocks, element) {
var el = element.createElement;
blocks.registerBlockType(
"my-blocks/sample-block",
{
title: "サンプルブロック",
icon: "heart",
// ✅プロパティ「myText」を定義
attributes: {
myText: {
type: 'string',
default: ''
}
},
edit: () => el("h2",{},["これはサンプルブロックです。(edit)"]),
save: () => el("div",{},["これはサンプルブロックです。(save)",]),
}
);
})(window.wp.blocks, window.wp.element);
プロパティに値をセット
✅edit関数またはsave関数の引数にprops
を付けて、
✅props.setAttributes({ 属性の名前: 属性の値 })
と書くと値をセットできる。
例:プロパティmyText
に”あいうえお”をセット
edit: function( props ) {
props.setAttributes({ myText: "あいうえお" });
}
ただし実際は上記のように固定の文字をセットすることは少ない。
ブロックに対して何かしら入力されたとき(onChangeハンドラー)、値をセットすることが多い。
例:リッチテキストのブロックに文字が入力されたとき、プロパティmyText
に入力値をセット
edit: function( props ) {
//プロパティ「myText」に値をセットするだけの関数
function onChangeContent( newText ) {
props.setAttributes( { myText: newText } );
}
return el(
RichText,
{
//✅イベントハンドラを設定(入力値が変更されたとき、プロパティ「myText」にも値をセットする)
onChange: onChangeContent,
// 省略
}
);
},
プロパティの値を取得
✅edit関数またはsave関数の引数にprops
を付けて、
✅props.attributes.属性の名前
と書くと取得できる。
例:プロパティmyText
の値を取得
save: function( props ) {
const hoge = props.attributes.myText;
}
【attributesの詳細を知りたい人向け】分かりやすい解説サイト
詳細を知りたい方は以下のサイトがおすすめ!
attributesの基礎
attributesの公式リファレンス
source と selector の解説(attributesの中の機能)
インスペクターを設定する
インスペクターとは投稿編集ページのブロックの設定ができるサイドバーのこと。
デフォルトでは質素だが、カスタマイズすることができる!
https://www.webdesignleaves.com/pr/wp/wp_block_basic_jsx.html#h3_index_32
ツールバーを設定する
ツールバーとは投稿編集ページでブロックを選択したときに表示されるバーのこと。
デフォルトでは質素だが、カスタマイズすることができる!
https://www.webdesignleaves.com/pr/wp/wp_block_basic_jsx.html#h3_index_33
トラブルシューティング
JavaScriptの処理がメインなので、上手く動かないときはディベロッパーツールを確認すればだいたい解決する。
参考サイト
WordPress公式の解説
入門的なサイト
基本的な仕組みの理解ができるサイト
もう少し詳しい仕組みが理解できるサイト
JSXを使う方法のサイト
いろいろな例が紹介されているサイト