Localization / Translation Mechanism

There are four steps needed to translate / localize software:

  • marking localizable strings in the source files
  • generating the translation database/file
  • the translation process itself
  • the usage of translated content within the code

Marking Translatable Strings in the Source Files

In Perl code, all literal strings to be translated are automatically marked for translation:

$LanguageObject->Translate('My string %s', $Data)

This will mark My string %s for translation. If you need to mark strings, but not translate them in the code yet, you can use the NOOP method Kernel::Langauge::Translatable().

package MyPackage;

use strict;
use warnings;

use Kernel::Language qw(Translatable);


my $UntranslatedString = Translatable('My string %s');

In template files, all literal strings enclosed in the Translate() tag are automatically marked for extraction: [% Translate('My string %s', Data.Data )%].

In system configuration and database XML files you can mark strings for extraction with the Translatable="1" attribute.

# Database XML
<Insert Table="groups">
    <Data Key="id" Type="AutoIncrement">1</Data>
    <Data Key="comments" Type="Quote" Translatable="1">Group for default access.</Data>

# SysConfig XML
    <Option SelectedID="0">
        <Item Key="0" Translatable="1">No</Item>
        <Item Key="1" Translatable="1">Yes</Item>

In YAML text, you can mark strings for translation by appending # Translatable to the end of the target string.

   - Ticket Number # Translatable
   - Alice

Collecting Translatable Strings Into The Translation Database

The console command otobo.Console.pl Dev::Tools::TranslationsUpdate is used to extract all translatable strings from the source files. These will be collected and written into the translation files.

For the OTOBO framework and all extension modules, .pot and .po files are written. These files are used by translators to localize the software.

But OTOBO requires the translations to be in Perl files for speed reasons. These files will also be generated by otobo.Console.pl Dev::Tools::TranslationsUpdate. There are two different translation cache file types which are used in the following order. If a word/sentence is redefined in a translation file, the last definition will be used.

  1. Default framework translation file: Kernel/Language/$Language.pm
  2. Custom translation file: Kernel/Language/$Language_Custom.pm

Default Framework Translation File

The default framework translation file includes the basic translations. The following is an example of a default framework translation file.

package Kernel::Language::de;

use strict;
use warnings;

use vars qw(@ISA $VERSION);

sub Data {
    my $Self = shift;

    # $$START$$

    # possible charsets
    $Self->{Charset} = ['iso-8859-1', 'iso-8859-15', ];
    # date formats (%A=WeekDay;%B=LongMonth;%T=Time;%D=Day;%M=Month;%Y=Jear;)
    $Self->{DateFormat} = '%D.%M.%Y %T';
    $Self->{DateFormatLong} = '%A %D %B %T %Y';
    $Self->{DateFormatShort} = '%D.%M.%Y';
    $Self->{DateInputFormat} = '%D.%M.%Y';
    $Self->{DateInputFormatLong} = '%D.%M.%Y - %T';

    $Self->{Translation} = {
    # Template: AAABase
    'Yes' => 'Ja',
    'No' => 'Nein',
    'yes' => 'ja',
    'no' => 'kein',
    'Off' => 'Aus',
    'off' => 'aus',
    # $$STOP$$
    return 1;


Custom Translation File

The custom translation file is read out last and so its translation which will be used. If you want to add your own wording to your installation, create this file for your language.

package Kernel::Language::xx_Custom;

use strict;
use warnings;

use vars qw(@ISA $VERSION);

sub Data {
    my $Self = shift;

    # $$START$$

    # own translations
    $Self->{Translation}->{'Lock'} = 'Lala';
    $Self->{Translation}->{'Unlock'} = 'Lulu';

    # $$STOP$$
    return 1;



The language files for the new interface are now part of the built application (static JSON). When you add a custom language file to the file system, you need to rebuild the application for the change to be considered. To trigger the rebuild, restart the server with the --deploy-assets option:

otobo> /opt/otobo/bin/otobo.WebServer.pl --deploy-assets

During the build process, the language files will be refreshed and will take any *_Custom.pm into account.

The Translation Process Itself

OTOBO uses Weblate to manage the translation process. Please see Translating section for details.

Using The Translated Data From The Code

You can use the method $LanguageObject->Translate() to translate strings at runtime from Perl code, and the Translate() tag in Templating Mechanism.