wordpress
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDrive the WordPress REST API () with .
/wp-json/wp/v2curl + jqThe user's self-hosted WordPress credentials are injected as env vars:
- — site root, e.g.
$WORDPRESS_SITE_URLhttps://blog.example.com - — the WordPress login username
$WORDPRESS_USERNAME - — an Application Password (WP 5.6+ core), NOT the login password. Treat it like a secret — never log or echo it.
$WORDPRESS_APP_PASSWORD
Auth is HTTP Basic () over HTTPS. Set up a reusable base
once, then every call reuses it:
username:app_passwordbash
undefined使用调用WordPress REST API()。
curl + jq/wp-json/wp/v2用户的自托管WordPress凭证会作为环境变量注入:
- — 站点根地址,例如
$WORDPRESS_SITE_URLhttps://blog.example.com - — WordPress登录用户名
$WORDPRESS_USERNAME - — 应用密码(WordPress 5.6+核心功能),并非登录密码。请将其视为机密信息——切勿记录或输出。
$WORDPRESS_APP_PASSWORD
认证方式为HTTPS下的HTTP Basic认证()。先设置可复用的基础配置,之后每次调用均可复用:
username:app_passwordbash
undefinedNormalize the site URL (strip a trailing slash) and build the API base.
标准化站点URL(去除末尾斜杠)并构建API基础地址。
SITE="${WORDPRESS_SITE_URL%/}"
API="$SITE/wp-json/wp/v2"
SITE="${WORDPRESS_SITE_URL%/}"
API="$SITE/wp-json/wp/v2"
-u sends HTTP Basic auth; --fail-with-body surfaces the JSON error body on 4xx/5xx.
-u 发送HTTP Basic认证;--fail-with-body 在4xx/5xx错误时显示JSON错误体。
WP=(curl -sS --fail-with-body -u "$WORDPRESS_USERNAME:$WORDPRESS_APP_PASSWORD")
Errors come back as `{"code": "...", "message": "...", "data": {"status": 401}}` —
show `message` verbatim. Common codes:
| HTTP | Meaning | What to tell the user |
|------|---------|-----------------------|
| 401 | `incorrect_password` / bad Basic auth | Application Password wrong or revoked → regenerate it and reconnect the WordPress connector |
| 403 | `rest_cannot_create` / insufficient role | The user's role can't publish; needs Author/Editor/Admin, or Application Passwords are disabled on the site |
| 404 | `rest_no_route` | REST API disabled or a security plugin blocks `/wp-json` → the user must re-enable it |
| 400 | `rest_invalid_param` | Bad field (e.g. unknown category id) → fix and retry |
> **`content` is HTML, not Markdown.** Convert Markdown to HTML first
> (`pandoc -f markdown -t html`, or a simple converter). Raw Markdown renders literally.WP=(curl -sS --fail-with-body -u "$WORDPRESS_USERNAME:$WORDPRESS_APP_PASSWORD")
错误返回格式为`{"code": "...", "message": "...", "data": {"status": 401}}`——直接显示`message`内容。常见错误码:
| HTTP | 含义 | 需告知用户的内容 |
|------|---------|-----------------------|
| 401 | `incorrect_password` / 无效Basic认证 | 应用密码错误或已失效 → 重新生成密码并重新连接WordPress连接器 |
| 403 | `rest_cannot_create` / 角色权限不足 | 用户角色无发布权限;需要作者/编辑/管理员权限,或站点已禁用应用密码功能 |
| 404 | `rest_no_route` | REST API已禁用或安全插件拦截了`/wp-json` → 用户需重新启用REST API |
| 400 | `rest_invalid_param` | 参数无效(如未知分类ID) → 修正后重试 |
> **`content`字段为HTML格式,而非Markdown。** 需先将Markdown转换为HTML(可使用`pandoc -f markdown -t html`或简易转换器)。原始Markdown会被原样渲染。Step 0 — verify the connection first
步骤0 — 先验证连接
bash
"${WP[@]}" "$API/users/me" | jq '{id, name, slug, roles: (.roles // [])}'A 200 with your user object confirms the site URL, username, and Application
Password all work. If this fails, stop and surface the error — don't attempt writes.
bash
"${WP[@]}" "$API/users/me" | jq '{id, name, slug, roles: (.roles // [])}'返回200状态码及用户对象,说明站点URL、用户名和应用密码均有效。如果此步骤失败,请停止操作并显示错误信息——不要尝试写入操作。
Publish or draft a post
发布或保存草稿文章
Publishing is public and hard to undo — confirm with the user before using
. Default to and hand back the edit link.
status=publishstatus=draftbash
jq -n --arg t "国内如何稳定调用 Claude API" \
--arg c "<p>正文 HTML……</p>" \
--arg s "draft" \
'{title:$t, content:$c, status:$s}' \
| "${WP[@]}" -X POST "$API/posts" \
-H "Content-Type: application/json" -d @- \
| jq '{id, status, link, edit: "\(env.WORDPRESS_SITE_URL)/wp-admin/post.php?action=edit&post=\(.id)"}'With categories / tags / excerpt (ids come from the endpoints below):
bash
jq -n --arg t "标题" --arg c "<p>正文</p>" --arg e "一句话摘要" \
'{title:$t, content:$c, excerpt:$e, status:"draft",
categories:[5], tags:[12,34]}' \
| "${WP[@]}" -X POST "$API/posts" -H "Content-Type: application/json" -d @- \
| jq '{id, status, link}'- Publish an existing draft: body
POST $API/posts/<id>.{"status":"publish"} - Update a post: with any subset of fields (WP REST uses POST, not PUT, for updates).
POST $API/posts/<id> - Delete (trash) a post: .
"${WP[@]}" -X DELETE "$API/posts/<id>"
发布操作是公开且难以撤销的——使用前请与用户确认。 默认使用并返回编辑链接。
status=publishstatus=draftbash
jq -n --arg t "国内如何稳定调用 Claude API" \
--arg c "<p>正文 HTML……</p>" \
--arg s "draft" \
'{title:$t, content:$c, status:$s}' \
| "${WP[@]}" -X POST "$API/posts" \
-H "Content-Type: application/json" -d @- \
| jq '{id, status, link, edit: "\(env.WORDPRESS_SITE_URL)/wp-admin/post.php?action=edit&post=\(.id)"}'包含分类/标签/摘要的示例(ID来自下方端点):
bash
jq -n --arg t "标题" --arg c "<p>正文</p>" --arg e "一句话摘要" \
'{title:$t, content:$c, excerpt:$e, status:"draft",
categories:[5], tags:[12,34]}' \
| "${WP[@]}" -X POST "$API/posts" -H "Content-Type: application/json" -d @- \
| jq '{id, status, link}'- 发布现有草稿:向提交请求体
POST $API/posts/<id>。{"status":"publish"} - 更新文章:向提交任意字段子集(WordPress REST API使用POST而非PUT进行更新)。
POST $API/posts/<id> - 删除(移入回收站)文章:。
"${WP[@]}" -X DELETE "$API/posts/<id>"
List / read posts
列出/读取文章
bash
"${WP[@]}" "$API/posts?per_page=10&status=publish,draft&_fields=id,title,status,link,date" \
| jq '.[] | {id, title: .title.rendered, status, link, date}'Paginate with ; the total page count is in the
response header (add to see headers).
&page=2X-WP-TotalPages-D -bash
"${WP[@]}" "$API/posts?per_page=10&status=publish,draft&_fields=id,title,status,link,date" \
| jq '.[] | {id, title: .title.rendered, status, link, date}'使用进行分页;总页数在响应头中(添加可查看响应头)。
&page=2X-WP-TotalPages-D -Categories & tags (get or create ids)
分类与标签(获取或创建ID)
bash
undefinedbash
undefinedList existing
列出已有分类/标签
"${WP[@]}" "$API/categories?per_page=100&_fields=id,name,slug" | jq '.[] | {id, name}'
"${WP[@]}" "$API/tags?per_page=100&_fields=id,name,slug" | jq '.[] | {id, name}'
"${WP[@]}" "$API/categories?per_page=100&_fields=id,name,slug" | jq '.[] | {id, name}'
"${WP[@]}" "$API/tags?per_page=100&_fields=id,name,slug" | jq '.[] | {id, name}'
Create one (returns its id)
创建分类/标签(返回其ID)
jq -n --arg n "AI 教程" '{name:$n}'
| "${WP[@]}" -X POST "$API/categories" -H "Content-Type: application/json" -d @-
| jq '{id, name}'
| "${WP[@]}" -X POST "$API/categories" -H "Content-Type: application/json" -d @-
| jq '{id, name}'
Creating a term that already exists returns
`{"code":"term_exists", ... "data":{"status":400,"term_id":<id>}}` — reuse
`.data.term_id` instead of failing.jq -n --arg n "AI 教程" '{name:$n}'
| "${WP[@]}" -X POST "$API/categories" -H "Content-Type: application/json" -d @-
| jq '{id, name}'
| "${WP[@]}" -X POST "$API/categories" -H "Content-Type: application/json" -d @-
| jq '{id, name}'
创建已存在的分类/标签会返回`{"code":"term_exists", ... "data":{"status":400,"term_id":<id>}}`——请复用`.data.term_id`而非报错。Upload media (featured image / in-body image)
上传媒体(特色图片/正文中的图片)
bash
FILE="./cover.png"
NAME="$(basename "$FILE")"
MEDIA_ID=$("${WP[@]}" -X POST "$API/media" \
-H "Content-Disposition: attachment; filename=\"$NAME\"" \
-H "Content-Type: image/png" \
--data-binary @"$FILE" | jq -r '.id')
echo "media id=$MEDIA_ID"bash
FILE="./cover.png"
NAME="$(basename "$FILE")"
MEDIA_ID=$("${WP[@]}" -X POST "$API/media" \
-H "Content-Disposition: attachment; filename=\"$NAME\"" \
-H "Content-Type: image/png" \
--data-binary @"$FILE" | jq -r '.id')
echo "media id=$MEDIA_ID"Attach as the post's featured image:
将其设置为文章的特色图片:
add "featured_media": <MEDIA_ID> to the post body.
在文章请求体中添加 "featured_media": <MEDIA_ID>。
undefinedundefinedGotchas
注意事项
- HTTPS + Application Passwords are required. On plain , WordPress disables Application Passwords → every call 401s. Tell the user to enable HTTPS.
http:// - A security plugin / host may block (Wordfence, "disable REST API" plugins, some managed hosts). Symptom: 404
/wp-jsonor an HTML login page instead of JSON. The user must allow REST API access.rest_no_route - The Application Password contains spaces (e.g. ). Keep them —
abcd efgh ijkl mnophandles the spaces fine; don't strip them.curl -u - Never publish silently. Even if the user says "post it", prefer creating a
draft and returning the edit link unless they explicitly asked to go live.
wp-admin
- 必须使用HTTPS + 应用密码。在纯协议下,WordPress会禁用应用密码功能→所有调用均返回401错误。请告知用户启用HTTPS。
http:// - 安全插件/主机可能拦截(如Wordfence、“禁用REST API”插件、部分托管主机)。症状:返回404错误
/wp-json或返回HTML登录页面而非JSON。用户必须允许REST API访问。rest_no_route - 应用密码包含空格(例如 )。请保留空格——
abcd efgh ijkl mnop可正常处理空格;不要去除。curl -u - 切勿静默发布。即使用户说“发布”,除非用户明确要求上线,否则优先创建草稿并返回编辑链接。
wp-admin
Record the output
记录输出结果
After you successfully publish and obtain the live result URL, call the built-in
tool ONCE so the user can track this deliverable in My Outputs:
publish_artifactpublish_artifact(kind="article", channel="wordpress", title="<title>", url="<the REAL returned URL>", status="delivered")Use the real returned URL — never fabricate one. Call it once per published item,
only after delivery is confirmed; skip it (or use ) if publishing failed.
See .
status="failed"_shared/artifacts.md成功发布并获取到实际结果URL后,调用内置的工具一次,以便用户在我的输出中跟踪此交付物:
publish_artifactpublish_artifact(kind="article", channel="wordpress", title="<title>", url="<the REAL returned URL>", status="delivered")请使用实际返回的URL——切勿伪造。每个已发布的内容仅调用一次,且仅在确认交付成功后调用;若发布失败,请跳过(或使用)。详情请查看。
status="failed"_shared/artifacts.md