Internationalization and localization

Introduction to Meridix resource/translation files

Meridix Platform has support for multiple languages both for the user interface and for the report content (columns and descriptions). This article is meant to describe how the translation process for new languages can be handled for external translators.

Meridix uses a modified approach based on the default localization support in Microsoft.NET using RESX resource files. The RESX files are XML files with a specific scheme and each group of resources (translations) consists of a base file with the default and fallback language which in Meridix is English and additional translated files for different languages.
This means that if a localizable string can not be found in the currently selected language pack (ex: Swedish or Danish) the default English resource is used instead as a fallback value.
A resource files contains a key and a value and an optional comment that is only used during the translation to help the translator and is not used by the application.

Read more about the RESX file format here: http://msdn.microsoft.com/en-us/library/ekyft91f%28v=vs.80%29.aspx

The combination of the Resource file path with the key makes up a resource value. Ex: ResourceSets/ui/pages/Login.aspx.resx contains a key named lbnLoginResource1.Text which is used for the text on the login button on the login page.

The following naming scheme for the RESX files are used:

Name{.culture-code}.resx

Examples:

FilenameDescription
NameOfResource.resxThe default/fallback resource file. (English in Meridix)
NameOfResource.sv.resx or
NameOrResource.da.resx
A resource file with Swedish (sv) translations and a file with Danish translations.
NameOfResource.sv-SE.resx or
NameOfResource.sv-FI.resx
A resource file with Swedish (sv) translations but with support for a region as well.
For example sv-SE means Swedish (Sweden) while sv-FI means Swedish (Finland).
So it is possible to have different translations depending on the region of the users as well.

Example of culture codes are:

CodeDescription
enEnglish (no specific region)
en-GBEnglish (Great Britain)
en-USEnglish (United States of America)
svSwedish (no specific region)
sv-SESwedish (Sweden)
daDanish (no specific region)
da-DKDanish (Denmark)
noNorway
fiFinland

A full list of valid region codes can be found at http://azuliadesigns.com/culture-codes/

When creating the files its important that the specific languages resource files is located in the same folder as the base resource file, the structure of the files can not be changes since the system is dependent on the file paths to the base file.
Example of the folder structure in Meridix:

  • ResourceSets
    • translations
      • InformationMessages.resx
      • InformationMessages.sv.resx (Swedish)
      • InformationMessages.da.resx (Danish)
      • .......

Some of the translation contains numeric placeholders for numbers or other values, these placeholders must be included in the translated value as well. An example of a numeric placeholder is {0} or {1}, these characters is replaced with a value at runtime and should be present in any new translations as well if they exist in the base files value to get the correct behavior. Meridix has a custom built support for Custom placeholders as well, these placeholders has the syntax {=key:option} (See section below)

An example is:
Report has been running for {0} seconds

This text can now be displayed at runtime as:
Report has been running for 10 seconds
or
Rapporten har körts i 10 sekunder
(Swedish)

Integrating translations into Meridix

By default Meridix translations are built into the system at build time and can not be altered at runtime. So when a translator is done with the translation for a language the files (resx or excel depending on the approach) needs to be sent back to Meridix which will integrate the translation into the build process.

Custom placeholders

Meridix has support for a placeholder syntax where commonly used words or sentences can be reused throughout the resource files. This makes is easy to replace the naming for specific actions/features in the system. The placeholder functionality is used by the default translations files to allow a easier editing of the translations since you only need to define a word or phrase once.

All the placeholder values is located in a file called Placeholders.{.culture}.resx where the systems tries to find a specific translations for the current language first and if not found it will fallback to the base placeholder value located in the base file (Placeholders.resx).

The syntax used for placeholders is {=key[:option]}. The simplest usage of a placeholder value is {=key } where no options is defined. This value will be replaced with the translated value for the key value from the placeholder file. To allow maximum reuse of a placeholder value several options can be defined that decides how the placeholder value should be displayed. A option value is a suffix to the key starting with a : (colon) followed by the option key (Se list below for available option keys and their usage)

Multiple option suffixes can be combined and the will be evaluated in the order they appear. E.g. key:lowercase:capitalizefirst:uppercase will make all characters in upper case since the last option (uppercase) will change the previous option results.

Option keyDescriptionExample of usage
:lowercaseConvert all characters to lowercase before being used{=Username:lowercase}
:uppercaseConvert all characters uppercase before being used{=Username:uppercase }
:capitalizefirstConvert the first character uppercase before being used. This does not convert the other characters lowercase. Combine with :lowercase  to make only the first character in uppercase.{=Username:capitalizefirst}
{=Username:lowercase:capitalizefirst}
:htmlencode

Encodes the values to a valid HTML representation, replacing any characters that would otherwise be interpreted as HTML tags.
Uses the .NET HttpUtility.HtmlEncode() method internally. (http://msdn.microsoft.com/en-us/library/system.web.httputility.htmlencode.aspx)

{=Username:htmlencode }
:urlencode

Encodes the values to a valid URL representation that can be used a in query strings etc.
Uses the .NET HttpUtility.UrlEncode() method internally. (http://msdn.microsoft.com/en-us/library/system.web.httputility.urlencode.aspx)

{=Username:urlencode }
:htmlnbspConverts all spaces to   to prevent unwanted line breaks in HTML based user interfaces. Is only used when a web based UI is calling the placeholder feature.{=Username:htmlnbsp }

Placeholders can also be overridden just as any other resource. To override a resource define a package of the type package_translation_overrides (see next section) and the resource path should be defined as placeholders

Additional placeholder values can be added to the placeholder file and can then be used from any other resource file.

If a value from another resource file than the default placeholders file is needed a source prefix can be used {=source_resource_name@key:options} can be used where source_resource_name is the name of the resource file where the key can be found.

Custom translation overrides

There are a hook that allows a customer to override translations for a specific languages without altering the binary build. This feature is meant to allow a customer to enable a specific terminology to increase the user terminology recognition from other systems.
Custom text files can be created and uploaded as packages in Meridix containing lines in the format defined below, each of these files (packages) is then loaded and used as overrides to the built in (compiled) translations.

There are two types of formats that can be used.

Package format: CSV

Package type:
package_translation_overrides_text

Format:
"{langauge-code}";"{resourcepath}";"{key}";"{value}"

Note that the delimiter needs to be semicolons ;

Example of file content:
"sv";"Login.aspx";"lbnLoginResource1.Text";"I want to log in"
"sv";"Login.aspx";"lbnLoginResource1.ToolTip";"I want to log in right now"

This would override the values for the Swedish translation for the login button on the login page.
Naming:
The packages of the type package_translation_overrides_text can be named to anything you prefer to keep the files structured. The package names is not used by the system.

Package format: RESX

Package type:
package_translation_overrides_rex

Format:
Default RESX XML (http://msdn.microsoft.com/en-us/library/ekyft91f%28v=vs.80%29.aspx)

Example of file content:
...
  <data name="Login" xml:space="preserve">
    <value>Logga in</value>
  </data>
...
The example is only part of the full format.

Naming:
The naming of the package should be in the following format {resource_set_base_name}.{culture}.resx where the package name is used to identify the values and type of culture that the file contains translations for. To add a base/fallback resource set this way the "en" culture name should be used in the filename.


The file should be uploaded to the system as a package of the type package_translation_overrides_text or package_translation_overrides_resx depending on the package format.

Placeholder values can be overridden by specifying the resourcepath as placeholders

Working with the resource files

Since the translations are stored in a known standardized format there are several ways how they can be translated. The simplest but maybe not the most efficient solution is to export all the values to a Excel file and work with the keys and translations there. But there are several other open source tools that can assist the translator while translating the information as well as helping with the creation of files for new languages.

Tool: Excel

The simplest way to working with the resources is to get the list and work with the values there. When the translation process is complete the Excel file is sent back to Meridix that reintegrates the translated values to the RESX files.

Tool: Zeta resource editor

An open source (free) tool that Meridix uses internally is the Zeta resource editor found at http://www.zeta-resource-editor.com. This tool provides great assistance when working with the RESX files, Meridix also has specific solution files defined for the tool that groups the resources so that information that is visible to end users (non admin) are grouped in a way that lets a translator work with a specific part of the system in isolation in cases where the complete UI should not be translated.

When using Zeta resource editor the translator are working directly with the resource files and when the translation process is complete the resource files are sent back to Meridix to integrate back into the system.

The user interface lets you see all the available translations side by side as well as the comment for the value if its exist any.

The tool also has a project structure where Meridix has divided the resources by whether the content is visible to End user or only for administrators.

And if you expand the End user section the resources is displayed per RESX file sets (base + ex: sv and dk files)

Tool: SimpleResxEditor

Another open source (free) tool is SimpleResxEditor found at http://code.google.com/p/simpleresxeditor/ which also works with the RESX files directly. But this tool only allows the translator to work with only one resource set at a time.



Webpage: www.meridix.se
Email: support@meridix.se
Tel: +46 (0) 21 38 30 32