为pelican添加子站点功能


Table of Contents

创建翻译

babel-init:
    cd $(THEMEDIR) && pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot ./ && pybabel init -i messages.pot -d translations -l en

babel-update:
    cd $(THEMEDIR) && pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot ./ && pybabel update -i messages.pot -d translations

babel-compile:
    cd $(THEMEDIR) && pybabel compile -d translations

动态变量

在模板里,我有一些动态变量需要翻译,比如在分类里的 Python 需要翻译成 生活苦短,但很不幸, Babel并不支持动态变量的翻译。 刚开始,在我没使用i18n_subsites时,我采用加载一个i18n.html文件

{% macro gettext(string) -%}
{% set _gettext=dict(
    python='人生苦短',
    security='极客安全',
    archives='文章归档',
) %}
{{ _gettext.get(string.lower(),string) }}
{%- endmacro %}

类似字典的形式对部分变量进行翻译,这能够工作的很好,虽然有些麻烦。

在使用Babel之后,我想要把它和messages.po统一管理,所以采用另一种比较折中的方案: jinja2 filter

from babel import support

def gettrans(text, locale=DEFAULT_LANG):
    translations = support.Translations()
    catalog = support.Translations.load(
        os.path.abspath(os.path.join(THEME, "translations")), locale)
    translations.merge(catalog)
    if hasattr(catalog, 'plural'):
        translations.plural = catalog.plural
    return translations.gettext(text)

JINJA_FILTERS = {
    'gettrans': gettrans,
}

这样就可以通过传递变量来获取对应的翻译, 而我所需要做的就是写好messages.po然后编译成messages.mo即可,同样为了每次使用pybabel update 都可以得到相同的内容,我使用了一种取巧的办法, 同样是i18n.html文件,把所需要国际化的可能变量全部放到一起,但不要在其它模板里import这个模板,这样每次更新翻译文件,*Babel* 都能自动找到并生成相同的messages.po文件

{% macro gettrans(string) -%}
  {% set _gettrans=[
      _("Linux"),
      _("Python"),
      _("Security"),
      _("友链"),
      _("联系")] %}
{%- endmacro %}

这种方式同样解决了我的另一个问题: 我可能在中文站点使用的是英文变量,但需要显示翻译后的中文,而在英文站点使用英文变量,显示的却同样是英文。说起来比较绕口,简单来说就是,中文站点里有一个Python变量,我需要显示为人生苦短 , 而在英文站点,则显示为 Python,毕竟我可以在zh_CN/LC_MESSAGES/messages.po写上翻译后的内容,而在en/LC_MESSAGES/messages.po里保持原样,很方便地做到中英文分离。

作者: honmaple
链接: https://honmaple.me/articles/2018/06/为pelican添加子站点功能.html
版权: 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat