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, and the usage of translated data 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>
    ...
</Insert>

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

Collecting Translatable Strings Into The Translation Database

The console command otrs.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 OTRS framework and all extension modules that also use Transifex for managing the translations, .pot and .po files are written. These files are used to push the translatable strings to Transifex and pull the translations from there.

But OTRS requires the translations to be in Perl files for speed reasons. These files will also be generated by otrs.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;
}

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;
}

1;

The Translation Process Itself

OTRS uses Transifex to manage the translation process. Please see this 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 <#translate-tag>`__ in templates.