Skip to main content

It happens that there is a piece of code in some blocks or others objects that looks like this:

$this->__(‘Sorry, no quotes are available for order %s at this time.’, $orderId);

This is a localization method accepted everywhere in the framework. But does it work?

1. Method__() is specified in Mage_Core_Block_Abstract class (the base class of Magento’s blocks).

The first argument in the method (the key of a translation line, in the example – ‘Sorry, no quotes are available for this order at this time.’) is packed in the object of the class Mage_Core_Model_Translate_Expr.
Besides the key itself, the line with the module’s name is added to the object. A real block belongs to this name, for example, ‘Magenmagic_Customer’.
Then, the singleton of a type age_Core_Model_Translate is requested in the method of a current application object, and the list of arguments transfers in its translate() method.

2. Method translate() searches for the translation of the line in its own massive of translated lines via a call to the method _getTranslatedString().
The translated key is used as the first one in the arguments’ massive of a standard PHP function vsprintf(). Its result transfers as a completely translated line.
How is the inner massive of translated lines created?

3. While the object Mage_Core_Model_Translate is forming, its init() method is calling.
The method downloads translations from the modules’ configurations as well as from the current module (the one that has a block that calls to translation).

All branches of a type [area]/translate/modules ([area] – is adminhtml or frontend – depending on a current position) are selected from the global configuration.
As a rule, the branches of this type in the configuration files of modules are created by the code like this:


Everything in the branch <files> are searched in the directory app/local/[lang] ([lang] is Ru_ru, for example) and loaded in the inner massive of translations. Of course, translations’ creation isn’t limited by the downloads from the files.

After all translation files from the modules are downloaded, the file translate.csv is loaded which is in the locale directory of a current theme. At the end, the lines from the database are downloaded from the tab core_translate.

The data are delivered to the tab if in Admin area > Developer is enabled Inline Translation. In this case, all the texts on the showcase in the default theme will get a small icon. A click on this icon will open the popup for translation creation via ajax. I have to admit that this feature may not work in the commercial themes. One more note: the lines that are the same in the current locale are ignored in the process of translations downloading.

It means if a translation file has a line of a type:
“Sorry, no quotes are available for order %s at this time.”,”Sorry, no quotes are available for order %s at this time.”
This line will absent in the inner massive of translations and it will be used the key itself.

4. Priority of translations is obvious according to the info above. It should be admitted that a rewrite of the previous keys happens while downloading of the same keys from a module’s configuration, theme or database. It may seem that the highest priority will have translations from the database, then – from a theme and, finally, from the configuration.

Yes. But not exactly.

The reason is that the consideration of visible takes place in the method Mage_Core_Model_Translate::_addData() while downloading.
For example, our module is named Magenmagic_Quote and we’ve specified the line string to translate” for translation. There will be created 2 lines “string to translate” and “Magenmagic_Quote::string to translate” in Mage_Core_Model_Translate::_addData(). The key “Magenmagic_Quote::string to translate” will be searched the first when a translation is called in the method_ _ ().

That’s why if the code Magenmagic_Quote_Block_Info::__(“string to translate”) is running the line from the module Magenmagic_Quote will be used for translation, not the same line from another module and not the translation of the line “string to translate” from locale/translate.csv.
If this line is absent, the translation will be taken from locale/translate.csv, if there is no such line the translation will be taken from the others modules.

The question is: how can we use the translation from locale/translate.csv (and rearrange original key?)

The answer is: use the key in the form of “Magenmagic_Quote::string to translate”.

By the way, if you enable in-line translation >translate several lines via showcase > look at the tab core_translate, you’ll see this form of the translation line record in the section string: “Mage_Page::string to translate”.

5. How do other translation types in Magento work? (not the block types)

– Almost in the same way. Just take a look into a realization of the method Mage_Core_Helper_Data::__() (base core helper).
The translation code that starts there is almost the same to the code of base blocks’ class.


There are 3 translation sources: module’s configuration file, file with translations (localization) of a theme, a tab of in-inline translations (core_translate). All these sources can be used for localization.

Module’s configuration file is suitable for modules’ distribution, translation file of a theme is ok for a project’s customization, the tab is for local admin corrections.

If you use a name of a module before a translation line, it will set a higher priority for a translation variant within the code of a module.

Seems that an interesting part has ended.

Share your opinion in the comments below.

Vladimir Repalo

Vladimir Repalo

Magento Developer at Mobecls, 8+ years of experience. Feel free to ask me anything about this post in the comments below.