- CLAUDE.md: 项目定位与治理规则 - API reference: 补充 multisite 参数文档 - Multisite blog_id 参数支持 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.5 KiB
GlotPress REST API 文档
概述
gp-rest-api 是部署在 wpfanyi.com 的 WordPress mu-plugin,为 GlotPress 翻译平台提供 REST API 端点,支持通过 Application Password 认证进行程序化翻译管理。
- 部署位置:
/www/wwwroot/wpfanyi.com/wp-content/mu-plugins/gp-rest-api.php - 服务器:feicode-prod (45.117.8.70)
- 源码仓库:
~/Projects/gp-rest-api/(待推送 feicode) - 版本:1.0.0
- GlotPress 版本:4.0.3
认证
使用 WordPress Application Password(Basic Auth)。
创建 Application Password
- 登录 wpfanyi.com 后台
- 用户 → 个人资料 → Application Passwords
- 输入名称(如
ai-translate-pipeline),点击"添加新的应用程序密码" - 记录生成的密码(只显示一次)
请求认证
curl -u "用户名:应用密码" "https://wpfanyi.com/wp-json/gp/v1/..."
或使用 Authorization header:
Authorization: Basic base64(用户名:应用密码)
多站点说明
wpfanyi.com 是 WordPress 多站点架构,67 个子站各自运行独立的 GlotPress 实例。所有端点需要传 blog_id 参数指定目标子站。
子站 blog_id 对照表(Top 15)
| blog_id | 路径 | 产品 |
|---|---|---|
| 2 | /woocommerce/ | WooCommerce |
| 3 | /buddypress/ | BuddyPress |
| 4 | /bbpress/ | bbPress |
| 5 | /mainwp/ | MainWP |
| 8 | /elementor/ | Elementor |
| 9 | /learndash/ | LearnDash |
| 10 | /gravityforms/ | GravityForms |
完整列表可通过 WP 网络管理后台查看。
端点
1. GET /wp-json/gp/v1/projects/{path}
获取项目信息、翻译集列表和翻译进度统计。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | URL 路径参数,GP 项目路径 |
| blog_id | integer | 否 | 子站 ID,默认 0(当前站) |
示例
curl -u "user:pass" \
"https://wpfanyi.com/wp-json/gp/v1/projects/woocommerce?blog_id=2"
响应
{
"id": 1,
"name": "WooCommerce",
"slug": "woocommerce",
"path": "woocommerce",
"description": "...",
"parent_project_id": 0,
"translation_sets": [
{
"id": 2,
"locale": "zh-cn",
"slug": "default",
"name": "Chinese (China)",
"stats": {
"all": 8378,
"current": 8378,
"waiting": 0,
"fuzzy": 0,
"untranslated": 0
},
"percent": 100
}
],
"sub_projects": [
{
"id": 2,
"name": "WooCommerce - Stable",
"slug": "stable",
"path": "woocommerce/stable"
}
]
}
2. GET /wp-json/gp/v1/originals
查询项目原文及其翻译状态,支持按状态过滤和分页。
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| project_path | string | 是 | - | GP 项目路径 |
| locale | string | 是 | - | 语言代码,如 zh-cn |
| blog_id | integer | 否 | 0 | 子站 ID |
| slug | string | 否 | default |
翻译集 slug |
| status | string | 否 | untranslated |
过滤状态:untranslated/current/fuzzy/waiting/all |
| per_page | integer | 否 | 50 | 每页数量(1-200) |
| page | integer | 否 | 1 | 页码 |
示例
# 获取 WooCommerce 未翻译的原文
curl -u "user:pass" \
"https://wpfanyi.com/wp-json/gp/v1/originals?project_path=woocommerce&locale=zh-cn&blog_id=2&status=untranslated&per_page=10"
# 获取已翻译的原文
curl -u "user:pass" \
"https://wpfanyi.com/wp-json/gp/v1/originals?project_path=woocommerce&locale=zh-cn&blog_id=2&status=current&per_page=5"
响应
{
"project": "woocommerce",
"locale": "zh-cn",
"slug": "default",
"total": 8378,
"page": 1,
"per_page": 5,
"items": [
{
"original_id": 1,
"singular": "Nuevo León",
"plural": null,
"context": null,
"references": ["i18n/states.php:943"],
"translation_id": 1,
"translation_0": "新莱昂",
"gp_status": "current"
}
]
}
3. POST /wp-json/gp/v1/translations
批量提交翻译。单次最多 100 条。
权限要求:用户必须拥有目标翻译集的 GP edit 权限。
状态逻辑:
- 用户有
approve权限 → 翻译直接设为current(已批准) - 用户无
approve权限 → 翻译设为waiting(待审核)
请求体(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| project_path | string | 是 | GP 项目路径 |
| locale | string | 是 | 语言代码 |
| blog_id | integer | 否 | 子站 ID |
| slug | string | 否 | 翻译集 slug,默认 default |
| translations | array | 是 | 翻译数组(最多 100 条) |
translations 数组项
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| original_id | integer | 是 | 原文 ID |
| translation_0 | string | 是 | 单数翻译 |
| translation_1~5 | string | 否 | 复数形式翻译 |
示例
curl -X POST -u "user:pass" \
"https://wpfanyi.com/wp-json/gp/v1/translations" \
-H "Content-Type: application/json" \
-d '{
"blog_id": 4,
"project_path": "bbpress",
"locale": "zh-cn",
"translations": [
{"original_id": 100, "translation_0": "论坛"},
{"original_id": 101, "translation_0": "主题"}
]
}'
响应
{
"summary": {
"submitted": 1,
"skipped": 1,
"errors": 0
},
"results": [
{
"original_id": 100,
"status": "created",
"translation_id": 5678,
"gp_status": "current",
"warnings": false
},
{
"original_id": 101,
"status": "skipped",
"translation_id": 1234,
"message": "Identical current translation exists."
}
]
}
结果状态说明
| status | 含义 |
|---|---|
created |
翻译已创建 |
skipped |
已存在相同的 current 翻译,跳过 |
error |
创建失败(附 message 说明原因) |
内部机制
翻译提交流程
- 通过
GP::$project->by_path()定位项目 - 通过
GP::$translation_set->by_project_id_slug_and_locale()定位翻译集 - 检查 GP 权限(
editontranslation-set) - 对每条翻译:
- 验证
original_id存在且属于目标项目 - 重复检测:比较所有复数字段(translation_0~5),相同则跳过
- 运行
GP::$translation_warnings->check()质量检查 - 调用
GP::$translation->create()创建翻译 - 调用
$translation->set_status()设置状态(处理 old/current 状态机)
- 验证
安全特性
- Application Password 认证(WP 5.6+ 内置)
- GP 权限层自动继承(基于
wp_get_current_user()) - 隐藏优先级原文(priority -2)对非项目管理员不可见
- 翻译质量警告自动检查
- 单次请求上限 100 条
多站点处理
使用 switch_to_blog() / restore_current_blog() 切换子站上下文,并重新初始化 GP 表名前缀(wp_N_gp_projects 等)。
环境配置
nginx
/www/server/nginx/conf/fastcgi.conf 需包含:
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
Application Password over HTTP
插件只在 local 和 development 环境覆盖 wp_is_application_passwords_available,用于反向代理终止 SSL 但 PHP 仍看到 HTTP 的开发环境。生产环境继续使用 WordPress 默认的 HTTPS 检查。
错误码
| code | HTTP | 说明 |
|---|---|---|
rest_forbidden |
401 | 未认证或无权限 |
gp_project_not_found |
404 | 项目路径不存在 |
gp_set_not_found |
404 | 翻译集不存在 |
gp_too_many |
400 | 超过 100 条限制 |
rest_missing_callback_param |
400 | 缺少必填参数 |