EP188. “新建 generic-button 骨架:复用 generic-heading 套路”
🔒 登录后可标记已读📌 并入 EP187 的提醒:如果想更彻底地关闭 theme.json 里几乎所有的颜色/字体自定义选项(而不只是 EP185-186 演示的那几项),settings.color 和 settings.typography 两个对象还可以补上更多属性统一设成 false/空数组:
"color": {
"background": true,
"text": false,
"link": false,
"custom": false,
"defaultPalette": false,
"duotone": [],
"customDuotone": false,
"gradients": [],
"customGradient": false,
"palette": [ /* ...原有的调色板数组不变... */ ]
},
"typography": {
"fontFamilies": [],
"fontStyle": false,
"fontWeight": false,
"letterSpacing": false,
"textDecoration": false,
"lineHeight": false,
"textTransform": false,
"dropCap": false,
"customFontSize": false,
"fontSizes": []
}
开始做第三个自定义 Block——generic-button(通用按钮),验证「用自定义 Block 练习框架」这个套路本身已经很熟练:靠 JSXBlock 类一行代码完成 PHP 注册,JS 文件直接从 generic-heading.js 复制过来改字段名。这一讲只做最基础的骨架:文字可编辑(复用 RichText,但不允许任何加粗/斜体格式)、标签从标题的 h1 换成链接的 a、class 前缀从 headline 换成 btn;链接地址和按钮颜色都先写死占位(href="#"、颜色留到后面几讲实现动态选择),先让这个新 Block 能在编辑器里跑起来。
涉及文件
wp-content/themes/fictional-university-block-theme/functions.php(修改,注册新 Block)wp-content/themes/fictional-university-block-theme/our-blocks/genericbutton.js(新建)wp-content/themes/fictional-university-block-theme/our-blocks/banner.js(修改,allowedBlocks新增按钮)wp-content/themes/fictional-university-block-theme/package.json(修改,start脚本新增入口)
代码实现
functions.php:用已有的 JSXBlock 类多注册一个 Block:
new JSXBlock('genericbutton');
our-blocks/banner.js:allowedBlocks 里加入新按钮 Block:
<InnerBlocks allowedBlocks={["ourblocktheme/genericheading", "ourblocktheme/genericbutton"]} />
our-blocks/genericbutton.js(这一讲搭好的骨架,先用占位链接/颜色,link 选择器和动态颜色留到 EP189/后续几讲实现):
import { RichText } from "@wordpress/block-editor"
import { registerBlockType } from "@wordpress/blocks"
registerBlockType("ourblocktheme/genericbutton", {
title: "Generic Button",
attributes: {
text: { type: "string" },
size: { type: "string", default: "large" }
},
edit: EditComponent,
save: SaveComponent
})
function EditComponent(props) {
function handleTextChange(x) {
props.setAttributes({ text: x })
}
return (
<RichText allowedFormats={[]} tagName="a" className={`btn btn--${props.attributes.size} btn--blue`} value={props.attributes.text} onChange={handleTextChange} />
)
}
function SaveComponent(props) {
return (
<a href="#" className={`btn btn--${props.attributes.size} btn--blue`}>
{props.attributes.text}
</a>
)
}
package.json:start 脚本追加入口文件:
"start": "wp-scripts start src/index.js our-blocks/banner.js our-blocks/genericheading.js our-blocks/genericbutton.js"
关键改动点:
new JSXBlock('genericbutton')一行完成 PHP 端注册——EP183 抽出来的可复用类这里第一次真正体现出价值:不需要再重复写wp_register_script/register_block_type那一整套样板代码genericbutton.js直接从genericheading.js复制再改:这门课这几讲一贯的省时做法——两者结构高度相似(都是RichText驱动的可编辑文字),复制过来改字段名/标签名比从零重写更快- 和标题 Block 的三处关键差异:
allowedFormats={[]}(空数组)——按钮文字不需要加粗/斜体这些格式化选项,直接禁用全部tagName="a"——标题用h1/h2/h3,按钮本质是一个链接,用<a>标签className前缀从headline/headline--{size}换成btn/btn--{size},对应 Fictional University 已有的按钮样式命名规则
save阶段不再需要RichText.Content:跟标题 Block 不同,按钮文字禁止任何嵌套格式(没有允许加粗/斜体),所以最终输出用普通的<a>{props.attributes.text}</a>就够了,不需要RichText.Content处理可能存在的嵌套<strong>/<em>标签——RichText.Content真正的价值在于「文字内部可能带有格式化标签」这种场景,这里用不上- 暂时写死的两处占位:
href="#"(真正的链接地址由 EP189 加入的「链接选择器」功能实现)、btn--blue(颜色写死成蓝色,真正可选颜色由后续几讲实现)——这一讲的重点只是先把骨架和基础可编辑体验跑通 - 别忘了两处「登记」步骤:
banner.js的allowedBlocks数组要把新 Block 的名字加进去,否则在 Banner 内部插入不了这个按钮;package.json的start脚本要把新 JS 文件也列成入口,否则不会被编译
常见坑
- 只新建了
genericbutton.js,忘记同步在banner.js的allowedBlocks里登记——新 Block 类型不会出现在「插入到 Banner 内部」的候选列表里 - 忘记把新文件加进
package.json的start脚本入口——浏览器请求这个 Block 的 JS 资源会 404 - 复制
generic-heading.js后忘记把allowedFormats改成空数组——按钮文字依然会带着加粗/斜体的格式化选项,跟设计预期不符
[截图:Banner Block 内部插入 Generic Button 骨架后的编辑器画面,蓝色按钮样式的可编辑文字链接]
延伸 / 后续讲座会用到
下一讲要给按钮加上「点击工具栏图标 → 弹出链接选择器 → 搜索站内文章/页面或输入任意 URL」的功能,取代这里写死的 href="#"。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 28, EP187, EP188