动手搭建翻译协作平台
传统翻译过程是跑出项目中的中文文件,将文件发给翻译人员,翻译完成传回研发,研发再替换到项目中。(一般给翻译人员的是 excel 或者 txt,还需要脚本进行转换至 json 之类的格式);
进一步,待翻译文件被上传至在线文档,多名翻译人员可以同时翻译;
更进一步,使用专门的翻译协作平台, 如 Transifex, Lokalise, Crowdin,这些平台基本都集成了 github,gitlab 等仓库,也支持 api 访问。
因这些平台收费都不菲(企业 5000 刀/年),今天介绍的是开源的 weblate,基于其开源项目可以自行搭建协作平台。
安装
- 安装 docker,docker-compose
sudo yum install docker
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
- 下载 weblate
git clone https://github.com/WeblateOrg/docker-compose.git weblate-docker
cd weblate-docker && vi docker-compose.override.yml
创建 docker-compose.override.yml 文件
version: '3'
services:
weblate:
ports:
- 80:8080
environment:
// 发送邮件邮箱
WEBLATE_EMAIL_HOST: smtp.example.com
// 邮箱用户名
WEBLATE_EMAIL_HOST_USER: user
// 邮箱密码
WEBLATE_EMAIL_HOST_PASSWORD: ***
// 必须配置才能通过weblate.example.com访问
WEBLATE_ALLOWED_HOSTS: weblate.example.com
// 管理员密码
WEBLATE_ADMIN_PASSWORD: ***
// 站点域名
WEBLATE_SITE_DOMAIN: weblate.example.com
// 管理员邮箱
WEBLATE_ADMIN_EMAIL: admin@example.com
// 启动
docker-compose up
// 停止
docker-compose down
附上官方安装步骤
集成 git
将 ssh 密钥添加至 git 仓库
在组件的设置里配置 git 地址
设置文件模板
api 访问
如果对 weblate 的安全持有怀疑,weblate 也提供了 api 访问
- 上传
官方文档给了示例:
curl -X POST \
-F file=@strings.xml \
-H "Authorization: Token TOKEN" \
http://example.com/api/translations/hello/android/cs/file/
但是尝试了多次都失败了,一度怀疑是配置有问题,后来发现是缺少了 method,加上method: replace
就可以了
下面是用 node 实现的关键步骤
const program = require("commander");
const axios = require("axios");
const fsExtra = require("fs-extra");
const FormData = require("form-data");
// 获取相关参数
program
.option("-p, --path <path>", "翻译文件的路径")
.option("-o, --organization <organization>", "所属组织")
.parse(process.argv);
// 创建axiosBase
const axiosBase = axios.create({
baseURL: "http://xxx/api/",
headers: {
"Content-Disposition": "attachment",
"Content-Type": "multipart/form-data",
Authorization: "Token xxx",
},
});
// 获取所有需要上传的文件
const files = fsExtra.readdirSync(uploadPath);
// 组装formdata
let formData = new FormData();
formData.append("method", "replace");
formData.append("file", file);
formData.append("filename", fileName);
const headers = formData.getHeaders();
// 上传文件
await axiosBase.post(
`translations/${organization}/${componentName}/${fileLang}/file/`,
formData,
{ headers }
);
- 下载
翻译人员在平台上翻译完成后,再通过脚本将文案拉到项目中。
// 获取目标文件夹中所有需要下载的语言
const fileList = await fsExtra.readdirSync(outputPath);
// 下载所有语言的文件
fileList.forEach(async (file) => {
let [fileName] = file.split(".");
const res = await axiosBase(
`translations/${organization}/${componentName}/${fileName}/file/`
);
});
// 将文件写入本地
await fsExtra.outputFileSync(
`${outputPath}/${fileName}.json`,
JSON.stringify(res.data, null, 2),
"utf8"
);
如果国际化使用的是 kiwi,也可以支持,大致思路就是将导出的 txt 转为 json 再上传,翻译完成,下载后再转为 txt,关键包为 d3-dsv。