最後の仕上げ

以上で JavaScript コードは期待どおりに動作するようになりました。ここからは将来の拡張ためにコードを簡素化し変更しやすくしていきます。

最初のステップとして関数 mapSelectToProps と mapDispatchToProps を無名関数にして、それぞれ withSelect と withData に直接渡します。

( function( wp ) {
    var registerPlugin = wp.plugins.registerPlugin;
    var PluginSidebar = wp.editPost.PluginSidebar;
    var el = wp.element.createElement;
    var Text = wp.components.TextControl;
    var withSelect = wp.data.withSelect;
    var withDispatch = wp.data.withDispatch;

    var MetaBlockField = function( props ) {
        return el( Text, {
            label: 'Meta Block Field',
            value: props.metaFieldValue,
            onChange: function( content ) {
                props.setMetaFieldValue( content );
            },
        } );
    }

    var MetaBlockFieldWithData = withSelect( function( select ) {
        return {
            metaFieldValue: select( 'core/editor' )
                .getEditedPostAttribute( 'meta' )
                [ 'sidebar_plugin_meta_block_field' ],
        }
    } )( MetaBlockField );

    var MetaBlockFieldWithDataAndActions = withDispatch(
        function( dispatch ) {
            return {
                setMetaFieldValue: function( value ) {
                    dispatch( 'core/editor' ).editPost(
                        { meta: { sidebar_plugin_meta_block_field: value } }
                    );
                }
            }
        }
    )( MetaBlockFieldWithData );

    registerPlugin( 'my-plugin-sidebar', {
        render: function() {
            return el( PluginSidebar,
                {
                    name: 'my-plugin-sidebar',
                    icon: 'admin-post',
                    title: 'My plugin sidebar',
                },
                el( 'div',
                    { className: 'plugin-sidebar-content' },
                    el( MetaBlockFieldWithDataAndActions )
                )
            );
        }
    } );
} )( window.wp );

次に MetaBlockFieldMetaBlockFieldWithDataMetaBlockFieldWithDataAndActions を1つの関数 MetaBlockField にマージし、 div 要素に渡します。@wordpress/compose パッケージから連結用の関数 compose が使用されています。忘れずに PHP スクリプトの依存配列に wp-compose を追加してください。

( function( wp ) {
    var registerPlugin = wp.plugins.registerPlugin;
    var PluginSidebar = wp.editPost.PluginSidebar;
    var el = wp.element.createElement;
    var Text = wp.components.TextControl;
    var withSelect = wp.data.withSelect;
    var withDispatch = wp.data.withDispatch;
    var compose = wp.compose.compose;

    var MetaBlockField = compose(
        withDispatch( function( dispatch ) {
            return {
                setMetaFieldValue: function( value ) {
                    dispatch( 'core/editor' ).editPost(
                        { meta: { sidebar_plugin_meta_block_field: value } }
                    );
                }
            }
        } ),
        withSelect( function( select ) {
            return {
                metaFieldValue: select( 'core/editor' )
                    .getEditedPostAttribute( 'meta' )
                    [ 'sidebar_plugin_meta_block_field' ],
            }
        } )
    )( function( props ) {
        return el( Text, {
            label: 'Meta Block Field',
            value: props.metaFieldValue,
            onChange: function( content ) {
                props.setMetaFieldValue( content );
            },
        } );
    } );

    registerPlugin( 'my-plugin-sidebar', {
        render: function() {
            return el( PluginSidebar,
                {
                    name: 'my-plugin-sidebar',
                    icon: 'admin-post',
                    title: 'My plugin sidebar',
                },
                el( 'div',
                    { className: 'plugin-sidebar-content' },
                    el( MetaBlockField )
                )
            );
        }
    } );
} )( window.wp );

最後にメタフィールド名 sidebar_plugin_meta_block_field を関数 withSelect と withDispatch から取り出し、1つの場所にまとめて将来の変更に備えます。withSelect と withDispatch 関数が第2引数として、メタフィールドをラップする UI コンポーネントの props を取るため、これを利用します。コード例を挙げます。

// ...
var MetaBlockFieldWithData = withSelect(
    function( select, props ) {
        console.log( props.metaFieldName );
    }
)( MetaBlockField );

// ...
    el(
        MetaBlockFieldWithData,
        { metaFieldName: 'sidebar_plugin_meta_block_field' }
    )
// ...

withSelect 内でどのように metaFieldName にアクセスできるかに注意してください。この利点を活かす形でコードを変更してみましょう。

( function( wp ) {
    var registerPlugin = wp.plugins.registerPlugin;
    var PluginSidebar = wp.editPost.PluginSidebar;
    var el = wp.element.createElement;
    var Text = wp.components.TextControl;
    var withSelect = wp.data.withSelect;
    var withDispatch = wp.data.withDispatch;
    var compose = wp.compose.compose;

    var MetaBlockField = compose(
        withDispatch( function( dispatch, props ) {
            return {
                setMetaFieldValue: function( value ) {
                    dispatch( 'core/editor' ).editPost(
                        { meta: { [ props.fieldName ]: value } }
                    );
                }
            }
        } ),
        withSelect( function( select, props ) {
            return {
                metaFieldValue: select( 'core/editor' )
                    .getEditedPostAttribute( 'meta' )
                    [ props.fieldName ],
            }
        } )
    )( function( props ) {
        return el( Text, {
            label: 'Meta Block Field',
            value: props.metaFieldValue,
            onChange: function( content ) {
                props.setMetaFieldValue( content );
            },
        } );
    } );

    registerPlugin( 'my-plugin-sidebar', {
        render: function() {
            return el( PluginSidebar,
                {
                    name: 'my-plugin-sidebar',
                    icon: 'admin-post',
                    title: 'My plugin sidebar',
                },
                el( 'div',
                    { className: 'plugin-sidebar-content' },
                    el( MetaBlockField,
                        { fieldName: 'sidebar_plugin_meta_block_field' }
                    )
                )
            );
        }
    } );
} )( window.wp );

以上でオリジナルのコードのコンパクトバージョンの完成です。ここからさらに機能を追加したり、他のチュートリアルを試したり、全く新しいブロックを作っていきましょう。

最終更新日: