#この記事は?
Wordpressの新エディタGutenbergをいじってて
よく使いそうだと思ったコンポーネントをまとめていきます
追記編集していきます
TextControl と TextareaControl
テキスト編集のコンポーネント。
onChangeでイベントオブジェクトじゃなく中身の文字列だけが渡されるようになってるので、値の取り出しとかしなくていいので普通にtextareaとか書いちゃうより楽です。
const {TextControl, TextareaControl} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<TextControl
onChange={(newText1)=>setAttributes({text1: newText1});}
/>,
<TextareaControl
onChange={(newText2)=>setAttributes({text2: newText2});}
/>
];
}
);
RichText
ちょっとした文字装飾ができるテキスト編集のコンポーネント。
使い方は基本TextControlと同じなのだけどこいつはwp.componentsではなくwp.editorにいます。
const {RichText} = wp.editor;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<RichText
onChange={(newText)=>setAttributes({text: newText});}
/>
];
}
);
RichTextで各文字に適用できる文字スタイルは
registerFormatTypeで増やすことができます
以下smallを追加してみるコード
const {Fragment}=wp.element;
const {RichText,RichTextToolbarButton,RichTextShortcut} = wp.editor;
const {registerFormatType,toggleFormat}=wp.richText;
const {__}=wp.i18n;
registerFormatType('my/editor',{
title:'small',
tagName:'small',
className:null,
edit({isActive,value,onChange}){
const onToggle=()=>onChange(toggleFormat(value,{type:'catpow/small'}));
const icon=(
<svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true">
<path d="M5.6,16.7l3.6-9.4h1.3l3.8,9.4H13l-1.1-2.8H8l-1,2.8H5.6z M8.3,12.9h3.2l-1-2.6C10.2,9.5,10,8.9,9.9,8.4
C9.7,9,9.6,9.6,9.3,10.1L8.3,12.9z"/>
</svg>
);
return [
<Fragment>
<RichTextShortcut
type={'primary'}
character={'-'}
onUse={onToggle}
/>
<RichTextToolbarButton
icon={icon}
title={'small'}
onClick={onToggle}
isActive={isActive}
shortcutType={'primary'}
shortcutCharacter={'-'}
/>
</Fragment>
];
}
});
iconにはdash-iconの名前(リンク先で書かれてる名称の"dashicon-"より後ろ)で指定する他にSVGを使うこともできます
RichTextShortcutのtypeの指定はそれぞれ以下のように修飾キーに対応
Mac | Win | |
primary | [ COMMAND ] | [ CTRL ] |
---|---|---|
primaryShift | [ SHIFT, COMMAND ] | [ CTRL, SHIFT ] |
primaryAlt | [ ALT, COMMAND ] | [ CTRL, ALT ] |
secondary | [ SHIFT, ALT, COMMAND ] | [ CTRL, SHIFT, ALT ] |
access | [ CTRL, ALT ] | [ SHIFT, ALT ] |
ctrl | [ CTRL ] | [ CTRL ] |
alt | [ ALT ] | [ ALT ] |
ctrlShift | [ CTRL, SHIFT ] | [ CTRL, SHIFT ] |
shift | [ SHIFT ] | [ SHIFT ] |
shiftAlt | [ SHIFT, ALT ] | [ SHIFT, ALT ] |
RichTextの値はsaveでの出力の際には<RichText.Content value={value}/>
のようにして出力しなくてはなりません。WP5.4以前はTextControlとかと同じノリで{value}
と書いても解決してくれましたが、WP5.5以降はちゃんと書かなくてはいけなくなりました。
CheckboxControl
チェックボックスのコンポーネント
多分一番使ってるコンポーネント
チェックボックスをポチポチするだけで
要素を入れたり消したりできるのはユーザー的に便利
const {RangeControl} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<CheckboxControl
label='真偽値'
help={bool?'真':'偽'}
onChange={(bool)=>{setAttributes({bool:bool});}}
checked={bool}
/>
];
}
);
RangeControl
スライダーで数値の入力できるコンポーネント
ユーザー入力を特定の範囲の数値に保証できるのがいいところ
こういうこと簡単にできるのは便利
const {RangeControl} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<RangeControl
label='数値'
onChange={(number)=>{setAttributes({number:number});}}
value={number}
min={0}
max={12}
/>
];
}
);
ServerSideRender
php側のregister_block_typeでrender_callbackを指定して
サーバーサイドでレンダリングするように作られたブロックをプレビューするコンポーネント。
使い方とかは公式ハンドブックのCreating dynamic blocksで大体わかります、大体だけ。
要は編集画面上で検索とかサーバーサイドの処理が絡むようなものをプレビューしながら編集できるわけです。
フォームの埋め込みなどショートコードでやってたことをもっと直感的にできるようになるわけですが、だからと言ってショートコードの出番がなくなるわけでもありません。
ショートコードにはテキストの途中の任意の場所で使用できるという利点があります。
また、ショートコードはブロックのレンダリングより後に行われるので、ブロックにショートコードを含むコードを出力させることで、ショートコードを組み合わせたり再利用したブロックというのも実現します。
//const {ServerSideRender} = wp.components;
const {serverSideRender:ServerSideRender}=wp;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<ServerSideRender
block='myPlugin/myBlock'
attributes={attributes}
/>
];
}
);
注意点としてはattributesの設定をjs側ではなくphp側
つまりregister_block_typeのパラメータで指定しないと
サーバーサイドでエラーになってしまうこと
考えてみりゃ当たり前ですが、考えずにやってるとつまづきます、つまづきました。
ということでregister_block_typeでrender_callbackとattributesは大体セットで指定することになります。
こんな感じに
register_block_type('myPlugin/myBlock',[
'render_callback'=>function($attr){
return sprintf('<p class="%s">MyBlock</p>',$attr['className']);
},
'attributes'=>[
'className'=>['default'=>'myclass']
]
]);
2023/04/05追記
WordPress6.2からServerSideRenderの読み込み方が変わりました。
const {ServerSideRender} = wp.components; //6.1以前
↓
const {serverSideRender:ServerSideRender} = wp; //6.2以降
InspectorControls と PanelBody
ブロックを選択した時に表示されるサイドバーのコンポーネント。
PanelBodyでtitleを指定すると折りたたみにできます。
サイドバーはまず基本この二つを使って作ることになるだろうと思います。
const {InspectorControls} = wp.editor;
const {PanelBody} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<InspectorControls>
<PanelBody title="パネルのタイトル">
//ここにパネルの中身を書く
</PanelBody>
</InspectorControls>
];
}
);
PanelBodyは本来はPanelに入れてPanelHeaderと共に使うものっぽいんですが
正直Panelコンポーネントは見にくい使いにくいです、PanelBodyだけでいいです。
InspectorControlsってかなり使いそうなものなのに、公式ハンドブックにはBlock Controls: Toolbars and Inspectorのページで「InspectorControlsはHTMLモードでも表示されるからテキスト編集とかのは入れちゃダメだよ」という注意書きにしか登場してなくて、使い方とか全然書かれてません。
この情報が書かれていないハンドブックは不親切だと思います(切実)
BaseControl
サイドバーの入力項目の入れ物になるコンポーネント。
オリジナルのコンポーネントに、基本コンポーネントと同様にラベルやヘルプをつけられます。
const {InspectorControls} = wp.editor;
const {PanelBody, BaseControl} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<InspectorControls>
<PanelBody title="パネルのタイトル">
<BaseControl label="入力項目名" help="ヘルプ">
入力項目
</BaseControl>
</PanelBody>
</InspectorControls>
];
}
);
InnerBlocks
ブロックを入れ子にするためのコンポーネントです。
このコンポーネントは特に特別なブロックで、他のブロックとは処理されるフェーズが異なり、独特な制約が伴います。
const {InnerBlocks} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
return [
<InnerBlocks template={[['core/paragraph'],['core/image']]}/>,
];
},
save({attributes,className,setAttributes}){
return <InnerBlocks.Content/>
}
);
allowedBlocksで入れ子にできるブロックを制限しつつ自由に組み合わせ
templateで指定した固定の構造で組み合わせ
値やID与えるようになっていないため
一つのブロックにInnerBlocksは一つしか置けないです
また、saveはinnerBlocksを含む場合戻り値を配列にすることができません
saveは単一のコンポーネントを返す必要があります
この情報が書かれていないハンドブックは不親切だと思います(切実)
詳しい情報はGitHubで
また、innerBlocksを含むブロック、例えばcore/columnsなどは
registerBlockStyleするとクラッシュするという問題があります
これはサイドバーでスタイル適用のプレビューをするタイミングでは
必要なデータがinnerBlocksの場合は揃っていないのが原因
なので上記の回答の中にもあるように、innerBlocksを含むブロックタイプの場合は
中身が空のコンポーネントを返すようにしてクラッシュを回避するなどします
そのうち修正されるとは思いますが5.1.1ではまだ修正されてません
// core/columnsでregisterBlockStyleがエラーを起こすバグの回避
wp.hooks.addFilter(
'editor.BlockEdit',
'my/editor',
wp.compose.createHigherOrderComponent(function(BlockEdit){
return function(props){
var content=wp.element.createElement(BlockEdit,props);
if(props.name==='core/columns' && typeof props.insertBlocksAfter==='undefined'){
return <Fragment><div></div></Fragment>
}
return <Fragment>{content}</Fragment>;
};
},'allowColumnStyle')
);
Fragment
Reactでお馴染みの何も出力しないコンポーネント。
複数のコンポーネントをまとめて一つのコンポーネントとして扱いたいとかに使います。
また、Gutenbergはsaveの返すコンポーネントのclassName
に
wp-block-ブロック名
のクラスを自動的に補完する様になっているのですが
ブロックのクラスをattributesの方でコントロールしたい場合にこれが邪魔になります。
saveで返すコンポーネントを<Fragment>
でラップすることで
このクラス補完の処理を回避することができます。
registerBlockType('myPlugin/myBlock',{
save({attributes}){
return (
<Fragment>
<MyComponent className={attributes.classes}/>
</Fragment>
);
}
);
Block API version 2からwp-block-ブロック名
のクラスなど
Gutenbergが自動で付与していたプロパティは
useBlockProps
を使って明示的に付与しなければ付与されることはなくなりました
BlockControls と Toolbar
ブロックを選択した時に左上に出てくるツールバーを拡張するために使うコンポーネント。
const {BlockControls} = wp.blockEditor;
const {Toolbar} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
const {EditMode=false}=attributes;
return (
<BlockControls>
<Toolbar
controls={[
{
icon:'edit',
title:'編集モード',
isActive:EditMode,
onClick:() => setAttributes({EditMode:!EditMode})
}
]}
/>
</BlockControls>
);
}
);
BlockAlignmentToolbar
BlockControlsに入れて使うブロックのレイアウトを選択するツールバーです。
値はleft,center,rightで固定です。
const {BlockControls} = wp.blockEditor;
const {Toolbar} = wp.components;
registerBlockType('myPlugin/myBlock',{
edit({attributes,className,setAttributes}){
const {blockAlignment='left'}=attributes;
return (
<BlockControls>
<BlockAlignmentToolbar
value={blockAlignment}
controls={['left','center','right']}
onChange={(blockAlignment)=>{setAttributes({blockAlignment})} }
/>
</BlockControls>
);
}
);
PluginSidebar と PluginSidebarMoreMenuItem
記事編集時に右側に出てくるサイドバーを拡張するためのコンポーネント。
wp.blocks.registerBlockType
ではなくwp.plugins.registerPlugin
で使います。
PluginSidebar
が本体、PluginSidebarMoreMenuItem
でサイドバーの表示項目の設定に追加しないと表示する術がなくなってしまうので、PluginSidebar
とPluginSidebarMoreMenuItem
はいつもセットで使うことになるかと思います。
const {registerPlugin}=wp.plugins;
const {PluginSidebarMoreMenuItem,PluginSidebar}=wp.editPost;
const MySidebarPanelComponent = (props) => {
return [
<PluginSidebarMoreMenuItem target="MySidebarPanel">MySidebarPanel</PluginSidebarMoreMenuItem>,
<PluginSidebar
name="MySidebarPanel"
title="MySidebarPanel"
icon={edit}
>
<PanelBody title="MySidebarPanel" initialOpen={false}>
MySidebarPanel
</PanelBody>
</PluginSidebar>
];
};
registerPlugin('MySidebarPanelComponent', { render: MySidebarPanelComponent } );