An overview of converting localization formats with Logen

David Piper
3 min readAug 25, 2019

--

Welcome back to part two of my series on generating localizations for multiple platforms with Logen. In this article I’m going to explain the structure of the python project. If you want to know why and how to use my tool, check out part one.

An Overview of how the converting works

The main components of Logen are converters which can handle various formats of localization files. Any converter inherits from the base class ConverterInterface and thus needs to implement a bunch of methods. Some of them provide metadata, but the key components are two methods, one to import and one to export content of the converter’s specific format.

The import method reads and parses the content of a file, which results is an instance of the class IntermediateLocalization. The export method takes this IntermediateLocalization and writes it out using a specific format. The result is an instance of LocalizationFile, which holds the content of a localization file before it is written to the destination path.

Using this structure, converting a given format to a new format is done in two steps:
1. A converter, which can parse the given format, imports the content and instantiates an IntermediateLocalization.
2. Another converter, which knows how to write the desired format, takes this IntermediateLocalization and creates an instance of LocalizationFile.

The separation of importing and exporting with different converters has multiple advantages:

  • Each converter only needs to know how to read/write its own format.
  • It’s easy to add new converter, because there are no dependencies to other converter.
  • Converters have a good testability, since you can check against an expected IntermediateLocalization for testing the import and against an expected LocalizationFile for testing the export.

Exploring the result of import: IntermediateLocalization

An IntermediateLocalization represents the content of a localization without platform specific format. It encapsulates an identifier of this localization and a list of IntermediateLanguage objects and thus assembles all languages of one localization.

Each IntermediateLanguage can be considered to be the content of one localization file. It includes a language identifier, e.g. en for English, as well as a list of IntermediateEntry objects.

These entries are the most basic parts of this structure. They contain a key, a value and a comment. One IntermediateEntry corresponds roughly to one element in a localization file.

Exploring the result of export: LocalizationFile

Since some localization formats require a specific directory structure — e.g. for an iOS app the file needs to be in a directory named languageIdentifier.lproj with languageIdentifier being the language code of the localization — the converter actually does not write the file itself and thus doesn’t need to know how and where to create new files and directories. Instead it will create an instance of LocalizationFile which encapsulates the content as well as the needed directory structure.

This is especially useful for testing the result of a converting process, because the test case does not need to read a generated file and validate its content, it can check the content of the resulting LocalizationFile directly. Also this reduces the responsibilities of a converter, it does not need to know anything of how to create or write to a file.

Currently available converter

In version 1.0.0 Logen is shipped with 4 different converter. You can use the subcommand list to see more information about these converter.

  • iOS: Knows how to read and write a .strings file containing the localization of an iOS app.
  • iOS Enum: Generates a Swift enum listing all keys for a localization file. This provides convenient access to the exported key when using the localization file in an app. But this converter does not have an import method, because these enums do not contain the localized values and thus can’t be imported to a full localization.
  • Android: Parses a given .xml file or creates a localization file for an Android app.
  • JSON: This converter takes a json file with the format
    { filename: { language: { key: value } } }
    and converts it into an intermediate localization when importin and the other way around when exporting. I use this structure for my personal projects, because then I definitely know the source of my localizations. If I would use an iOS localization file or an Android localization file, I may be confused, which file should be generated from which.

That’s it for now! Part three will be a deep dive into the structure of the project and the final part four will be a tutorial on how to add a new custom converter for your own format!

--

--

David Piper
David Piper

Written by David Piper

Working as an iOS and Android dev.

No responses yet