docassemble allows you to write a single interview that asks questions differently depending on the user’s language and locale. It also allows Unicode to be used in user-facing text, user input, and documents. With these features, docassemble should be fully usable in languages other than English.
The value of
locale must be a locale name without the language
prefix, such as
DE.utf8. Any locale you use must be
installed on your system. (See the
other os locales configuration
Within interviews, the functions
set_locale() will change the active language, locale, and dialect.
(The dialect is relevant only for the text-to-speech feature, which is
controlled by the special variable
If you write functions that need to know the current language or
locale, use the
get_locale() function from
docassemble.base.util module. Also note that there is a
get_dialect() for retrieving the dialect.
The language and locale settings have the following effects:
- If you have a
translationsblock in your interview, then whenever docassemble processes a phrase (text that you can mark up with Mako templating), it will use the appropriate translation of that phrase if a translation for the phrase is present in one of the Excel files referenced in the
translationsblock. For more information about creating these Excel files, see the documentation for the Download an interview phrase translation file utility.
- Built-in words and phrases from the “core” docassemble code will
be translated into the active language. Whenever docassemble
prints such a word or phrase, it calls the
word()function from the
word('Login')will look up the word
Loginin a translation table. If the
word()function finds the word
Loginin the translation table for the active language, it will return the translated value. If it does not find a translation, it will return
Login. For more information about how
word()works, see functions. For information on how to define translations for a server, see the
wordsdirective in the configuration. For information on downloading a complete list of these phrases so that you can translate them into another language, see the documentation for the utility called Translate system phrases into another language.
- When docassemble looks for a
codeblock that defines a variable, it first tries
codeblocks for which the
languagemodifier is set to the active language (either explicitly or by operation of the
default language). If docassemble does not find any such
codeblocks, it looks for ones that do not have
languagemodifier set. This means that if your interview only uses one language, you do not need to worry about setting the
languagemodifier. If you are using the
translationsblock to translate all of the phrases in your interview, you probably will not need to use the
questionblocks, but you will need to use it on your
sectionsblock if you have one.
- Some functions have language-specific responses, such as
docassemble.base.utilmodule, which returns today’s date in a readable format such as “October 31, 2015” (for language
en) or “31 octobre 2015” (for language
fr). However, not all languages are supported by the
babel.datespackage; you may need to fall back to a different language. To configure how this works, set the
babel dates mapdirective in the Configuration.
- When docassemble highlights
termsin a question (see initial blocks), it will only highlight words specified in
termsblocks for which the
languageof the term matches the language of the question. Or, if the question does not have the
languagemodifier set, docassemble will look for a
termsblock that does not have
- When docassemble displays
interview helptext, it will only display the content of
interview helpblocks for which the
languagemodifier is the same as the language of the question. Or, if the question does not have the
languagemodifier set, docassemble will look for an
interview helpblock that does not have the
- If you have defined default text for various “screen parts” (such as
submit) using the
metadatablock and you defined values for multiple languages, docassemble will use the value for the current language.
If your interview only works in one language, do not set the
language modifier for any blocks, do not use
and do not call
simply make sure that the default
locale in the
configuration are set to the correct values.
If you have an interview that needs to function in multiple languages,
you will need to have
initial code that calls
docassemble does not remember the active language from one screen
to the next (in a multi-user interview, the language could depend on
who the user is), but the
initial code will make sure that it is
always set to the correct value.
code.yml- for language-independent initial blocks, interview logic, questions, and code blocks.
en.yml- for English-language
default language: enas the first line.
es.yml- for Spanish-language
default language: esas the first line.
interview.yml- the main file, which simply
includes the above three files.
Below is an example of a multi-language interview that asks the user
for a language, then asks for a number, then makes a statement about
the number. The interview is split into the four files listed above,
and all files reside in a folder called
bestnumber within the
The contents of
The contents of
The contents of
Finally, the contents of
While it is generally a good thing that docassemble allows you to
questions that make heavy use of Mako
templating, Markdown, and embedded Python code, a downside is that
all of this “code” can make the translation process more complicated.
Translators may be confused by all of the code. They may ask you to
convert your code to Microsoft Word, putting a great deal of
conversion work on you, or they may translate variable names when they
You may be tempted to change the way that you code interviews to
optimize for the needs of the tech-phobic translators you hire. For
example, if you have a single
question that has ten different
variations, you may decide to split this into ten separate
questions so that the translator has an easier time translating.
Or you might decide to remove Mako templating and substitute generic
language that is easier to translate.
However, there is no reason that you should have to make your interview less functional or less maintainable just because the translators you tried to hire were confused by “code.” The solution is to find a different translator. Although hiring a translator other than the “lowest bidder” could increase the out-of-pocket costs of your project, you should think about the net cost of your project, including your own time, and think about costs and benefits in the long term.
While there are many translators who will be confused by having to “translate around code,” there are also many translators for whom “translating around code” is not a problem at all. Companies like Morningside Translations regularly handle technical translations and provide quality control to ensure that the translators do not disturb embedded Python. Shop around before concluding that you have to “dumb down” your interview to make it translatable.
This will use the file
letter_en.docx if the language is English,
letter_es.docx if the language is Spanish, etc. This is
primarily useful if you are using the
translations block for
translating phrases and you are not using the
language modifier on
The documents feature that allows documents to be created from
Markdown text with Mako templating supports languages other than
English to the extent that RTF, Pandoc, and LaTeX do. LaTeX has
support for internationalization, and the default LaTeX template
will load either the polyglossia package or the babel package,
depending on what is available. The language used by LaTeX can be
set using the
mainlang in the
attachment specification. For some languages, you may need to write
your own templates in order to enable fonts that support your
language-specific functions], many of which are used internally
by docassemble object methods, can all be overridden with your own
versions. You can write special functions that should be used
depending on which language is the active language (as set by
set_language()). For example, there is an internal function
your() that when called as
The default language is English, and there are no definitions for any
other languages, so if you want to use a language other than English,
you will need to write alternatives. For more information about how
to do this, see the sections on language-specific functions and
simple language functions.
While many functions depend on the current language, there are a few
that depend on the locale. One is
nice_number() (one of the
language-specific functions that can be overridden). When the given
number is not among the numbers that should be converted to a word
update_nice_numbers()), it is formatted according to the
locale. For example, in locale
en_US (English, United States),
'6,242,235.4', but in locale
es_ES (Spanish, Spain), it becomes
Other locale-dependent functions are
currency_symbol(). In locale
en_US (English, United States),
'$101.34', but in locale
(Spanish, Spain), it becomes
'101,34 EUR'. In locale
(English, United States),
es_ES (Spanish, Spain), it becomes
The docassemble features that work with currencies are complicated
because the way that currency is represented depends on locale, and
you might want to support more than one locale, but Python’s
module assumes that the locale setting is server-wide.
currency() function and the
are both [language-specific function]s, which means that you can
substitute your own functions in their place in order to have full
control over currency formatting. For example, if you include the
following in a Python module, then whenever the active language is
French, the currency symbol will be € by default and the
function will return the number followed by €, instead of the currency
symbol followed by the number.
You can also override the default
currency_symbol() functions using the catch-all language
'fr'. You could use
update_locale()) in an
initial block and use
currency_symbol() functions to do different
things depending on the locale.
If you have a specific currency symbol that you want to use on your
server, you can set the
currency symbol directive in the
configuration. This will have a global effect. Suppose you set
this in the configuration:
This is equivalent to doing: