WordPressのGutenbergハンドブックに記述がみつからず、GitHubに載っている方法での実装を試した内容です。
注意点
- Gutenbergがコアに入る前の段階の記事です
- 書き方だけではなく、語句や名称にも問題がある可能性があります
- バッドノウハウな状態だと思いますので、読む方は参考程度に考えてください
- 私自身の書き方がまだ固まっていないためと参考にしたサンプルの都合上、当ブログ内のサンプルコードにはアロー関数の使用の有無などに表記揺れがあります
[追記 2018.11.8]
Gutenberg4.2.0よりカスタムHTMLに使われているCodeEditorがPlaneTextに変更されたため、当記事もPlaneTextに変更しました。これに伴い入力欄左にあった行数の表示やタグの色変更がなくなりました。
実現したいこと
- GutenbergでカスタムHTMLを追加する
- カスタムHTMLに初期値(任意のHTML)を入れる
「カスタムHTML」という名称のブロックに関してはハンドブックでは見当たりませんでしたが、GitHubの以下のページが該当するようです(ブロックのtitleにCustom HTMLという名称があっただけでした)。
コードをみると編集ではPlaneTextコンポーネントを使い、出力時にRawHTMLコンポーネントを使う仕組みの模様です。
以降のサンプルはサンプル1が上記の1を参照し、サンプル2は上記2を参照しつつ上記1で得た要素も取り入れています。
今回の問題点
根本的な問題として、これらのコードをそのまま使ってよいものかの判断が付きませんでした。
当初はRichTextのように簡単に使えるコンポーネントにされていると考えていて、それさえかけばGitHubに載っている記述そのままを記載する必要はないのではと思ったためです。
しかしながら調べても該当のものを出せるコンポーネントがわからず、当記事のような形となっています。
未発見、あるいは今後追加されるかもしれませんので、特に参考程度にご覧下さい。
サンプル 1
以下が「プレビュー機能も付いたカスタムHTML(=コードエディタ?)」のサンプルです。
一部使っていないコンポーネントがあるようですが何かの意図があって書かれているのではと思うため、ほぼGitHubのコードと同じです。そのため形を整える以外は、初期値の設置(コード内のコメント部分)を追加した程度です。
ButtonやwithStateなどの使い方の実例も見られるコードで参考になる点が多々ありました。
//初期設定
add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script(
'myplugin-gutenberge',
plugins_url( 'block.js', __FILE__ ),
[ 'wp-blocks', 'wp-element', 'wp-components', 'wp-i18n', 'wp-editor', 'wp-compose' ]
);
} );
const {
registerBlockType,
setDefaultBlockName,
setUnknownTypeHandlerName,
getPhrasingContentSchema
} = wp.blocks;
const { RawHTML } = wp.element
const { __ } = wp.i18n;
const { Disabled, SandBox} = wp.components;
const { BlockControls,PlainText } = wp.editor;
const { withState } = wp.compose;
registerBlockType( 'my-plugin/test-customhtml', {
title: 'test-customHTML',
icon: 'universal-access-alt',
category: 'layout',
supports: {
customClassName: false,
className: false,
html: false,
},
attributes: {
content: {
type: 'string',
source: 'html',
},
},
transforms: {
from: [
{
type: 'raw',
isMatch: ( node ) => node.nodeName === 'FIGURE' && !! node.querySelector( 'iframe' ),
schema: {
figure: {
require: [ 'iframe' ],
children: {
iframe: {
attributes: [ 'src', 'allowfullscreen', 'height', 'width' ],
},
figcaption: {
children: getPhrasingContentSchema(),
},
},
},
},
},
],
},
edit: withState( {
isPreview: false,
} )( ( { attributes, setAttributes, setState, isSelected, toggleSelection, isPreview } ) => (
//以下で初期値を設定。未入力時点ではattributes.contentがundefinedであるため、それを判定して値を入れる。
if(attributes.content == undefined){
setAttributes( { content: '<ul>\n\t<li>default HTML</li>\n</ul>' } );
}
<div className="wp-block-html">
<BlockControls>
<div className="components-toolbar">
<button
className={ `components-tab-button ${ ! isPreview ? 'is-active' : '' }` }
onClick={ () => setState( { isPreview: false } ) }
>
<span>HTML</span>
</button>
<button
className={ `components-tab-button ${ isPreview ? 'is-active' : '' }` }
onClick={ () => setState( { isPreview: true } ) }
>
<span>{ __( 'Preview' ) }</span>
</button>
</div>
</BlockControls>
<Disabled.Consumer>
{ ( isDisabled ) => (
( isPreview || isDisabled ) ? (
<SandBox html={ attributes.content } />
) : (
<PlainText
value={ attributes.content }
focus={ isSelected }
onFocus={ toggleSelection }
onChange={ ( content ) => setAttributes( { content } ) }
/>
)
) }
</Disabled.Consumer>
</div>
) ),
save( { attributes } ) {
return <RawHTML>{ attributes.content }</RawHTML>;
},
} );
まだあやふやな推測しかできない部分が多いのでコメント挿入版はありません。
サンプル 2
サンプル2はプレビュー機能がない簡易版のようなものかもしれません。
サンプル1に比べると機能的に劣る可能性がありますが(iframeとfigcaptionに対する設定がないなど)、用途がある程度限定されるならば使える可能性はありそうです。
なお、RawHTMLを使わない場合は、そのままCodeEditorとして利用可能です(HTMLが文字列のまま出力される)。
//初期設定
add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script(
'myplugin-gutenberge',
plugins_url( 'block.js', __FILE__ ),
[ 'wp-blocks', 'wp-element', 'wp-editor' ]
);
} );
const { registerBlockType } = wp.blocks;
const { RawHTML } = wp.element
const { PlainText } = wp.editor;
registerBlockType( 'my-plugin/test-codeeditor', {
title: 'test-codeeditor',
icon: 'universal-access-alt',
category: 'layout',
attributes: {
content: {
type: 'string',
default: '<ul>\n\t<li>default HTML</li>\n</ul>',
}
},
edit( { attributes, setAttributes } ) {
const { content } = attributes;
const onChangeContent = newContent => {
setAttributes( { content: newContent } );
};
return(
<div className="wp-block-html">
<PlainText
value={ attributes.content }
onChange={ onChangeContent }
/>
</div>
);
},
save( { attributes, className } ) {
const { content } = attributes;
return (
<div className={ className }>
<RawHTML>{content}</RawHTML>
</div>
);
},
} );
サンプル1との違い source
大きな記述内容の違い以外にも一点重要な部分があります。
supports: {
customClassName: false,
className: false,
html: false,
},
attributes: {
content: {
type: 'string',
source: 'html',
}
}
上記はサンプル1の一部ですが、save内でRawHTML(おそらく、渡された文字列ではなくHTMLとして出力させるコンポーネント)を使う場合に以下のような状態でした。
- attributesのsourceがhtmlで、supportsのhtmlがfalseではない
- saveのreturn時にRawHTMLを囲むようにdivなどを記述する
- 上記2点の場合、保存後の再表示(リロードなど)を行うと二重に外側のdivが出力されてブロックが壊れる
対して、以下がサンプル2の状態です。
attributes: {
content: {
type: 'string',
default: '<ul>\n\t<li>default HTML</li>\n</ul>',
}
},
sourceを指定しないことでサンプル1の記述がなくとも動作を確認しました。
supportsのhtml:falseとattributesのsource:htmlの役割と関係性が確認できず、これを書かない事による影響が把握できていませんが、少なくとも単にliとaタグなどを使ってもおかしな動作にはなりませんでした。
とはいえ懸念を感じる場合はサンプル1のほうを基本にしたほうが良いのかもしれません。
サンプル1との違い 初期値
サンプル1はwitStateで括られているためすぐにif文が動作する模様ですが、サンプル2は自動保存が走るタイミングで実行されるようで、同じ記述では初期値が入るまでにラグがでてしまいました。
そこで、サンプル2では以下のようにdefaultを使って試したところ、意図どうりの動作になりました。
attributes: {
content: {
type: 'string',
default: '<ul>\n<li>default HTML</li>\n</ul>',
}
},
関連記事
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への投稿など他サービスとの連動は一切ありません。