name: translation-management description: 与翻译管理系统和国际化工作流程集成。连接 Crowdin、Transifex、Weblate,管理翻译记忆库,同步术语表,并自动化本地化流程。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep backlog-id: SK-010 metadata: author: babysitter-sdk version: “1.0.0”
翻译管理技能
与翻译管理系统和国际化工作流程集成。
能力
- Crowdin API 集成(上传、下载、状态)
- Transifex API 集成
- Weblate 集成
- 翻译记忆库管理
- 术语表同步
- 伪本地化生成
- 从文档中提取字符串
- 区域文件管理(JSON、XLIFF、PO)
使用场景
当您需要时调用此技能:
- 设置翻译工作流程
- 与 TMS 平台同步内容
- 管理翻译记忆库
- 生成伪本地化
- 提取可翻译字符串
输入参数
| 参数 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
| platform | string | 是 | crowdin, transifex, weblate |
| action | string | 是 | upload, download, status, sync-glossary |
| sourcePath | string | 否 | 源内容路径 |
| targetLocales | array | 否 | 目标翻译区域 |
| projectId | string | 否 | 平台上的项目标识符 |
| apiKey | string | 否 | 平台 API 密钥(来自环境变量) |
输入示例
{
"platform": "crowdin",
"action": "upload",
"sourcePath": "./docs/en",
"targetLocales": ["es", "fr", "de", "ja"],
"projectId": "my-docs"
}
Crowdin 集成
crowdin.yml 配置
project_id: 123456
api_token_env: CROWDIN_TOKEN
preserve_hierarchy: true
base_path: docs
files:
- source: /en/**/*.md
translation: /%locale%/**/%original_file_name%
update_option: update_as_unapproved
skip_untranslated_strings: true
export_quotes: double
- source: /en/**/*.json
translation: /%locale%/**/%original_file_name%
type: json
bundles:
- name: Documentation
patterns:
- "**/*.md"
labels:
- docs
languages_mapping:
locale:
pt-BR: pt_BR
zh-CN: zh_Hans
zh-TW: zh_Hant
Crowdin CLI 命令
# 安装 CLI
npm install -g @crowdin/cli
# 上传源文件
crowdin upload sources
# 下载翻译
crowdin download
# 检查翻译状态
crowdin status
# 使用翻译记忆库进行预翻译
crowdin pre-translate --method tm
# 上传术语表
crowdin glossary upload ./glossary.csv
Crowdin API 集成
const crowdin = require('@crowdin/crowdin-api-client');
const { projectsGroupsApi, sourceFilesApi, translationsApi } = new crowdin.default({
token: process.env.CROWDIN_TOKEN
});
// 上传源文件
async function uploadSource(projectId, filePath, content) {
const storage = await crowdin.uploadStorage(content, path.basename(filePath));
await sourceFilesApi.createFile(projectId, {
storageId: storage.data.id,
name: path.basename(filePath),
directoryId: await getDirectoryId(filePath)
});
}
// 下载翻译
async function downloadTranslations(projectId, locale) {
const build = await translationsApi.buildProject(projectId, {
targetLanguageIds: [locale]
});
// 等待构建完成
let status;
do {
await sleep(1000);
status = await translationsApi.checkBuildStatus(projectId, build.data.id);
} while (status.data.status === 'inProgress');
const download = await translationsApi.downloadBuild(projectId, build.data.id);
return download.data.url;
}
// 获取翻译进度
async function getProgress(projectId) {
const progress = await translationsApi.getProjectProgress(projectId);
return progress.data.map(lang => ({
locale: lang.data.languageId,
translated: lang.data.translationProgress,
approved: lang.data.approvalProgress
}));
}
Transifex 集成
.tx/config
[main]
host = https://www.transifex.com
[o:myorg:p:mydocs:r:documentation]
file_filter = docs/<lang>/**/*.md
source_file = docs/en/**/*.md
source_lang = en
type = GITHUBMARKDOWN
[o:myorg:p:mydocs:r:ui-strings]
file_filter = locales/<lang>.json
source_file = locales/en.json
source_lang = en
type = KEYVALUEJSON
Transifex CLI
# 安装 CLI
pip install transifex-client
# 推送源文件
tx push -s
# 拉取翻译
tx pull -a
# 拉取特定语言
tx pull -l es
# 检查状态
tx status
Weblate 集成
weblate.yml
project: my-docs
component: documentation
format: markdown
source_language: en
files:
- filemask: docs/*/index.md
file_format: md
template: docs/en/index.md
translation_memory: true
machine_translation:
- service: deepl
key_env: DEEPL_KEY
quality_checks:
- placeholders
- urls
- xml_tags
Weblate API
import wlc
client = wlc.Weblate(
url='https://weblate.example.com/api/',
key=os.environ['WEBLATE_KEY']
)
# 获取翻译状态
project = client.get_project('my-docs')
for component in project.components():
for translation in component.translations():
print(f"{translation.language}: {translation.translated_percent}%")
# 触发翻译记忆库重建
component = client.get_component('my-docs/documentation')
component.rebuild_translation_memory()
翻译记忆库
TM 管理
class TranslationMemory {
constructor(storage) {
this.storage = storage;
}
// 添加翻译到记忆库
async add(source, target, locale, metadata = {}) {
const entry = {
source,
target,
locale,
timestamp: Date.now(),
...metadata
};
const hash = this.hash(source);
await this.storage.set(`tm:${locale}:${hash}`, entry);
}
// 查找匹配项
async findMatches(source, locale, minScore = 0.7) {
const entries = await this.storage.getByPrefix(`tm:${locale}:`);
const matches = [];
for (const entry of entries) {
const score = this.calculateSimilarity(source, entry.source);
if (score >= minScore) {
matches.push({
...entry,
score,
matchType: score === 1 ? 'exact' : 'fuzzy'
});
}
}
return matches.sort((a, b) => b.score - a.score);
}
// 从 TMX 导入
async importTMX(tmxContent) {
const parser = new TMXParser();
const entries = await parser.parse(tmxContent);
for (const entry of entries) {
await this.add(entry.source, entry.target, entry.locale, {
importedFrom: 'tmx'
});
}
}
// 导出到 TMX
async exportTMX(locale) {
const entries = await this.storage.getByPrefix(`tm:${locale}:`);
return this.generateTMX(entries);
}
}
术语表管理
术语表格式
term,definition,context,do_not_translate
API,Application Programming Interface,Technical term,false
SDK,Software Development Kit,Technical term,false
OAuth,Open Authorization,Authentication protocol,true
术语表同步
async function syncGlossary(platform, glossaryPath) {
const glossary = await parseGlossary(glossaryPath);
switch (platform) {
case 'crowdin':
await crowdin.glossary.upload(glossary);
break;
case 'transifex':
await transifex.glossary.sync(glossary);
break;
}
return {
terms: glossary.length,
synced: true
};
}
function parseGlossary(path) {
const content = fs.readFileSync(path, 'utf8');
const rows = csvParse(content, { columns: true });
return rows.map(row => ({
term: row.term,
definition: row.definition,
context: row.context,
doNotTranslate: row.do_not_translate === 'true'
}));
}
伪本地化
生成伪区域设置
function pseudoLocalize(text, options = {}) {
const {
expansion: expansionFactor = 1.3,
accents: useAccents = true,
brackets: useBrackets = true
} = options;
// 重音字符映射
const accentMap = {
'a': 'ä', 'e': 'ë', 'i': 'ï', 'o': 'ö', 'u': 'ü',
'A': 'Ä', 'E': 'Ë', 'I': 'Ï', 'O': 'Ö', 'U': 'Ü',
'c': 'ç', 'n': 'ñ'
};
let result = text;
// 应用重音
if (useAccents) {
result = result.split('').map(char =>
accentMap[char] || char
).join('');
}
// 模拟文本扩展
const expansion = Math.ceil(text.length * (expansionFactor - 1));
const padding = '~'.repeat(expansion);
// 添加括号
if (useBrackets) {
result = `[${result}${padding}]`;
}
return result;
}
// 示例: "Hello" -> "[Hëllö~~~]"
工作流程
- 提取字符串 - 查找可翻译内容
- 上传到 TMS - 推送源文件
- 同步术语表 - 更新术语
- 监控进度 - 跟踪翻译状态
- 下载翻译 - 拉取已完成的翻译
- 验证 - 检查翻译质量
- 部署 - 构建本地化文档
依赖项
{
"devDependencies": {
"@crowdin/crowdin-api-client": "^1.30.0",
"transifex-api": "^0.2.0",
"csv-parse": "^5.5.0",
"xml2js": "^0.6.0"
}
}
CLI 命令
# Crowdin
crowdin upload sources && crowdin download
# Transifex
tx push -s && tx pull -a
# 生成伪区域设置
node scripts/pseudo-localize.js --input en --output pseudo
应用的最佳实践
- 保持源字符串具有上下文意识
- 维护术语表
- 使用翻译记忆库确保一致性
- 首先使用伪本地化进行测试
- 在 CI/CD 中自动化同步
- 将翻译与文档一起版本化
参考资料
- Crowdin: https://crowdin.com/
- Transifex: https://www.transifex.com/
- Weblate: https://weblate.org/
- XLIFF: https://docs.oasis-open.org/xliff/xliff-core/v2.1/xliff-core-v2.1.html
目标流程
- docs-localization.js
- terminology-management.js
- content-strategy.js