Dit product is onderdeel van Infowijs - een studio met maarschappelijk hart.
  • The basics


An important part of the Includable platform is its flexibility. One of the ways we try to make it flexible, is by supporting multiple languages in the user interface.

Adding translatable content

Using the $this->language object, it is easy to display localized content. The first step is adding your translations to the module.

Create translations files

Currently, custom translations only work for the web controller of your module, so it makes sense to store translations files in the web directory.



    "todo_intro": "Hello, {name}!",
    "todo_example": "Example"


    "todo_intro": "Hallo, {name}!",
    "todo_example": "Voorbeeld"

Referencing the translation files in module.json

Add a key translations under webOptions:



    "controllers": {
        "web": "web/index.php"
    "webOptions": {
        "translations": {
            "en_US": "web/locales/en_US.json",
            "nl_NL": "web/locales/nl_NL.json"

Using your translations

There are multiple ways to access your translations.

In your PHP code:


// Translation without context
echo $this->language->translate('todo_example'); // "Example"

// Using the l() helper function
echo l('todo_example'); // "Example"

// Using context variables
echo l('todo_intro', 'Bob'); // "Hello, Bob!"

In Handlebars templates:


<!-- Without context -->
<b>{{l 'todo_example'}}</b>

<!-- Expects the view to have a variable 'name' set -->
<h1>{{l 'todo_intro' name}}</h1>

Other language helpers


// Codes
echo $this->language->country_code(); // "us" (en_US) or "nl" (nl_NL)
echo $this->language->language_code(); // "en" (en_US) or "nl" (nl_NL)
echo $this->language->language_name(); // "English" (en_US) or "Nederlands" (nl_NL)

// Dates
echo $this->language->date($timestamp, 'short'); // "Sunday, January 1" (en_US) or "Zondag 1 januari" (nl_NL)
echo $this->language->date($timestamp, 'long'); // "Sunday, January 1 12:00" (en_US) or "Zondag 1 januari 12:00" (nl_NL)

// Relative times
echo $this->language->timeago($timestamp); // "4 hours ago" (en_US) or "4 uren geleden" (nl_NL)
echo $this->language->timeleft($timestamp); // "10 days left" (en_US) or "nog 10 dagen" (nl_NL)

// Currency
echo $this->language->currency(12532.56); // "€   12,532.56"
echo $this->language->currency(12532.56, false); // "€12,532.56"

// Pluralize
echo $this->language->pluralize(1, 'tiger'); // "1 tiger"
echo $this->language->pluralize(4, 'turtle'); // "4 turtles"
echo $this->language->pluralize(2, 'child', 'children'); // "2 children"

See the Language class documentation for more details.

Global access

In places where $this->language is not accessible (outside the global scope), Language::instance() can also be used to access the language object:


// This...
echo $this->language->country_code();

// Is the same as this:
echo \Language::instance()->country_code();

Supported locales

Currently, Includable supports the following locales:

Code English name Localized name Country code Language code
en_US English (US) English (US) us en
nl_NL Dutch Nederlands nl nl

Determining user locale

We attempt to determine the locale of the user from the language of their browser (header Accept-Language), if available. Otherwise, we default to en_US, with the possibility for the user to change the interface language from the user menu.

To be exact, this is the logic used to determine user locales:

  1. If GET-parameter locale is set (as in ?locale=nl_NL) and contains a valid locale identifier, we use that to set the locale.
  2. Otherwise, if a cookie exists with name locale and contains a valid locale identifier, we use that to set the locale.
  3. Otherwise, if there is a currently signed in user and that user has a attribute named locale, which is set to a valid locale identifier, we use that to set the locale.
  4. Otherwise, we try to determine the locale from the user's browser headers (i.e. Accept-Language) or default to en_US.

Collaborating on translations

If you wish to collaborate on translations with other non-technical people, try POeditor.com. To use it together with your Includable module, either manually import the JSON files as type JSON key-value, or set up an integration with Github.