[Pelican] Localize Theme via Jinja2 Custom Filter


Introduction

Pelican static site generator and i18n_subsites plugin can help you build website or blog which supports multiple languages. When generating websites for each supported language, some strings in the theme need to be translated according to default language while i18n_subsites plugin generates sub-site for each supported language. There are several ways to localize theme:

  1. Use Jinja2 i18n extension in GNU gettext way as [2]:

    This way is good for big projects, but for small projects it is too tedious.

  2. Implement a gettext macro in theme as [3]:

    This way needs to put the code in the HTML theme, which is not good in terms of overall architecture.

Instead, this post shows another way to implement gettext-like filter in pelicanconf.py and ust it to localize theme (translate strings in the theme).

Solution

First implement a custom filter named gettext in pelicanconf.py as follows. Note that strings to be translated and translations are included in this filter, in this case en is default locale, zh and th are supported locales except en.

# custom Jinja2 filter for localizing theme
def gettext(string, lang):
    if lang == "en":
        return string
    elif lang == "zh":
        if string == "Archives": return "歸檔"
        elif string == "Categories": return "分類"
        elif string == "Category": return "分類"
        elif string == "Authors": return "作者"
        elif string == "Author": return "作者"
        elif string == "Tags": return "標籤"
        elif string == "Updated": return "更新"
        elif string == "Translation(s)": return "翻譯"
        elif string == "Edit on Github": return "在Github上編輯"
        else: return string
    elif lang == "th":
        if string == "Archives": return "สารบรรณ"
        elif string == "Categories": return "ประเภท"
        elif string == "Category": return "ประเภท"
        elif string == "Authors": return "ผู้เขียน"
        elif string == "Author": return "ผู้เขียน"
        elif string == "Tags": return "แท็ก"
        elif string == "Updated": return "การปรับปรุง"
        elif string == "Translation(s)": return "การแปล"
        elif string == "Edit on Github": return "แก้ไขที่ Github"
        else: return string
    else:
        return string

JINJA_FILTERS = {
    "gettext": gettext,
}

Strings to be localized in the theme are marked as follows, and i18n_subsites plugin will replace strings according to DEFAULT_LANG setting while generating subsites of each language.

<!-- mark all the strings to be localized ... -->
<span>{{ 'Archives'|gettext(DEFAULT_LANG) }}</span>
<span>{{ 'Updated'|gettext(DEFAULT_LANG) }}</span>
<span>{{ 'Author'|gettext(DEFAULT_LANG) }}</span>
<!-- ... -->

For full working example, see [1].


Tested on: Ubuntu Linux 16.10, Python 2.7.12+, Pelican 3.7.0.


References:

[1]use Jinja2 custom filter to localize theme · siongui/pelican-template@b7dcda2 · GitHub
[2]Localizing themes with Jinja2 - i18n_subsites - pelican-plugins
[3][Pelican] Translate String According to Default Language in Theme
[4][Pelican] Get Single Page or Article by slug Metadata in Theme