Welcome | Get started | Dive into Lino | Contribute | Reference
How to contribute translations¶
Here is how your can help translating Lino into your language.
We assume that you have installed a contributor environment of Lino.
Background knowledge¶
You are going to edit a series of .po
files which are part of the Lino
source code. Each Lino repository has its own series of .po
files.
Their place is given by the locale_dir
setting (see
Project configuration settings). Here are some examples:
lino
: lino/localelino_xl
: lino_xl/lib/xl/localelino_noi
: lino_noi/lib/noi/localelino_cosi
: lino_cosi/lib/cosi/localeetc.
If the .po
do not yet exist in your language read Add support for a
new language before going on.
If you are the first to provide translations to some source code that has new or
changed translatable strings, you must run inv mm
("make message files")
in order to make sure that the .po
files are in sync with the source
code. The inv mm
command never deletes any messages, so you can run it
also when you aren't sure whether it has run.
To edit these .po
files you can use either your preferred text
editor or a tool like Poedit. We recommend the latter.
On Debian you install it with apt-get install poedit
.
Choose a site to work on¶
Don't simply translate all the messages in the django.po
files because
some translations depend on the context. It's better that you see where a message is being used before you decide how to translate it.
don't try to translate all messages at once. It's more satisfying to start with the most visible ones and to see the results your work while you are evolving.
Go to some demo project or to some local site directory (e.g. the one you created in Install your Lino developer environment):
$ go first
Edit your project's settings.py
file so that
it specifies a language distribution (in the
languages
setting) consisting of
English as first language
your language as the second language.
The first language cannot be your language because some demo fixtures would fail (https://gitlab.com/lino-framework/lino/blob/master/docs/tickets/108).
Your settings.py
file should look similar to this:
# -*- coding: UTF-8 -*-
from lino_book.projects.min9.settings import *
class Site(Site):
title = "My Lino Mini site"
languages = 'en es'
SITE = Site(globals())
Initialize the demo database:
$ python manage.py prep
Run the development server:
$ python manage.py runserver
Point your browser to view the site. Sign in as the user in your language.

Find the strings that you want to translate¶
The translatable strings on this page (gettext and Poedit call them "messages") are for example the menu labels ("Contacts", "Products" etc), but also content texts like "Welcome", "Hi, Rodrigo!" or "This is a Lino demo site."
Now you must find out which django.po
file contains these strings. For
example, you can open another terminal window and use grep to find
the file:
$ grep -H Contacts ~/repositories/lino/lino/locale/es/LC_MESSAGES/*.po
/home/repositories/work/lino/lino/locale/es/LC_MESSAGES/django.po:#~ msgid "Contacts"
$ grep -H Contacts ~/repositories/xl/lino_xl/lib/xl/locale/es/LC_MESSAGES/*.po
/home/luc/repositories/xl/lino_xl/lib/xl/locale/es/LC_MESSAGES/django.po:msgid "Contacts"
/home/luc/repositories/xl/lino_xl/lib/xl/locale/es/LC_MESSAGES/django.po:msgid "Client Contacts"
/home/luc/repositories/xl/lino_xl/lib/xl/locale/es/LC_MESSAGES/django.po:#~ msgid "Contacts"
Translate¶
Launch Poedit on the django.po
file for the Spanish translation:
$ poedit lino/locale/es/LC_MESSAGES/django.po
It looks similar to this screenshot:

Translate a few messages. In our example we translated the following message:
Hi, %(first_name)s!
into:
¡Hola, %(first_name)s!
Save your work in Poedit. Poedit will automatically compile the
django.po
file into a corresponding django.mo
file.
Now you should first touch your settings.py file in order to tell
runserver
that something has changed. Open a third terminal window and
type:
$ go first
$ touch settings.py
This will cause the server process (which is running in the first terminal window) to reload and to rewrite any cache files.
Refresh your browser page:

Submit your work¶
When you are satisfied with your work, you must make a pull request to ask us to integrate your changes into the public Lino repositories. More about pull requests in Git cheat sheet.
Add support for a new language¶
Lino uses the same language codes as Django. You can see the list of available languages in django/conf/global_settings.py.
Every repository has a list of languages for which it provides translations.
This list is in the languages
parameter in the repository's
tasks.py
file. If your language is not yet mentioned there, then add
it.
After adding a language, you must run inv mm
, which will create the new
catalogue files.
And then you probably want to create a demo user for your language. Otherwise
pm prep
gives a warning:
No demo user for language 'bn'.
There are three ways to do it:
Do this manually by signing in as robin and changing the language field in robin's user preferences. You will have to do this again and again after each
pm prep
.Edit the demo_users.py <https://gitlab.com/lino-framework/lino/-/blob/master/lino/modlib/users/fixtures/demo_users.py> file in your local copy of the lino repository.
And don't forget to include this change in your pull request (see Submit your work)
Create a local fixture that creates the user:
$ mkdir fixtures $ touch fixtures/__init__.py $ nano fixtures/demo.py
The demo.py
file should look as follows:
# This is needed only if Lino does not yet have a default site
# administrator for your language.
from django.conf import settings
from lino.modlib.users.choicelists import UserTypes
def objects():
yield settings.SITE.user_model(username="roberto", language="es",
first_name="Roberto",
last_name="Spanish",
email=settings.SITE.demo_email,
user_type=UserTypes.admin)
Trucs et astuces¶
Voici un pitfall: la traduction du string suivant:
msgid "%(person)s has been unregistered from %(course)s"
ne doit pas être:
msgstr "%(personne)s a été désinscrit du %(cours)"
mais bien:
msgstr "%(person)s a été désinscrit du %(course)s"
C.-à-d. les mots-clés entre parenthèses sont des variables, et il ne faut pas les modifier.
À noter également que le s
derrière la parenthèse ne sera pas
imprimé mais est obligatoire
(il indique à Python qu'il s'agit d'un remplacement de type string).