Language Translations

From 2.2 onwards we use Moodle's AMOS system to manage language translations. The language packs are stored on our servers and downloaded on demand when required.

The translations site is available here:

Request a login if you want to help with translations.

Prior to 2.2 language packs were distributed with the code and translations handled via a different site (now deprecated).

Coding for multi-language compatibility

Use get_string()

All text strings output to the page (including error strings) should be stored in a language pack and displaying using get_string() to allow for translations.

Formatting in language strings

There are situations where you may want to use basic formatting (such as bold, emphasis, paragraphs, lists and links) inside a specific language string. When doing this first consider if this should be done via a mustache template with multiple language strings referenced within the template (to allow theme designers to override the HTML in themes). If you are sure that the formatting belongs within a single string, the recommended best practice is to use Markdown to format the string, then in code convert the Markdown to HTML as follows:

format_text(get_string('setup_description_body', 'component'), FORMAT_MARKDOWN);

Not that conversion from Markdown is already automatically applied to help strings (those ending with '_help' used in help buttons), but not to other language strings at this time.

Use format_string()

All text strings coming from the database should be output using format_string(). This provides XSS protection, correctly escapes HTML entities and provides support for Moodle's multi-language filter.

Avoid concatenating strings

If you need to join strings or variables together, use placeholders. Concatenating strings together should be avoided because the grammar of other languages may require them to be joined differently:

Use UTF-8 character encoding and mbstring functions

Using htmlentities() without the 'encoding' argument will break in languages that rely on Unicode characters such as Cantonese (for PHP versions prior to 5.4).

Using strtolower() and strtoupper() will break too, instead use core_text (or textlib in older versions):

Functions ucfirst() and ucwords() shouldn't be used at all because the capitalisation rules are different in some languages.

If you really have to do it you can do following instead of ucwords():

There doesn't appear to be an easy solution for ucfirst() but there are some ideas in the comments here, or you could do something like:

function mb_ucfirst($str, $encoding = 'UTF-8') {
    return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding) .
        mb_substr($str, 1, mb_strlen($str), $encoding);
function mb_lcfirst($str, $encoding = 'UTF-8') {
    return mb_strtolower(mb_substr($str, 0, 1, $encoding), $encoding) .
        mb_substr($str, 1, mb_strlen($str), $encoding);

Most other text related functions such as substr() are implemented as methods in core_text (or textlib in older version).

Use language-aware date formats

Since dates are often displayed differently in different regions, many common date formats are stored as language strings so they can be correctly localised. Make sure you use them instead of hard coding the date format.

For example:Not:

Set the user language for emails/on cron

Be aware that Totara supports multiple languages at the same time (each user can pick their language). In some circumstances this means you need to specify the language you want to get a string in (by default this is the current user's language or the site's language if there isn't a current user).

For example if sending emails via the cron this won't take into account the user's language preference:You need to do this instead:

Right-to-left language support

Totara supports languages such as Hebrew and Arabic where text flows from right-to-left instead of from left-to-right. In those languages all UI features need to be mirrored horizontally. To ensure compatibility follow these guidelines:

Don't use inline styles. RTL languages need to override things like float:left to switch to float:right, so set alignment in the CSS then override it with a more specific selector. This includes avoiding using the 'align' attribute in print_heading.

Table columns are automatically reversed. If an image is directional (for example a progress bar that fills up from the left), create one facing the opposite direction and refer to it from the stylesheet or via PHP.


Try and keep right-to-left styles close to the styles they are overriding:In some cases you want when to override a style that you don't know the default value of, it's best to set the left-to-right style too:To conditionally replace images you'll need to use Moodle's file template syntax:PHP

You can find the current language direction in your PHP code using:


From Totara 2.4 there is a right_to_left() function for javascript too. In earlier versions you need to use YUI like this:

Testing RTL support

As of Totara 2.4.6 you can add a setting to your config.php file to force right-to-left text. This switches the direction but not the language allowing you to easily test RTL support. Just add the following to your config.php file while developing: