teedoc 国际化(i18n)(翻译)

国际化(i18n)简介

如果文档只使用一种语言,事情比较简单,但是事实是经常会遇到不同语言的使用:

  • 对于 teedoc, 必须支持足够多的语言,或者易于扩展翻译。 因为使用者可能使用的语言不尽相同, 可能是英语, 可能是中文, 也可能是其它语言, 哪怕使用者只使用一种语言

  • 对于使用者, 在使用时需要指定语言, 以让teedoc生成合适的翻译, 最后在没有翻译的时候能自定义文字,或者能参与翻译

所以国际化(Internationalization, 缩写 i18n)就十分重要, 下面对在teedoc中如何使用国际化进行介绍

文档指定语言

每份文档都有一个config(config.yaml或者config.json)文件,在其中加入locale即地域(地域对应了一种语言)关键字,比如 简体中文

{
    "locale": "zh_CN",
    ...
}

地域编号可以参考这里, 可以在维基百科查阅到, 或者使用程序来查看,比如

pip install babel
pybabel --list-locales

比如zh zh_CN zh_TW en en_US ja 等等

文档只有正确指定了语言,才能让部分文档的内容语言正确, 比如搜索插件的提示语言,不同语言的文档页面会生成对应语言的搜索提示信息

文档内容国际化(翻译)

如果你有一份文档,希望有其它语言的翻译,有几种方法:

  • 使用页面翻译插件,用户可以选择翻译到几乎任何语言,比如谷歌翻译插件teedoc-plugin-google-translate, 但是缺点是机器翻译可能有些地方会不准确
  • 用户自己使用浏览器自带的页面翻译功能,和插件的功能一样
  • 新建一份翻译文档, 进行人工翻译校对

如果需要人工翻译,则需要在site_config中进行配置translate关键字,比如编辑site_config(site_config.yaml或者site_config.json):

    "route": {
        "docs": {
            "/more/": "docs/more"
        }
    },
    "translate": {
        "docs": {
            "/more/": [ {
                    "url": "/more/en/",
                    "src": "docs/more/en"
                }
            ]
        }
    },

这样配置就是 docs/more 目录下的文档生成的 html 文件会在 out/more/ 目录下(也就是 url /more/);
英文源文件在docs/more/en 目录下,生成的网页页面url/more/en/下。
这样做的好处就是翻译文档里面可以直接使用相对路径引用主文档的资源文件,比如../assets/,不论是本地编辑器预览还是最终生成的网页都能正常预览图片,不用担心路径问题。

另外,你可能想将中英文翻译分开放置,比如docs/get_started/zhdocs/get_started/en目录,并且共用docs/get_started/assets的资源文件,会复杂一点,现已不建议这样使用:

    "route": {
        "docs": {
            "/get_started/zh/": "docs/get_started/zh"
        },
        "pages": {
            "/": "pages/index/zh",
        },
        "assets": {
            "/get_started/assets/": "docs/get_started/assets"
        }
    },
    "translate": {
        "docs": {
            "/get_started/zh/": [ {
                    "url": "/get_started/en/",
                    "src": "docs/get_started/en"
                }
            ]
        },
        "pages": {
            "/": [ {
                    "url": "/en/",
                    "src": "pages/index/en"
                }
            ]
        }
    },

这里有份文档"/get_started/zh/", 以及页面"/", 都是中文文档.
现在我们需要为他们三份文档添加英文翻译, 分别在translate -> docs下添加翻译, 翻译文档需要指定url(生成的路径, 需要/结尾)和src(翻译文档的根目录, 不需要/结尾)

可以看到这里手动指定了一个中英文文档共同使用的资源文件"assets", 这样在文档里面都可以用相对路径../assets来引用资源文件了并且在本地编辑器也可以预览。

然后

  • config(config.yamlconfig.json) 和 sidebar(sidebar.yamlsidebar.json) 复制一份到 翻译文档目录比如这里是"docs/get_started/en"
  • 修改configlocale值为en, 在navbar添加语言选项, type 指定为language
  • 翻译sidebar为英文, 结构需要和源文相同, 只是 label 不同, 若不相同在构建时会抱警告消息
  • 复制需要翻译的文档并翻译, 需要和源文档目录结构相同,如果用户通过侧边栏访问到了未翻译的文档,会自动显示no_translate.md页面,你也可以在翻译目录下新建一个no_translate.md文档来覆盖默认的,建议基于默认的修改
    "locale": "en",
    "navbar": {
        "items": [
            {
                "id": "language",
                "label": "语言: ",
                "position": "right",
                "type": "language"
            }
        ]
    }

布局模板国际化

使用自定义布局时,如果想要国际化,可以使用{{gettext}}来进行国际化,比如:

{{gettext("Hello world")}}

或者

{{_("Hello world")}}

执行teedoc build或者teedoc serve时会在layout/locales目录下自动生成翻译文件,手动编辑layout/locales/下的po文件即可。
也可以手动执行 teedoc translate 来更新翻译文件。

会自动生成layout/i18n_babel.cfglayout/i18n_locales.cfg两个文件,前者是设置扫描的文件,后者是设置需要翻译的语言,根据情况修改即可

除了使用 Jinja2 模板的 gettext 方法来翻译,你也可以用网页前端的方法来翻译,请自行查阅相关资料。

插件国际化

插件使用babel进行国际化渲染, 使用gettext定义的格式, 可以使用gettext 生成, 翻译文件格式为

  • pot: 翻译模板字符文件
  • po: 翻译字符文件
  • mo: 翻译编译后的二进制文件, 用于发布给程序使用

这里以teedoc-plugin-search为例,需要给搜索提示进行国际化

目录下有locales文件夹, 生成过程:

  • __init__.py中使用gettext来使用国际化, 在babel.cfg中设置了寻找py文件
  • 执行./trans_prepare.sh 生成翻译文件,会自动寻找使用了翻译的字符串
  • 手动翻译locales/语言目录/*.po
  • 执行./trans_finish.sh来编译po生成mo文件
  • 运行即可使用mo文件
  • 记得添加资源文件到setup.pypackage_data

对于 HTML template的渲染, 比如 teedoc-plugin-theme-default, 会自动从locales目录下查找翻译, 在模板中使用Jinja2语法使用即可,比如

{% trans %}需要翻译的语句{% endtrans %}

生成翻译的方法和上面所讲相同