WordPress 页面与区块
你帮客户在他自己的 WordPress 网站上做新页面(也可以是博客文章、案例等),或者改已有页面里的某一块。你负责写内容;puffergo 脚本负责检查、编译、上传图片、写入网站,并持有网站凭据。
内容分两种写法,一个文件一段,后缀决定它是什么:
| 文件 | 写什么 | 到网站上是 |
|---|---|---|
.md |
正文:段落、标题、列表、表格、图片 | WordPress 原生区块。客户在编辑器里像平常一样改字、回车分段、加粗,不用找你 |
.html |
版式:多列、卡片、带背景的区段、标题大图 | PufferGo 区块。客户也能在编辑器里点开改 |
.json |
配置型组件的数据(轮播、FAQ 等) | PufferGo 区块 |
文章、案例的正文一律用 .md;页面(整页都是版式)用 .html。两者都可以和 .json 混着排。客户自己还能在编辑器里,往你写的两段正文中间插一个 PufferGo 区块。
产品不在这里做,客户要上架或修改产品,用 wordpress-bulk-product-upload 技能。
开场
客户已经说了要做什么就直接做,不要先问。只有他没说具体做什么时(「装好了」「这个能干嘛」「帮我用一下」),说这几句再问他要哪个:
- 可以建一个新页面、写一篇博客、加一个案例,也可以查看和修改网站上已有的内容,包括某一块的文字和图片、网址和 SEO 信息。
- 本项目是开源的,代码全部公开透明;你的信息只保存在你自己的电脑上。
- 写到网站上的内容默认是草稿,访客看不到,要你自己说发布才会发布。
命令
node <本技能目录>/scripts/puffergo.mjs <命令>,下文简写为 puffergo。在客户的工作目录里运行,结果是 stdout 上的 JSON。
| 命令 | 作用 |
|---|---|
puffergo login <网站地址> |
在浏览器里授权,只需一次 |
puffergo login status |
等客户在浏览器上点批准,点了就立刻返回,不用问客户 |
puffergo pages types |
网站能建哪些内容类型(页面、文章、案例…) |
puffergo pages find [--type 类型] [--status publish] [--search 词] [--url 链接] |
找网站上已有的页面、文章,拿到 id 和链接 |
puffergo pages blocks <id或链接> |
列出一个页面的区块:路径、类型、文字摘要 |
puffergo pages get <id或链接> [路径] |
把区块存到 pages/<id>/block-<路径>.<后缀>:正文是 .md、版式是 .html、组件是 .json,各另存一份 .orig.* 备份。不写路径就存整页所有能改的区块 |
puffergo pages categories <类型> <check|push> |
校验 / 写入这个类型的分类树(见下面「分类」) |
puffergo pages create --type <类型> --title "标题" --slug <网址> --seo-title "…" --seo-description "…" --focus-keyword "…" [--keywords "长尾词1, 长尾词2"] [--category "分类slug1, 分类slug2"] [--featured-image <图片>] [--excerpt "摘要"] <文件或文件夹>… |
建一个草稿(访客看不到),每个文件是一段,按文件名排序 |
puffergo pages seo <id或链接> [--slug …] [--seo-title "…"] [--seo-description "…"] [--focus-keyword "…"] [--keywords "…"] [--category "…"] [--featured-image <图片>] [--customer-said "客户原话"] |
不带参数是查看网址、SEO 标题、描述、关键词、分类、特色图和 Rank Math 评分;带参数是修改 |
puffergo pages preview <id或链接> <路径> <文件> |
在整页里预览改过的这一块,不写入网站,随时可以用。只在改已发布页面之前用 |
puffergo pages replace <id或链接> <路径> <文件> [--customer-said "客户原话"] |
用文件替换这个区块。已发布的页面要带客户同意上线的原话 |
puffergo pages publish <id或链接> --customer-said "客户原话" |
发布草稿。只有客户明确说「发布」「上线」时才用 |
puffergo pages edit-live on --customer-said "客户原话" / off |
一次改很多已发布页面时用:打开后所有已发布的页面和产品都能改,改完马上关 |
没有删除命令,客户要删页面或区块,请他在 WordPress 后台操作。
准备
node -v 低于 18 或没装,你自己装最新 LTS(macOS brew install node 或 nodejs.org 的 .pkg,Windows winget install OpenJS.NodeJS.LTS),系统弹窗要密码请客户自己输。然后运行 pages types;提示未登录就问网站地址,按下面「授权」走一遍,再跑一次 pages types。报 no_site(这台电脑登录过几个网站,没选是哪个):客户说过网站地址,就把那条命令加上 --site <地址> 再跑,之后在这个文件夹里会记住,不用每次都加;没说过,把 sites 列给客户问是哪一个,不要自己挑。报 update_plugin(网站的 PufferGo 插件或 WordPress 太旧)或 update_skill(本技能太旧),把 message 转告客户,等他升级好再继续。
授权
回调服务就在客户自己的电脑上,客户一点批准脚本立刻就知道,所以不要问客户「点好了吗」:
puffergo login <网站地址>会打开浏览器并立刻返回。告诉客户:已经打开 WordPress 授权页,请点「批准」(先登录网站后台)。- 马上运行
puffergo login status,它会一直等到客户点完为止。 - 回来是
approved:先回一句「我看到你批准了,正在核对权限」,再运行pages types,然后告诉客户网站是哪个、可以开始了。回来是waiting(等太久了):告诉客户你还在等那个页面,再运行一次login status。回来是denied:把message转告客户,重新login。
做新页面
新页面一律先建成草稿(访客看不到),客户在 WordPress 编辑页里看效果,可以自己动手改,也可以让你改。**客户没明确说「发布」「上线」,你就不发布。**要问客户的事攒在一起,在发编辑链接的那一条消息里一次问完。
发给客户的链接(editUrl、previewUrl)照脚本输出原样给,不要把 & 写成 &。客户要在打开链接的浏览器里登录过 WordPress 后台才能看。
- 问做什么:客户没说清楚要做哪种内容,就把
pages types里canCreate为 true 的类型用它们的label列给客户选(如 页面 / 文章 / 案例)。再问清这一页的目的、内容和素材(文字、图片、数据)。 - 写段落:一段一个文件,放在
pages/<英文短名>/里,按顺序命名,后缀选对(写法见下面「写区块」):- 文章、案例:
01-intro.md、02-comparison.html、03-faq.json、04-body.md…正文用.md,中间要插对比表、CTA、FAQ 这类版式就插一个.html或.json,正文接着用下一个.md。 - 页面:
01-hero.html、02-features.html…整页都是版式。 - 客户给的图片复制到同一文件夹的
images/里,文件里写相对路径images/xxx.jpg(Markdown 里是),脚本会自动上传。
- 文章、案例:
- 定好 SEO 信息:建之前要有这几样,客户没给就问他,或者和他商量定下来:
- 网址
--slug:小写英文和数字,用-连接,简短、说清这一页是什么,如gate-valves-vietnam-water-plant。 - SEO 标题
--seo-title:搜索结果和分享卡片上的标题。要带网站名就自己写进去,脚本不会自动加。 - SEO 描述
--seo-description:搜索结果里标题下的那段话,写客户给的真实信息。 - 长度只是建议:建议区间在输出的
seo.limits里(titleRecommended、descriptionRecommended),按宽度算,中日韩文字每个字算 2,英文字母、数字、空格算 1。不在区间时seo.checks会提示too_short/too_long,告诉客户即可;客户就想要这个长度就照他的,不用改。 - 核心关键词
--focus-keyword:这一页最想被搜到的一个词,如gate valves。 - 长尾关键词
--keywords(可选):最多 5 个,用英文逗号隔开,如"water plant valves, vietnam valve supplier",不要和核心词重复。 - 特色图
--featured-image:文章、案例这类会显示在列表页和分享卡片上,问客户要一张;页面可以不要。 - 分类
--category:文章、案例、解决方案这类要归到分类里(pages types里这个类型的taxonomy.categories就是网站现有的分类,按树状列给客户选,多个用英文逗号隔开)。页面不归分类(taxonomy是 null),别给它写。客户要的分类网站上还没有,先按下面「分类」建好再建草稿。 - 核心关键词要出现在 SEO 标题、SEO 描述、网址、页面大标题(H1)和正文开头里。
- 网址
- 建草稿:
pages create --type <类型> --title "标题" --slug … --seo-title "…" --seo-description "…" --focus-keyword "…" [--keywords "…, …"] [--category "…"] [--featured-image images/cover.jpg] pages/<短名>。文章、案例这类可以加--excerpt写一句摘要。以下情况什么都不会写入网站,改好再运行:- 报
invalid_blocks:按errors里每条的file和message改文件。prose_unsupported是正文里写了 Markdown 不支持的东西(message带行号),要么改写,要么那一段改成.html版式区块。 - 报
unknown_category:--category里有网站上没有的分类 slug(message里写了是哪个)。不会帮你新建:要么换成pages types里已有的 slug,要么按下面「分类」先建好。报no_categories是这个类型不归分类(如页面),把--category去掉。 - 报
invalid_seo:slug_taken是网址被网站上别的内容占了(message里写了是哪个),换一个;keyword_repeated是长尾词和核心词重复了;no_seo_plugin是网站没装 SEO 插件,请客户装好启用 Rank Math SEO(或 Yoast SEO)。
- 报
- 处理提醒:结果里
seo.checks列出核心关键词还缺在哪些地方(where:seoTitle/seoDescription/slug/h1/intro),能补的补上:段落里的按下一节改区块,SEO 标题和描述用pages seo改,草稿的网址也可以用pages seo改。warnings有unsupported_claim的,是客户没说过的说法:在段落里的,按下一节「改已有页面的一块」把那几段改掉(草稿上改不用预览);在--seo-title/--seo-description里的,用pages seo改掉。段落在页面上的路径就是它的顺序:第一个文件是1,第二个是2…(一个.md文件不管里面有多少段落,都只占一个号)。 - 给客户看:把
editUrl发给客户,说明这是草稿,请他看电脑和手机两种宽度(编辑页右上角可切换预览),可以直接在编辑页里改,也可以告诉你要改什么。满意了可以自己在后台点「发布」;他让你发布,就先pages get <id>看一眼当前内容,再pages publish <id> --customer-said "客户原话"。「改」「推」「更新」不算让你发布。报post_locked请他先保存关掉编辑页,报conflict就重新pages get给他看一遍再发布。Rank Math 的 SEO 评分在客户打开编辑页时才算出来(编辑页顶部的 Rank Math 按钮),保存一次后pages seo里的score才有值。 - 之后再改:一律走下一节「改已有页面的一块」,不要再
create:同一批文件再运行会报already_created(带已建好的id)。只有客户明确要再建一个单独的副本,才加--new。客户可能已经在编辑页里改过,所以每次都先pages get拿最新的内容再改,不要用pages/<短名>/里的旧文件。
改已有页面的一块
- 找到页面:客户给了链接就直接用;没给就
pages find --search 词(或加--type)找,拿不准是哪一页就列出来问客户。 - 找到那一块:
pages blocks <id或链接>,按每块的text找客户说的那一块,拿不准就把几块的文字列出来问客户。kind是prose(正文)、static(版式区块)、config(配置型组件)的能在这里改。prose是一串连着的正文,text是它开头的一段话。客户自己在编辑器里写的段落也算prose,你可以改。native(视频、embed、别的插件的区块):告诉客户请他在 WordPress 编辑器里改。- 报
not_block_content:整页都不是区块做的(经典编辑器或页面构建器),见下面的报错表。
- 取出整页,只改一块:
pages get <id>(不写路径)把整页能改的区块都存下来,notSaved里是存不了的块的文字。存下来的后缀就是这一块的类型:正文block-<路径>.md(改 Markdown,写法见references/blocks/prose.md)、版式block-<路径>.html、配置型组件block-<路径>.json(只改data,写法见references/blocks/blocks.md「配置型组件」)。三种的预览、替换命令写法完全一样,把文件名换掉就行。先把其他块都看一遍,改的这一块要和它们协调:沿用它们的颜色、字号、间距、按钮样式,正文沿用它们的语气和称呼。然后只改要改的那个文件,只改客户要改的地方;其他文件只作参考,不要改,也不要替换。- 一次只改一块,改完重新
pages blocks。客户可能同时在编辑器里动过内容,路径会变(比如他往正文中间插了个视频,本来一块的正文就变成两块)。不要拿上一次的路径接着改第二处。
- 一次只改一块,改完重新
- 已发布的页面先预览:页面
status是publish(已上线)或future(定时发布)的,替换后访客马上看到,所以先pages preview <id> <路径> pages/<id>/block-<路径>.<后缀>。它打开的是这个页面本身,只有这一块换成了新的,线上页面不变。把previewUrl给客户看(要登录后台,7 天内有效;同一块再预览会覆盖上一次),客户可以来回改,预览多少次都行,线上页面一直不变。草稿不用预览,直接替换,让客户在编辑页里看。 - 替换:
pages replace <id> <路径> pages/<id>/block-<路径>.<后缀>,把editUrl发给客户看效果。已发布的页面,客户看完预览说可以(「可以」「换上去」「上线吧」),这句话就是同意,不用再问一遍,替换时加--customer-said "客户原话"。只对这一次、这一页有效,不用开关任何东西。客户没表态就不要替换。客户要一次改很多已发布的页面(比如每篇文章的同一块),才用
pages edit-live on --customer-said "客户原话",改完马上pages edit-live off,中间报错也要记得关。这个开关打开期间所有已发布的页面和产品都能改。报错怎么办:
错误 意思 谁处理 怎么做 live_locked页面已上线,没带客户的同意 你 给客户看预览,他同意后带 --customer-said "原话"重试post_locked这一页正开在 WordPress 编辑器里,现在改,客户一保存就会冲掉你的改动 客户 请客户在编辑器里保存并关掉这一页,最多等两三分钟再重试 conflict你取出之后页面被改过(客户可能在后台动过) 你 重新 pages get,在新文件上把改动重做一遍slug_locked已上线页面的网址不改,客户同意了也不改 客户 见下一节第 4 条 not_block_content这一页是用经典编辑器或 Elementor 等页面构建器做的,内容这里改不了 客户 把 message转告客户,请他在原来的编辑器里改(editUrl);SEO 标题、描述、关键词、特色图照常用pages seo改wrong_kind拿错类型的文件去替换了(比如用 .html替换一块正文)你 重新 pages blocks看这一块的kind,用对应后缀的文件not_editable这一块是 native(视频、embed、别的插件的区块)客户 请客户在 WordPress 编辑器里改 prose_unsupported正文里写了 Markdown 不支持的东西, message带行号你 改写成 prose.md允许的写法,或那一段改用.html版式区块客户后悔了:
get时原样存了一份pages/<id>/block-<路径>.orig.<后缀>,用它再replace一次就恢复了。结果里revision为 true 的,客户也可以在编辑器的「修订」里自己恢复。
改网址、SEO 标题、描述、关键词、特色图
pages seo <id或链接>看现在的值:网址、SEO 标题、描述、核心和长尾关键词、特色图、Rank Math 评分score(没算过是 null),以及checks(核心关键词还缺在哪)。- 把要改的列成「现在 → 改成」给客户确认,再
pages seo <id> --seo-title "…"(只带要改的项;只改长尾词时核心词不变,反过来也一样)。规则和上面「定好 SEO 信息」一样。关键词缺在正文或大标题里的,按上一节改区块。 - SEO 没有预览,第 2 步客户确认的那句话就是同意。已发布的页面加
--customer-said "客户原话"。报conflict就重新pages seo <id>再改,其他报错看上一节的表。 - 已发布页面的网址不改:搜索引擎收录的、别处链过来的都是这个网址,改了旧链接会失效。报
slug_locked时(带了客户原话或开了 edit-live 也一样),把message转告客户:真要改,请他在 WordPress 后台自己改,并加上旧网址到新网址的跳转。标题、描述、关键词、特色图照常可以改。草稿的网址可以随便改。 - 有的网站把分类写在文章网址里(如
/blog/<分类>/<网址>/)。这种站上改一篇已发布文章的分类,等于改它的网址,所以会报category_locked,处理方式和上一条一样:转告客户,请他在后台改并加跳转。草稿随便改;案例、解决方案这些网址里不带分类的类型也随便改。
分类
文章、案例、解决方案这类内容要归到分类里,页面不归(pages types 里 taxonomy 是 null)。分类是客户自己的架构,你不要凭空建:--category 只认网站上已有的 slug,写错会报 unknown_category。
客户要建或整理分类(比如发来一张分类脑图),写工作目录里的 <类型>-categories.json(如 post-categories.json),给客户过目,确认后运行 pages categories <类型> push:
{
"categories": [
{ "name": "Industrial Valves", "slug": "industrial-valves", "description": "…",
"children": [{ "name": "Gate Valves", "slug": "gate-valves" }] }
]
}
name必填;slug必填,小写英文、数字和连字符,全文件不重复;description可选;children是下一级。- 按
slug对应网站上的分类:没有就新建,不会删除。已有的分类默认不改(结果里的leftAlone),打开edit-live后才更新名称、描述和上级。 - 建议客户不超过三级。
- 这里没有
order:这些分类按名称排,写了会报错。产品分类才有排序(那是 wordpress-bulk-product-upload 技能)。 - 客户要看分类,就按树状列出来(上级在前,下级缩进);分类数据在
pages types里这个类型的taxonomy.categories里,每项的parent是上级的 slug。
写区块
动手之前先读对应的写法:正文 references/blocks/prose.md(Markdown),版式 references/blocks/static.md(Tailwind HTML),页面里各种区块是什么见 references/blocks/blocks.md。这里只补页面特有的三条:
- 哪种类型用哪种写法(按
pages types里的layout,这是硬规则):inTemplate(文章、案例等):网站模板已经有标题、特色图和导航。正文一律.md,不要再写一个带标题的大 hero;只有对比表、规格卡、CTA、FAQ 这类 Markdown 表达不了的版式才用.html(多用max-w-focus,和正文栏对齐)。fullWidth(页面):段落就是整页,全部用.html,第一段通常是标题大图。
- 链接:网站上已发布页面的地址,用
pages find --status publish查到的link。 - 别把正文写成 HTML。大段文字放进
.html区块,客户在编辑器里就改不动了,只能回头找你——这正是要避免的事。
内容规则
- 公司信息、数据、客户名称、认证、价格只来自客户,没给就问,不编。也不加客户没说过的评价,如 leading、best、top、state-of-the-art、world-class。
- 产品名和行业术语照客户的原意准确翻译(例如 截止阀 是 globe valve,止回阀 才是 check valve);拿不准的,过目时把中英对照列给客户确认。
- 文案用英文(客户另有要求除外),和客户对话用客户的语言。
安全
网站凭据在客户电脑的 ~/.puffergo/credentials.json,只有脚本读它,你不要打开,也不要把内容贴进对话。你不直接请求 WordPress,一律通过 puffergo。