Help us understand the problem. What is going on with this article?

Wordpress Gutenberg よく使いそうなコンポーネントまとめ

この記事は?

Wordpressの新エディタGutenbergをいじってて
よく使いそうだと思ったコンポーネントをまとめていきます
追記編集していきます

TextControl と TextareaControl

テキスト編集のコンポーネント。
onChangeでイベントオブジェクトじゃなく中身の文字列だけが渡されるようになってるので、値の取り出しとかしなくていいので普通にtextareaとか書いちゃうより楽です。

JSX
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にいます。

JSX
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を使うこともできます

CheckboxControl

チェックボックスのコンポーネント
多分一番使ってるコンポーネント
チェックボックスをポチポチするだけで
要素を入れたり消したりできるのはユーザー的に便利

JSX
const {RangeControl} = wp.components;

registerBlockType('myPlugin/myBlock',{
    edit({attributes,className,setAttributes}){
        return [
            <CheckboxControl
                label='真偽値'
                help={bool?'':''}
                onChange={(bool)=>{setAttributes({bool:bool});}}
                checked={bool}
            />
        ];
    }
);

RangeControl

スライダーで数値の入力できるコンポーネント
ユーザー入力を特定の範囲の数値に保証できるのがいいところ
こういうこと簡単にできるのは便利

JSX
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で大体わかります、大体だけ。
要は編集画面上で検索とかサーバーサイドの処理が絡むようなものをプレビューしながら編集できるわけです。
render_callbackとServerSideRenderを使ったブロックの仕組みはショートコードの後継となるものと思われます。
追記:フォームやスライダーなどリッチコンテンツの埋め込みの用途では確かにSSRは上位互換なのですが、ショートコードにはテキストの途中など好きな箇所に挿入できるという利点があり、単純に上位互換とは言えないです。

その場でプレビューできるってだけでなくパラメータの指定もドロップダウンとかトグルとかのUIで直感的に、タイポの心配なくできるので、ユーザーにとっては完全上位互換になるでしょう。

JSX
const {ServerSideRender} = wp.components;

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は大体セットで指定することになります。

こんな感じに

PHP
register_block_type('myPlugin/myBlock',[
    'render_callback'=>function($attr){
        return sprintf('<p class="%s">MyBlock</p>',$attr['className']);
    },
    'attributes=>[
        'className'=>['default'=>'myclass']
    ]
]);

InspectorControls と PanelBody

ブロックを選択した時に表示されるサイドバーのコンポーネント。
PanelBodyでtitleを指定すると折りたたみにできます。
サイドバーはまず基本この二つを使って作ることになるだろうと思います。

JSX
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

サイドバーの入力項目の入れ物になるコンポーネント。
オリジナルのコンポーネントに、基本コンポーネントと同様にラベルやヘルプをつけられます。

JSX
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

ブロックを入れ子にするためのコンポーネントです。
なんとなくコンテンツの構造を複雑にさせないためにブロックは入れ子にできるようにしないだろうと思ってたんですが、できるようにしたようです。

JSX
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

何も出力しないコンポーネント、複数のコンポーネントをまとめて
一つのコンポーネントとして扱いたいとかに使うやつ

BlockControls

ブロックを選択した時に左上に出てくるアイコン並んだやつ、あれを拡張するために使うやつ

BlockAlignmentToolbar

BlockControlsに入れて使う用、値はleft,center,rightで固定

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away