# Lektor i18n plugin This plugin enables a smarter way to translate a [Lektor](http://getlektor.com) static website using old-good PO files. So you can use your beloved translation processes and tools. ## Principles The idea of this plugin is to capture the **sentences** or **paragraphs** from your **content** and **templates**, and populate a standard *Gettext* [PO file](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html). Using usual tools, user can translate these files, very easily. Then the plugin will merge the translations into new [_alternative_](https://www.getlektor.com/docs/content/alts/) content files, providing a translated website. ## Configuration ### Configuration file #### `configs/i18n.ini` content = en translations = fr,es,it i18npath = i18n translate_paragraphwise = False Where : * `content` is the language used to write `contents.lr` files (default is `en`) * `translations` is the list of target languages (you want to translate into). * `i18npath` is the directory where translation files will be produced/stored (default is `i18n`). This directory needs to be relative to root path. * `translate_paragraphwise` specifies whether translation strings are created per line or per paragraph. The latter is helpful for documents wrapping texts at 80 character boundaries. It is set to `False` by default. #### `babel.cfg` If you plan to localise your templates as well, you can use `{{ _("some string") }}` in your templates. To make this work, pybabel should be installed (pip install pybabel; maybe pip3). A `babel.cfg` also has to exist in your project root with this content: [jinja2: **/templates/**.html] encoding = utf-8 extensions=jinja2.ext.autoescape,jinja2.ext.with_ ### Translatable fields In order for a field to be marked as translatable, an option has to be set in the field definition. Both blocks and flowblocks fields are subjects to translations. in `flowblocks/*.ini` and/or `models/*.ini`, mark a field as translatable with : [model] name = Page label = {{ this.title }} [fields.title] label = Title type = string translate = True [fields.body] label = Body type = markdown translate = True Both `title` and `body` are now translatable. It means that during the parsing phase, all sentences from `title` or `body` fields from the `contents.lr` files with `Page` model will populate the collected PO file. Another flowblock example: [block] name = Section Block button_label = Section [fields.title] label = Title type = string translate = True [fields.body] label = Body type = markdown translate = True [fields.image] label = Image type = select source = record.attachments.images [fields.image_position] label = Image Position type = select choices = left, right choice_labels = Left, Right default = right Here again, `body` and `title` will be translated. But `image` and `image_position` won't. ### Non-english content Thanx to a limitation of msginit it's not so easy to translate a website with default language set to anything but english. So if your default content language is not english, you will have to edit the first `contents-en.po` file and remove the translations (by hand ?)... ## Installation ### Prerequisites #### Lektor This plugin has been tested with `Lektor 3..0.x`. #### GetText Both Gettext and Pybabel are required. For a Debian/Ubuntu system, this means a simple : sudo apt-get install gettext python3-babel On macOS, use a decent package manager, like MacPorts or Homebrew. With Homebrew: brew install gettext and then pip to fetch pybabel: pip install babel ### Installation Very straightforward : $ lektor plugins add lektor-i18n Verify installation with a simple : $ lektor plugins list ... lektor-i18n (version 0.1) ... ## Usage The translation mechanism is hooked into the build system. So translating a website just means building the website. $ lektor build On first call, a new `i18n` directory (can be changed in configuration file) will be created on top the lektor tree. This directory will be populated with a single `contents.pot` file, compiling all the sentences found by the plugin. The list of fields eligible to translation is configured in the models/flows definition with `translate=True` added to each field. For each translation language (still from the configuration file), a `content-.po` file will be created/updated. These are the files that need to be translated with your prefered tool (like [POEdit](http://poedit.net) or [Transifex](http://transifex.com)). All translation files (`contents-*.po`) are then compiled and merged with the original `contents.lr` files to produce all the `contents-.lr` files in their respective directories. Due to the way Lektor building system is designed, all these steps happen on every build. This means that sometime, after translating the `contents-*.po` files, it might be required to run the build system twice to see the translation appear in the final HTML files. ### Project file It's still the user responsability to modify the project file in order to include the expected languages : [alternatives.en] name = English primary = yes locale = en_US [alternatives.fr] name = French url_prefix = /fr/ locale = fr See [Lektor Documentation](https://www.getlektor.com/docs/content/alts/) for more information. ## Support This plugin is provided as-is by [NumeriCube](http://numericube.com) a human-sized Paris-based company prodiving tailored services to smart customers. We will be happy to try to help you with this plugin if need. Just file an issue on our [GitHub account](https://gihub.com/numericube/lektor-i18n-plugin/).