之前为WordPress写了一个首行缩进插件[2em],主要是照顾国人书写习惯即段落的首行缩进。很久没用博客了没进行关注,最近一直收到WordPress邮件提示插件兼容问题,所以抽空更新了下该插件。

升级了下WordPress版本,发现新版富文本编辑器换成了Gutenberg(古腾堡),之前插件是基于TinyMCE,所以插件增加了对该新编辑器的支持。

效果如下:

老插件对 TinyMCE 的支持通过添加插件按钮和监听tab按键事件操作选中的富文本节点样式,新插件本来也想采用该方式,但是目前新插件开发文档和资料实在太少,暂时没有找到相关资料。目前采用为block块添加样式支持的方式进行实现。

官方文档很坑,上面提到的后台直接php代码注册样式(register_block_style)压根还没有更新,采用JS注册样式到paragraph块。

/**
 * Enqueue Gutenberg block assets for backend editor.
 */
function iw_2em_enqueue_block_editor_assets() {
	wp_enqueue_script( 'iw-2em-plugin-js', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-block-library' ) );
}
add_action( 'enqueue_block_editor_assets', 'iw_2em_enqueue_block_editor_assets' );

/**
 * 注册block 样式
 */
function iw_2em_enqueue_block_assets() {
	wp_enqueue_style( 'iw-2em-plugin-css',  plugins_url( 'res/css/index.css', __FILE__ ));
}
add_action( 'enqueue_block_assets', 'iw_2em_enqueue_block_assets' );
registerBlockStyle('core/paragraph', {
    name: 'iw-2em',
    label: '首行缩进'
});

为了方便操作,在paragraph操作栏上也增加一个缩进按钮,这里可以操作富文本块,增加对应的缩进样式,我们注册的样式名称为iw-2em,对应的class名称则是is-style-iw-2em

const {compose, ifCondition} = wp.compose;
const {registerFormatType} = wp.richText;
const {RichTextToolbarButton} = wp.blockEditor;
const {registerBlockStyle} = wp.blocks
const {withSelect} = wp.data;
const updateBlockAttributes = wp.data.dispatch('core/block-editor').updateBlockAttributes


const TextIndentButton = props => {
    const {selectedBlock} = props
    let isActive = selectedBlock.attributes.className === 'is-style-iw-2em'

    return <RichTextToolbarButton
        icon='align-right'
        title={isActive ? '取消首行缩进' : '首行缩进'}
        onClick={() => {
            updateBlockAttributes(selectedBlock.clientId, {
                className: isActive ? undefined : 'is-style-iw-2em'
            })
        }}
        isActive={isActive}
    />
};

const ConditionalButton = compose(
    withSelect(function (select) {
        return {
            selectedBlock: select('core/editor').getSelectedBlock()
        }
    }),
    ifCondition(function (props) {
        return (
            props.selectedBlock &&
            props.selectedBlock.name === 'core/paragraph'
        );
    })
)(TextIndentButton);

registerFormatType('iw-2em-format/text-indent', {
        title: '首行缩进',
        tagName: 'p',
        className: null,
        edit: ConditionalButton
    }
);