Internationalising your Plugin/Theme

You are free to write your plugin and/or theme in whatever language you'd like, although if you wish to support multiple languages, NodeBB has a language engine that you can utilise.

In this article, we'll be referring to plugins. Keep in mind that themes are also plugins, so the implementation is the same for both.

Step 1: Directory layout of translations

To begin, let's define some language keys and translations! In your plugin, create a new directory to house your translations. Keep in mind that the structure of the files inside this folder must match that of NodeBB itself: Each sub-directory is named after a language key (e.g. en-GB), and contains .json files housing the translations themselves.

$ cd /path/to/my/plugin
$ mkdir -p languages/en-GB
$ mkdir -p languages/es

In the commands above, I've created my languages folder, with two languages, English (en-GB), and Spanish (es).

Step 2: Add your translations

In the sub-directories created in Step 1, I'll create text files with a .json extension. These file will house the plugin's translations.

In languages/en-GB/myplugin.json:

{
    "greeting": "Hello there! How are you?"
}

In languages/es/myplugin.json:

{
    "greeting": "Hola! Como estás?"
}

You can name the file whatever you'd like, but keeping it something recognizable (e.g. related to your plugin) is ideal. You can also name a file the same name as an existing language file in NodeBB. NodeBB will automatically merge the two localisation sets together into a single set. For example, NodeBB contains a user.json file. You can also name your file user.json and you can call language strings from both files in your plugin/theme.

Note: Remember to change the name myplugin to something related to your plugin!

Step 3: Tell NodeBB that you have language files to load

NodeBB won't automatically know you have translations to load, so we'll need to add a line to our plugin.json file to tell NodeBB to load our language files, and where those files reside.

Open up plugin.json and add a new property called languages:

{
    ...
    "languages": "languages",
    ...
}

The value for this property is the path to wherever your language files reside, relative to the plugin's root folder. In this case, I've placed my languages in a folder called languages directly in my plugin's root folder, so I just need to put in languages. If my languages were in a sub-folder called public, then the correct value here would be public/languages.

Step 4: Use your translations in your plugin

There are a number of ways you can use your translations in your plugin:

Server-side

In your server-side code, you can invoke the translation engine as follows:

var translator = require.main.require('./public/src/modules/translator');

translator.translate('[[myplugin:greeting]]', function(translated) {
    console.log('Translated string:', translated);
});

Client-side

In the browser, you can invoke the translation engine as follows:

require(['translator'], function(translator) {
    translator.translate('[[myplugin:greeting]]', function(translated) {
        console.log('Translated string:', translated);
    });
});

Templates

In your templates, you don't need to do anything special to invoke the translation engine, it is run through automatically, and parses any language strings matching the following syntax: [[resource:key]]. So for our plugin:

<p>[[myplugin:greeting]]</p>

(Optional) Step 5: Tell NodeBB that a particular language is the default

NodeBB itself supports around 40 languages, so you couldn't possibly be expected to translate them into every language! To define a specific language as default, add the defaultLang property to your plugin.json file:

{
    ...
    "languages": "languages",
    "defaultLang": "es",
    ...
}

Now, if a user utilising a language not supported by your plugin loads a language resource for your plugin, they will see the Spanish translation, as it is the designated fallback language.