> 技术文档 > 【Word Press基础】创建一个动态的自定义区块

【Word Press基础】创建一个动态的自定义区块

书接上文:【Word Press基础】创建一个自定义区块,上篇博客创建了一个自定义区块。但这个区块的展示效果都没有处理,肯定没有办法实现项目的需求。因此这篇文章将带领大家实现一个动态的自定义区块。

一、修改编辑器中展示的内容

打开src/ht-note/edit.js,这个复杂(并非复杂)的文件就是编辑器中展示的内容了。我们可以在文章/页面的编辑器中创建一个我们的自定义区块,创建完成后记得保存一下草稿:

【Word Press基础】创建一个动态的自定义区块

这就是默认的效果了。一个静态的文字。我们的目标就是先写一个静态的投票区块。我们的区块应当包括:

  1. 一个富文本编辑器。管理员可以编写内容
  2. 一个投票按钮。用户能够进行投票
  3. 适当的动画、样式

1、创建一个被word press管理的盒子

如果打开一个word press的网站,可以看到每个段落都有默认的样式、行为。我们的插件当然也不应该例外。{ ...useBlockProps() }方法就能简单的创建一个能被word press管理的盒子。

打开edit.js并修改Edit()方法:

export default function Edit() { return ( <> <div { ...useBlockProps() }> <p>自定义的区块</p> <div>自定义的按钮</div> </div> </> );}

保存并刷新界面。

【Word Press基础】创建一个动态的自定义区块

修改成功。

2、添加富文本编辑器

简易的富文本编辑器能够使用控件直接引用。包括了文本样式、上下角标、图文混排等。

使用Rich Text

富文本编辑器可以自定义的设置一些内容。详细可以看官方文档。这里先规定了占位符。

修改edit()方法,注意引用Rich Text依赖

export default function Edit() { return ( <> <div { ...useBlockProps() }> <RichText placeholder=\'输入你的内容...\'> </RichText> <div>自定义的按钮</div> </div> </> );}

保存并刷新,上方内容便是富文本了:

【Word Press基础】创建一个动态的自定义区块

3、保存富文本内容

可惜,富文本的内容并没能保存在任何地方,当保存后再次刷新内容就会消失。因此我们首先应当有一个保存富文本的地方。

建立变量

打开block.json并添加attributes字段。attributes字段中加入我们需要保存的变量名称和一些基本的配置(本篇博客以note-content)举例:

{ \"$schema\": \"https://schemas.wp.org/trunk/block.json\", \"apiVersion\": 3, \"name\": \"ht/ht-note\", \"version\": \"v1.0.0\", \"title\": \"自定义投票\", \"category\": \"widgets\", \"icon\": \"smiley\", \"description\": \"创建一个自定义投票区块\", \"example\": {}, \"supports\": { \"html\": false }, \"textdomain\": \"自定义投票区块\", \"editorScript\": \"file:./index.js\", \"editorStyle\": \"file:./index.css\", \"style\": \"file:./style-index.css\", \"render\": \"file:./render.php\", \"viewScript\": \"file:./view.js\", \"attributes\": { \"note-content\": { \"type\": \"string\" } }}

使用变量

重新回到edit()方法。传递{attributes, setAttributes}参数使方法支持读取自定义的变量。

另外,也需要为Rich Text添加回调事件。每当内容改变时,将内容同步在变量中。当然了,如果变量有内容,也应当同步进来。修改完成后记得刷新界面:

export default function Edit({ attributes, setAttributes }) { return ( <> <div { ...useBlockProps() }> <RichText onChange={ (value) => setAttributes({ content: value })} value={attributes.content} placeholder=\'输入你的内容...\'tagName=\"div\" > </RichText> <div>自定义的按钮</div> </div> </> );}

这里的tagName=\"div\"RichText标签以div的格式进行保存。

保存内容

通过以上步骤,确实同步了变量了,可是当保存刷新后,内容依然没能保存。是因为note-content变量没能保存。

即:

  1. 修改了内容,变量被修改
  2. 编辑后,内容同步至note-content。note-content被修改
  3. 保存后,note-content并没能保存。

也就是说note-content依然没有改变,这个区块还是一个静态的区块。因此,我们应当额外处理一下变量的保存。

src目录下新建save.js并将edit中部分代码复制到文件中,并改名为save()方法。如下所示:

import { useBlockProps } from \'@wordpress/block-editor\';export default function save({ attributes }) { const { noteContent } = attributes; return ( <div { ...useBlockProps.save() }> { noteContent } </div> <div>自定义的按钮</div> );}

并且编辑index.js并修改registerBlockType()为:

registerBlockType( metadata.name, {/** * @see ./edit.js */edit: Edit,save: Save,} );

这样子就能正常保存变量与内容了(当然这个说法并不准确。我们将在以后提到发生了什么)。区块也变成了一个动态区块。

保存刷新。

调整保存的内容

如果你是跟着我一起做的,你会发现这样的bug
【Word Press基础】创建一个动态的自定义区块

第一次出现这种报错可以完全的放心,这个是正常的现象,具体的解决方案在Word Press中富文本控件的保存BUG中已经顺利解决。有兴趣的可以去看看产生的原因和调试的方式。这里只给出结论,保存的内容和编辑器中的内容没有对上,可以将save()方法改成如下所示:

export default function save({ attributes }) { const { noteContent } = attributes; return ( <> { noteContent } </> );}

保存刷新,即可正常保存。

二、修改界面显示的内容

如果你发布这篇页面/文章。你会发现咱们的控件依然显示着刚开始的静态文字。怎么回事??

原来word press将界面的显示内容和编辑器中显示的内容分开处理了。这样子可以实现编辑时用利于编辑的展示方式。显示时,则使用利于用户的展示方式。可以更人性化的实现复杂功能。这里先不放开来讲了。

总之,我们可以直接打开插件src/ht-note目录下的render.php。这里就是界面实际显示的内容啦。

修改内容如下:

<?php$content = $attributes[\'noteContent\'] ?? \"默认投票\";?><div <?php echo get_block_wrapper_attributes(); ?>><?php echo $content; ?><div>自定义的按钮</div></div>

这里的实现的就是让这个容器被Word Press管理的功能。

效果:
【Word Press基础】创建一个动态的自定义区块

三、总结

  1. 创建一个容器
  2. 创建一个变量储存内容
  3. 使用富文本编辑器
  4. 保存内容
  5. 在界面上展示

不知不觉又写了好多。但这也才写出来了一个静态的区块。虽然整体复杂了些,但还是没有什么让人费解的功能。后续会再完善这个区块