WordPressのGutenbergに関する内容ですが、まだコアに入る前の段階で書いています。
コアに入った後やその後のアップデートでどう変わるかわからないため、その点は留意してください。
最初に
あくまで個人的な認識ですが、まずReactの基本的な部分を学んだ方が断然よいです。
Reactを学ばずとも簡単なものなら作れるため必須とは言い切れないのですが、何かしら実現したい機能を持ったブロックを独自に作りたいと思った時には必須となる可能性が高いでしょう。
個人的には以下の本が参考書として良かったです(比較できるほど読んでいないので最初にあたりを引いただけという感じですが)。
2017年の本なので最新ではありませんが、前半のさらに前半程度をみるだけでGutenbergでも必要なprops(やAttributes)のイメージがぼんやりながら掴めると思います。
Gutenbergに関する記事
この記事を含めて以下のように内容を分けて記述しています。
- [Gutenberg対応版]WordPressで複数のCSSをまとめてインラインCSSとして出力する
- @wordpress/create-blockで一つのプラグインに複数のブロックを入れる
- @wordpress/wp-env と @wordpress/create-block で簡単にブロック開発環境を作る
- 3度目のブロック開発環境(Docker Desktopとcreate-block)
- Gutenberg(ブロックエディタ)メモ [現在表示中]
- Gutenberg(ブロックエディタ)メモ -Gutenbergの使い方で迷うところ
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ1
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ2
- Buttonを使う(MediaUploadとRichTextも含む)
- metaデータを設定する
- Templatesとplaceholderを使う
- Toggleを使う
- カスタムHTMLを使う
- サイドバー(Inspector)を設定する
- サイドバーを作ってcheckboxを使う
- サイドバーを作ってラジオボタンを使う
- ショートコードの代替案的なブロックを作る
- ラジオボタンでクラスを変更可能なコードエディタブロックを作る
- 登録されているショートコードの一覧を表示したブロックを作る
- AddQuicktagのGutenberg対応に関して
- Classic Editorプラグインに関して
- wp_is_mobile関数を利用して出し分け機能をもったブロックを作る
- 任意のHTMLタグを範囲選択で挿入可能なツールバーを付ける
- 任意のHTMLタグを範囲選択で挿入可能なボタンをRichTextのツールバーに追加する
- 自動でテーマCSSの指定箇所をGutenberg用CSSとして用いる方法の検討
- 自動で出力されるブロック用のCSSを取除く
- Gutenberg関連の参考サイト:メモ
- WPのsetMeta()で複数のキーと値を保存する
- WPのブロックエディタでTypeError: Cannot read property ‘firstChild’ of nullのエラー:メモ
- WPのブロックエディタでUncaught Error: Minified React error #321のエラー:メモ
- WPのブロックエディタでタグをドロップダウンで変更する:メモ
- WPのブロックエディタでブロック追加用ボタンを表示させる:メモ
- WPのブロックエディタで親の値を子に設定する:メモ
- WPのブロック作成メモ
- WPの独自ブロックが設定されている時のみCSSやJSをフロントに表示する方法
- ブロック作成時のclassNameに関するメモ
- ブロック開発の環境構築におけるwp-scriptsとCreate Guten Blockのメモ
構造
Gutengergのブロックを作る上での基本的な構造に関して。
- ファイルと言語
-
管理画面で動かすJSファイルと、ブロックの登録やサーバー側での処理を行うPHPファイルの2種類。
JSに関しては、ハンドブック含めてReactのJSX記法とESNextで書かれることが多いため、最低限JSXをトランスパイルできる環境は必須に近いです。
PHPに関しては、Gutenberg専用の記述は多くないようなのでそれほど問題はないと思います。
- REST API
-
metaへのアクセスや書換えをGutenbergのブロックで行う場合にはREST APIが使われます。
functions.phpで無効化している場合は動作しないため、無効化を解除する必要があります。
- 作る際の形
-
基本的には、ローカルに開発環境を整えてプラグインの形で作る模様です。
プラグインではなくfunctions.phpやテーマ内のJSで対応することもできますが、趣旨的にもプラグインの方が良いように思います。
運用中のサイトでGutenbergプラグイン(WordPress5.0以降はコアにあるのでプラグインは不要)が有効なら、ローカルでコードを書いてサーバーにファイルをアップする方法でも作成は可能ですが、その場合でもReactの使用とBabelやWebpackを使ってトランスパイルできる環境が最低ラインとなる可能性が高く、いずれにせよGutenbergのブロック制作は環境構築からといえます。
- CSS
-
最終的にブラウザにページが出力される際には、CSSの記述(ブロック自体が持つ見映えに関連する記述)は全て外部CSSファイルにまとめられて、以下のような感じでhead内に出力されます。
<link rel="stylesheet" id="wp-core-blocks-css" href="'https://example.com/wp-includes/css/dist/block-library/style.min.css" type="text/css" media="all">
サイドバーで文字色や背景色を変更できるブロックもありますが、その場合はstyle属性で出力される可能性があります。
- CSS(投稿画面)
-
投稿画面に読み込ませるCSSは、上記ページを参考に以下のように記述することで自動でインライン出力されます。
add_action( 'after_setup_theme', 'nxw_setup_theme' ); function nxw_setup_theme() { add_theme_support( 'editor-styles' ); add_editor_style( get_stylesheet_directory_uri() . '/css/editor-style.css' ); }
( function() { window._wpLoadBlockEditor = new Promise( function( resolve ) { //省略 Styles that are reused verbatim in a few places\n *\/\nbody {\n font-family: \"Noto Serif\", serif;\n font-size: 16px;\n line-height: 1.8;\n color: #191e23; }\n\np {\n font-size: 16px;\n line-height: 1.8; }\n\nul,\nol {\n margin: 0;\n padding: 0; }\n\nul {\n list-style-type: disc; }\n\nol {\n list-style-type: decimal; }\n\nul ul,\nol ul {\n list-style-type: circle; }\n\n.mce-content-body {\n line-height: 1.8; }\n"},{"css":"body { font-family: 'Noto Serif JP' }"},{"css":"@charset \"UTF-8\"; h2 { margin-top: 30px; margin-bottom: 20px; padding: 10px; color: #32c1c1;} //省略 , null ) ); } ); } ); } )();
上記下部の.post h2のあたりが投稿画面用CSSの中身ですが、ここが自動で以下のように変換されます。ソースを見てもわかりませんが、開発者ツールで該当箇所を指定すれば確認できます。
.editor-styles-wrapper h2{ margin-top: 30px; margin-bottom: 20px; padding: 10px; color: #32c1c1;}
bodyは自動で.editor-styles-wrapperに置換してくれますが、独自のクラスでは以下のような問題が発生する可能性があります。
<!-- オリジナル --> .single h2{ color: red;} .post h2{ color: red;} <!-- Gutenbergによる置換後 --> .editor-styles-wrapper .single h2{ color: red;} .editor-styles-wrapper .post h2{ color: red;}
壊れた指定記述部分の確認方法がわからなかっため実際には上記と違うかもしれませんが、少なくとも意図した箇所にCSSは反映されませんでした。
補足
ハンドブックや他サイトにも載っていることと重複しますが、当初悩んだ点を元に記載。
- registerBlockTypeの名称
-
registerBlockTypeに設置する名称に関しては、ハンドブックに記載された以下の通り。
The name for a block is a unique string that identifies a block. Names have to be structured as namespace/block-name, where namespace is the name of your plugin or theme.
-
/(スラッシュ)は必須で、前半がnamespace、後半がblock-nameの役割を持っています。プラグイン前提の記述なので、namespaceはプラグイン名にするのがわかりやすいです。
この名称はサーバーでの処理と連動させる場合にも使うため、重要な部分でもあります。
// Registering my block with a unique name registerBlockType( 'my-plugin/book', {} );
- アイコン
-
blocks.registerBlockTypeのiconで指定可能なアイコンは、以下のWordPress管理画面で使えるアイコンから選べます。
なお、記述する際にはdashicons-は不要です。
dashicons-buildingであればbuildingだけにします。
- attributes
-
以下のページが項目に触れているので引用。
・title(必須): ブロックのinserter上に表示する名前
・category(必須): inserter上の分類。common formatting layout widgets embedのいずれか
・icon: ブロックのアイコン WordPressのDashiconsの名前を指定するか、独自のsvg要素を指定する
・keywords: 検索時のキーワード
・attributes: ブロックが使用する構造化されたデータ
・transforms: 説明なし。WIPらしい
・useOnce: 記事ごとに1個だけしか使えない場合はtrueにする
・supports: サポート機能を拡張する設定
・anchor(default: false): ページ内リンクできるようにする
・customClassName(default: true): ブロックのラッパー要素にブロック独自のクラス名をつける
・className(default: true): .wp-block-bour-block-name という形式のクラスをつけるか
・supportHTML(default: true): HTMLモードで編集可能か -
attributesは重要な設定で、ここに記載することで簡易にedtiとsaveに同じ値を設定できるようになります。not definedなどのエラーが出る場合には、attributesの設定が抜けていたりスペルミスである場合をまず疑うと初歩的なミスが減ります。
遭遇したエラーなどの問題
以下は遭遇したエラーなどのメモ書き。
「更新に失敗しました」
- [起きた問題]
公開や更新を押した際に「更新に失敗しました」のエラーが表示される - [原因]
カスタムフィールドと連動させていたPHPファイルに、投稿画面内にechoする記述があったため。 - [解決策]
echoを消す
独自に追加したカスタムフィールドへの入力内容に連動して、記事の公開時と更新時に動作するPHPコードを自作していましたが、Gutenbergに変えると公開や更新を押した際に「更新に失敗しました」のエラーが表示されました。
データ自体は保存されていて、公開や更新もされる模様ですが、投稿画面上ではエラーが出ているという状態。
PHPやJSのエラー表示が確認できなかったため、問題の箇所を特定する手がかりがありませんでした。
別サイトに同手法で追加したカスタムフィールドがあったのでそちらで確認すると問題はありませんでした。
そのためカスタムフィールの内容や追加方法は原因から除外。
連動したPHPファイルの方を疑い、消去法で箇所を特定しました。内容的に疑わしいのがechoでした。
今回は問題の箇所がほぼ使っていない箇所だったため、echoを含めた関連部位を丸ごと削除することで解決しました。
投稿画面を開いたままだとエラーが出る
投稿画面を開いたまま長時間放置しておくと自動保存や更新ができない場合があります。
この時に開発者ツールを開いていれば以下のようなエラーが確認できると思います。
/wp-json/wp/v2/posts/875/autosaves?_locale=user 400 ()
/wp-admin/post.php?post=875&action=edit&meta-box-loader=1&_wpnonce=〇〇&_locale=user 403 ()
保存が出来なくなってはいますがこうなる前の段階で自動保存が完了している可能性が高く、ほとんどの場合は一旦別ページを開くかリロードしてしまえば問題はでないはずです。
サンプルが動かない
- [起きた問題]
ハンドブック以外のページに記載されたサンプルが動かない - [原因]
参考にされた記述が古いため、削除された要素やパスが変更された可能性がある - [解決策]
ハンドブックで類似のサンプルを探すか、GitHubなどでremoveを確認したら今現在の書き方を探す
海外含めていくつかのサンプルコードが見つかりますが、そのままではエラーになる場合がよくあります。
理由はいくつも考えられますが、その内に1つに「そのコードが古く、現在は使えない記述である」という原因もあります。
ハンドブックではどこがどうかわったのかわからないので、GitHubの方を確認したり類似のコードを探し探すなど調査する必要があります。
classやfunctionが未定義
開発者ツールで以下のようなエラーがでる場合があります。
react-dom.min.82e21c65.js:110 Error: Minified React error #130; visit…
上記のvisitの後に続くURLにアクセスすると、reactjs.orgのページでもう少し具体的なエラーメッセージが確認できます。
このページでは以下のような記述がでると思います。
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
何らかのサンプルコードを試している時にこれが出た場合は、呼び出しのコンポーネントが違う可能性が高いです(2018.5以前あたりに公開された記事を参考にすると発生率が高い)。
例えば、wp.editorから呼ぶはずのRichTextをwp.blocksと書いている場合などです。
比較的調べやすい部分なので、とりあえず記述されているコンポーネントでそのまま検索すると簡単に解決できるかもしれません。
Babel6以降のパッケージやプラグイン
参考にする記事が古い(といってもタイミングによっては1年前どころか月単位のズレで起こるのですが…)と使うパッケージやプラグインが別のものに統合や置き換わっている場合がわりとあります。
npm insrtall後に一応教えてくれるますが、今回見つけたものを以下に記載しておきます。
旧 | 新 | 補足 |
---|---|---|
babel-preset-es2105 | babel-preset-env | ※1 |
babili | babel-preset-minify | ※2 |
※1 babel-preset-env
※2 babel-preset-minify
npm install時のWRANは以下のようになっている。
npm WARN deprecated babili@0.1.4: babili has been renamed to babel-minify. Please update to babel-minify
npm WARN deprecated babel-preset-babili@0.1.4: babili has been renamed to babel-minify. Please update to babel-preset-minify
webpackのエラー
本筋とは関係ありませんが、トランスパイルとファイルの結合に使うのでwebpackでつまづいた点に付いて。
babel(babel-core)は6でwebpackを使いimportのあるファイルでビルドすると、以下のようなエラーがでます(パスや関数名はそれぞれの環境によります)。
ERROR in ./src/index.js
Module not found: Error: Can’t resolve ‘関数名’ in ‘/src’
resolve ‘関数名’ in ‘/src’
色々弄り回すと以下のようなエラーにもなりました(経緯をメモっていなかったので少々あやふやです)。
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
ReferenceError: [BABEL] /src/index.js: Using removed Babel 5 option: foreign.modules – Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules
Babel5以前の古い書き方は止めて、pluginsオプションを使えという意味だと思いますが、その時にはまだプラグインを一切記述していなかったので、書けといわれても書く内容がありませんでした。
その後検索で以下のページを発見。
状況が少し違いますが、presetsのes2015に"modules": falseを記載したらという解決策が提示されていました。
今回はbabel-preset-es2105は使っていませんが、babel-preset-envは設定したので、.babelrcに以下を記載して解決できました。
{
"presets": [
['env', {modules: false}]
]
}
なお、webpack.config.jsにpresetsを記載すると"modules": falseのない記述状態でも動作しますが、この場合は.babeircが存在しないことが条件でした。
逆に言えば、.babelrcを作成していない状態では問題なく動作したのに、.babelrcを追加した途端にエラーがでるのであれば、上記のような問題が起きている可能性がありえます。
webpackでES5にした際のJSの状態
調べ方が悪いのかあまり目にすることができなかったので、webpackでES5にトランスパイルされた際のJSの状態を一応以下に記載。
importとexportを試したかったので、index.jsとblock/sample.jsという2つを以下のように適当に作成したとします。
//index.js
import sample from './blocks/sample.js';
console.log(sample());
//block/sample.js
const name = '佐藤';
export default function() {
return `私は${name}だ。`;
}
これをwebpack v4でBabel6のbabel-preset-envを通してminifyせずにトランスパイルすると以下のようになります。
関連記事
Gutenberg(ブロックエディタ)に関連する記事一覧。
- [Gutenberg対応版]WordPressで複数のCSSをまとめてインラインCSSとして出力する
- @wordpress/create-blockで一つのプラグインに複数のブロックを入れる
- @wordpress/wp-env と @wordpress/create-block で簡単にブロック開発環境を作る
- 3度目のブロック開発環境(Docker Desktopとcreate-block)
- Gutenberg(ブロックエディタ)メモ [現在表示中]
- Gutenberg(ブロックエディタ)メモ -Gutenbergの使い方で迷うところ
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ1
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ2
- Buttonを使う(MediaUploadとRichTextも含む)
- metaデータを設定する
- Templatesとplaceholderを使う
- Toggleを使う
- カスタムHTMLを使う
- サイドバー(Inspector)を設定する
- サイドバーを作ってcheckboxを使う
- サイドバーを作ってラジオボタンを使う
- ショートコードの代替案的なブロックを作る
- ラジオボタンでクラスを変更可能なコードエディタブロックを作る
- 登録されているショートコードの一覧を表示したブロックを作る
- AddQuicktagのGutenberg対応に関して
- Classic Editorプラグインに関して
- wp_is_mobile関数を利用して出し分け機能をもったブロックを作る
- 任意のHTMLタグを範囲選択で挿入可能なツールバーを付ける
- 任意のHTMLタグを範囲選択で挿入可能なボタンをRichTextのツールバーに追加する
- 自動でテーマCSSの指定箇所をGutenberg用CSSとして用いる方法の検討
- 自動で出力されるブロック用のCSSを取除く
- Gutenberg関連の参考サイト:メモ
- WPのsetMeta()で複数のキーと値を保存する
- WPのブロックエディタでTypeError: Cannot read property ‘firstChild’ of nullのエラー:メモ
- WPのブロックエディタでUncaught Error: Minified React error #321のエラー:メモ
- WPのブロックエディタでタグをドロップダウンで変更する:メモ
- WPのブロックエディタでブロック追加用ボタンを表示させる:メモ
- WPのブロックエディタで親の値を子に設定する:メモ
- WPのブロック作成メモ
- WPの独自ブロックが設定されている時のみCSSやJSをフロントに表示する方法
- ブロック作成時のclassNameに関するメモ
- ブロック開発の環境構築におけるwp-scriptsとCreate Guten Blockのメモ
1人がこの記事を評価
役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。
連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。