书接上文:【Word Press基础】创建一个自定义区块,上篇博客创建了一个自定义区块。但这个区块的展示效果都没有处理,肯定没有办法实现项目的需求。因此这篇文章将带领大家实现一个动态的自定义区块。
一、修改编辑器中展示的内容
打开src/ht-note/edit.js
,这个复杂(并非复杂)的文件就是编辑器中展示的内容了。我们可以在文章/页面的编辑器中创建一个我们的自定义区块,创建完成后记得保存一下草稿:
这就是默认的效果了。一个静态的文字。我们的目标就是先写一个静态的投票区块。我们的区块应当包括:
- 一个富文本编辑器。管理员可以编写内容
- 一个投票按钮。用户能够进行投票
- 适当的动画、样式
1、创建一个被word press管理的盒子
如果打开一个word press的网站,可以看到每个段落都有默认的样式、行为。我们的插件当然也不应该例外。{ ...useBlockProps() }
方法就能简单的创建一个能被word press管理的盒子。
打开edit.js
并修改Edit()
方法:
export default function Edit() {
return (
<>
<div { ...useBlockProps() }>
<p>自定义的区块</p>
<div>自定义的按钮</div>
</div>
</>
);
}
保存并刷新界面。
修改成功。
2、添加富文本编辑器
简易的富文本编辑器能够使用<RichText>
控件直接引用。包括了文本样式、上下角标、图文混排等。
使用Rich Text
富文本编辑器可以自定义的设置一些内容。详细可以看官方文档。这里先规定了占位符。
修改edit()
方法,注意引用Rich Text依赖:
export default function Edit() {
return (
<>
<div { ...useBlockProps() }>
<RichText placeholder='输入你的内容...'>
</RichText>
<div>自定义的按钮</div>
</div>
</>
);
}
保存并刷新,上方内容便是富文本了:
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
变量没能保存。
即:
- 修改了内容,变量被修改
- 编辑后,内容同步至note-content。note-content被修改
- 保存后,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中富文本控件的保存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>
这里的<?php echo get_block_wrapper_attributes(); ?>
实现的就是让这个容器被Word Press管理的功能。
效果:
三、总结
- 创建一个容器
- 创建一个变量储存内容
- 使用富文本编辑器
- 保存内容
- 在界面上展示
不知不觉又写了好多。但这也才写出来了一个静态的区块。虽然整体复杂了些,但还是没有什么让人费解的功能。后续会再完善这个区块