We have a plugin with user facing pages; Now is the time to think about making it translatable. It’s best to think about this early in your development as it becomes increasingly difficult the longer you put it off.

Having a translation system setup when you start to implement your plugin will help you save time, and encourage people to contribute translations early!


Koha added the functionality to pass the LANG variable to plugin templates with bug 25099 so translatable plugins are well supported since the release of 19.11.06.

The LANG variable contains the code for the language that has been selected by the logged in user. As such, your plugin can be aware of the language in which the strings must be translated.

Setting up the translation system

The basic concept is to have different translated template files served by the plugin for each translated language.

We can use an include file to group all the translatable strings for ease of translation.

Start by creating one empty file Koha/Plugin/FancyPlugin/i18n/default.inc and reference it from each of your templates as follows:

[% TRY %]
    [% PROCESS "$PLUGIN_DIR/i18n/${LANG}.inc" %]
[% CATCH %]
    [% PROCESS "$PLUGIN_DIR/i18n/default.inc" %]
[% END %]

Add new strings

Now add new “strings” to your template as [% T.your_string_code %] and set their default value in default.inc:

    T = {
        your_string_code = "This is an example string to translate",

To add a translated language, simply add a new file for language you would like to translate, for example Koha/Plugin/FancyPlugin/i18n/es-ES.inc:

    T = {
        your_string_code = "Esta es una cadena de ejemplo para traducir",

And that’s it, you now have an es-ES translation!

This is a naive, but very easy, way to handle translation.

In the future we will provide a more robust solution based on gettext, to correctly deal with language problems like plural forms and context.

Going further

It can quickly become a challange to keep the list of strings in all the include files up-to-date with new strings.

There is a script that could be useful in the case your plugin is getting bigger, see the file fetch_po.js from an existing plugin.

It will need small adjustements to make it work however.