具体思路来源于官方文档Block Editor Handbook,中文名称暂定为“块编辑手册”。

wordpress官方文档《Block Editor Handbook 》

wordpress 5.0版本正式加入Gutenberg(古腾堡)编辑器,这个编辑器的特色是将所有的内容模块化,官方定义为”Block”。在实际使用时,用户会发现每一段文字都变成了一个模块,写文章的感觉和儿时堆积木的体验很接近。虽然这个编辑器刚出来的时候饱受争议,甚至到现在wordpress的商店里评分还是负数,但是我个人感觉这个编辑器才是未来网络编辑的方向,比起之前那个大型富文本输入框,这种编辑器可谓即优雅又实用。但这只是个开始,个人认为,能够有效的自定义模块,才是这个编辑器最有优势的地方。

关于这个编辑器,官方之前给了一个初步的文档,但是那个文档是以插件化为教程进行的,对于主题设计者而言,更希望在自己的主题里直接加入古腾堡自定义模块比较方便,因此本文的方向是在主题里直接往古腾堡编辑器里插入自定义模块。

加载

打开functions.php,直接加入方法

#-----------------------------------------------------------------#
# 加载古腾堡自定义模块
#-----------------------------------------------------------------#
function my_gutenberg_block(){
	//注册古腾堡编辑器
	wp_register_script( 'block-js', get_template_directory_uri() . '/src/blocks.js', array('wp-blocks', 'wp-element', 'wp-editor', 'wp-i18n'), '1.0.0' );
	//插入模块
	//fishtheme/block可自定义, 比如: demo/block
	register_block_type( 'fishtheme/block', array(
        'editor_script' => 'block-js'
    ) );
}
add_action( 'init', 'my_gutenberg_block' );

新建blocks.js

在主题的目录下,新建一个src的文件夹,并新建blocks.js
如果想自定义的话,注意把上面代码里的对应路径也改一下。

编辑blocks.js

这个是古腾堡核心文件,基本所有的功能都在这里。

//引入对应方法, 需要注意的是这里引用了4个方法, 那么在底部也需要window.wp.回调这4个方法
//这4个方法的来源是functions.php里的wp_register_script时array()里传入, 需要注意一一对应
(function (blocks, element, editor, i18n) {
    var el = element.createElement; //用于输出HTML
    var RichText = editor.RichText; //用于获取文本输入块

    blocks.registerBlockType('gutenberg-examples/example-03-editable', {
        title: '测试模块', //标题
        icon: 'universal-access-alt', //图标
        category: 'layout', //对应栏目
        attributes: { //模块的属性
            content: {
                type: 'array',
                source: 'children',
                selector: 'p',
            },
        },
        //编辑时
        edit: function (props) {
            //获取模块输入的值
            var content = props.attributes.content;
            //点击输入框时用的方法
            function onChangeContent(newContent) {
                //将输入框里的内容输出到模块属性里
                props.setAttributes({ content: newContent });
            }
            //返回HTML
            //el的方法格式为: el( 对象, 属性, 值 ); 可以相互嵌套
            //例如:
            // el(
            //     'div',
            //     {
            //         className: 'demo-class',
            //     },
            //     'DEMO数据'
            // );
            // 输出为: <div class="demo-class">DEMO数据</div>
            return el(
                RichText,
                {
                    tagName: 'p',
                    className: props.className,
                    onChange: onChangeContent,
                    value: content,
                }
            );
        },
        //保存时
        save: function (props) {
            //保存时返回的HTML
            return el(RichText.Content, {
                tagName: 'p', value: props.attributes.content,
            });
        },
    });
}(
    window.wp.blocks,
    window.wp.element,
    window.wp.editor,
    window.wp.i18n
));

返回编辑器

新建文章后,你就会看见一枚你自己定义的模块了。

后记

此为官网提供的DEMO,如果想更深一步的开发自己需要的复杂的模块,请直接参考文章开始的《Block Editor Handbook》。

另外再提供一个el布局上嵌套的例子:

return el(
    'div',
    {
        className: 'components-placeholder wp-block-embed'
    },
    el(
        'div',
        {
            className: 'components-placeholder__label'
        },
        el(
            'span',
            {
                className: 'editor-block-icon block-editor-block-icon has-colors'
            },
            el(
                'span',
                {
                    className: 'dashicons dashicons-universal-access-alt'
                }
            )
        ),
        el(
            'span',
            {},
            '测试'
        ),
    ),
    el(
        'div',
        {
            className: 'components-placeholder__fieldset'
        },
        el(
            'input',
            {
                className: 'components-placeholder__input',
                placeholder: '键入要在此嵌入的URL…',
                onChange: onChangeContent,
                value: 11
            },
        ),
        el(
            'button',
            {
                className: 'components-button is-button is-default is-large',
            },
            '嵌入'
        )
    )
);

此为古腾堡默认的嵌入样式,直接加在edit: function (props)里就能预览到了。