Expression Engine i18n - internationalization

Does Expression Engine have a built-in solution for i18n (internationalization)?
I have to build a multi-language site, and would like to know the best approaches in EE for doing so.

There are many ways you can create a multilingual or country-specific site in ExpressionEngine to deliver content specific to each language/country.
The two most popular solutions are summarized from the following ExpressionEngine Wiki articles:
MultiLingual Websites in ExpressionEngine
The basic idea is to present your content in different languages using a combination of URL Segments, custom fields and a bit of PHP.
Advantages
Single entry manages multiple languages
Simple URL structure
As an example, say you have a 3-language site: English (en), Spanish (es) and German (de).
For every piece of content in your site, you'd create a custom field with the language identifier as a postfix (or prefix, whatever you prefer) to the fields.
Your custom field names might look like this:
custom_field_en
custom_field_es
custom_field_de
To switch between languages, simply add a corresponding URL segment (/en, /es or /de) that matches the language:
example.com/template_group/template/en
example.com/template_group/template/es
example.com/template_group/template/de
The main advantage of this approach is that it keeps all versions of your content inside a single entry, making updates and edits easy and consistent.
MultiLingual Websites in ExpressionEngine, Alternative
The alternative approach idea is to create sub-directories for each country, and use ExpressionEngine's path.php Global Variables to hold the country code and/or language as a variable.
Advantages
No PHP needed
No need to keep track of which segment holds the language variable
Elegant URL structure
Using the same 3-languages as an example from the first method, you would create a new directory in the root of your EE install and name it after the country code of the language you want to add:
Your folder structure might look like this:
+ /de
+ /en
+ /es
index.php
+ /images
+ /system
+ /themes
To allow this method work, place a copy of the main index.php inside each of the language directories. You would then modify each file by assigning variables corresponding to each language's directory:
$assign_to_config['site_index'] = 'http://www.example.com/en/';
$assign_to_config['global_vars'] = array(
"country_code" => "en",
"language" => "english"
);
The URLs built will use whatever language/country designation you choose:
example.com/es-MX/template_group/template/
example.com/MX/template_group/template/
The main advantage of the alternative approach is using Global Variables, leveraging the fact they are are parsed very early, and can be used almost anywhere in templates.
See: ExpressionEngine's Parse Order (PDF, 33 KB)
Other Solutions
Embracing the philosophy of ExpressionEngine, the flexibility you're given as a designer/developer allows you to tailor a custom solution that suits your unique needs.
If either of these approaches don't quite meet your needs, you can eaily craft your own method or take a hybrid approach.
With this in mind, a good starting point would be to look into the Multilingual Add-Ons at Devot-ee that may aide in your development.

Related

Single or multiple translation.json files for i18n?

I'm working a project in Aurelia and using the aurelia-i18n plugin. So far it looks great and translation is working and instantly updating interface language when I change locale.
Question: is there a logical, organizational or performance advantage to using multiple translation files vs. a single translation file? For instance:
Should I just put everything into one file?
my-aurelia/locales/en/translation.json
my-aurelia/locales/es/translation.json
Or should I separate into multiple translation files?
my-aurelia/locales/en/nav.json
my-aurelia/locales/en/words.json
my-aurelia/locales/en/phrases.json
my-aurelia/locales/es/nav.json
my-aurelia/locales/es/words.json
my-aurelia/locales/es/phrases.json
Here's how I have instantiated the plugin for this example (inside the export function configure(aurelia) { of my-aurelia/src/main.js, but I'm at an important design crossroads.
aurelia.use.plugin('aurelia-i18n', (instance) => {
// register backend plugin
instance.i18next.use(XHR);
// adapt options to your needs (see http://i18next.com/docs/options/)
instance.setup({
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
lng : 'es',
ns: ['words','phrases','nav'],
defaultNS: 'words',
attributes : ['t','i18n'],
fallbackLng : 'en',
debug : false
});
});
One json language file or multiple json language files? Any additional advice?
Performance-wise, a single file per language will be slightly faster on the initial load because fewer requests are necessary. However, this micro-optimization will be negligible, and you should put more value towards code structure and readability, especially for other people working on the code after you.
Will a single file become so large, that it will be hard for people to find the right entry, and change the content of the JSON file? If not, and you do not expect it to grow to such a size, you're probably best off using a single file.
Will people wonder if you put "Gracias/Thank You" in words (thanks) or phrases (thank you)? I recommend using a structure which is clear for someone who is not familiar with your code.
Lastly, one of the organization structures I have not seen you mention, but which I have used myself, is to order i18n files based on your views. This makes it easy to find the file which needs to be changed, as you already know which view you're working so you don't have to look for the i18n.

WinRT Localization - Multiple Translations per Language

I am building a Windows Store application in XAML/C# for a Windows 8.1 Professional environment.
My project has a requirement that I must support multiple languages in addition to multiple translations for any given language. For example, I may have a label that would be displayed in English or French, but in English it may need to display the word "Title" or the word "Heading" depending on the customer's preferences.
My issue is that I cannot figure out a way to package and switch between multiple resource dictionaries for the same language while still using the built-in localization functionality provided by XAML for WinRT (i.e. using the Uid property on my controls to bind them to a resource dictionary).
I've noticed two functions, ResourceManager.LoadPriFiles and ResourceManager.UnloadPriFiles, that I thought might allow me to swap out resource dictionaries at runtime, but I can't figure out how to get the PRI files to be package outside of the application's main resource map to allow the loading and unloading.
I've also considered creating a custom data binding or converter that I could use to bind the controls' text manually, but that would cost me the ability to see labels at design time in Blend as well as sacrificing the convenience of the built-in localization capabilities.
Another option was to compile a separate instance of the application for each of the custom translations the customer might require, but obviously that's not a very maintainable way of solving the issue...
Finally, I had considered repurposing something like the homeregion qualifier of the ResourceContext to solve the issue; however, that seems very limiting as there are already pre-established homeregions that I would have to choose from. Repurposing fields seems like a bad idea in general.
You can use several resources files and use the PrimaryLanguageOverride property to select a different language than the default one. This will allow you to change the current resources set without doing anything specific.
You can use a structure like this one for your resources:
Strings
+- en-US
+-Resources.resw
+- fr-FR
+-Resources.resw
+- fr-other
+-Resources.resw
Then in you code, you will just have to call any of the following lines :
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "fr-other";
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "fr-FR";
You application will now use the "fr-other" language. You can use up to 8 characters in the second part of the language tag.

Magento Translation

I have Magento 1.8.1.0. Recently I've installed Russian pack, the result wasn't appropriate enough, cause some phrases on frontend remained in English
I know there's handy way to translate Magento using cvs-files.
The question is where I can find proper cvs-file? Does installed theme concerns translation some how? I know I'm asking newbie questions, I've read several posts, but I haven't made up my mind how to translate Magento.
Many thanks in advance.
Hope you are doing well,
As i have gone through your question that you want to translate your websites front end in Russian if user has selected the language Russian.
For this you are required to work out the translate.csv files which will be available in your theme Package.
Example : app/design/frontend/default/SecuareWeb/locale/de_DE
In the locale folder you will find the folder for Russian language open that folder and you will find the file where you are required to add the required translation text in it.
How to add translation text in translate.csv file is given below.
Example:
"This is the demo of translation in Russian","Это демо-трансляции на русском языке"
And one thing i would like add is that make sure your front end .phtml files must contain the text in $this->__("Example");. If you have added all the text like this then only then it will allow you for translation other wise it will not translate a text.
Hope this might be use full to you !!!
Waiting for your valuable comments in regards to your Question !!!
There are different ways to achieve translation in Magento so you can find multiple directory containing static csv files and also a database table.
All the modes have same structure: key/value. For example: "String to translate","String translated".
Inline Translation (database table: core_translate):
following best practices in Magento, you should use inline-translation aka database saved translation in rare cases. It is harder to mantain and can be buggy. It has first precedence, so any translation you do via inline translation will override the other 'modes'.
Theme level Translation (file in app/design/frontend/your_package/your_theme/ru_RU/translate.csv):
you can place any string to be translated in the translate.csv. It has second precedence.
Locale translation (file in app/locale/ru_RU/Module_Name.csv):
the suggested way to do translation as it will keep translation separated by each module and is easier to maintain. For example: Mage_Catalog.csv etc.
Each module in Magento can specify its csv file containing translation and sometimes the same string has different modules trying to translate, so if your translation does not work check between multiple file by a quick editor search. It will be overridden by the two above modes.
Note:
Magento will load all the csv files and build up a giant tree and caches it. So before scratching your head because the string is not translated as you wished in the frontend:
1. clean the cache.
2. check for any same key string which comes after your translated string. For example: in the same csv Line 100 will override Line 1 if the key string are the same.
3. check for any same key string in the mode which has higher precedence. For example: inline translation will override any csv based translated string.
It may be easier for you to go to the admin backend System -> Configuration -> Developer and switch "Translate Inline" "Enabled for Frontend" to "Yes".
Then, refresh the frontend and you can change the translation directly at your web browser.
The translation is saved in the database table core_translate just for the case you want to do it in a test environment and copy the translation later on to the production.
Take care that without client restrictions (System -> Configuration -> Developer) everyone will see the translation options.
btw. You may need to clear the cache and refresh the webpage in order to see your changes.

wxWidgets: User defined (or from config), language dependent strings. How?

Our application (rewritten to wxWidgets) should use mostly common strings from the language catalogs (.mo). But it also uses panels with texts that are tailored for the customer via the configuration file. The configuration files are generated for the customer, so it could be (say) another catalog file. However...
Can one catalog file contain replacements (overwrites) for the default strings from the basic catalog?
Or, can the structure with strings loaded from the catalogs (.mo) be modified programmatically? (I mean if it can be done using some recommended way in the sense "Don't pee against the wind".)
Is there any standardized mechanism for storing the user-defined strings (via the same application)?
Thanks for your time and experience,
Petr
You can load several catalog files by using wxLocale::AddCatalog. The translations are searched for in all the catalogs loaded. If two catalogs contain the same string, I assume the translation is taken from the catalog that was loaded first. I didn't test though, admittedly. Anyway, if this is the case, you need to make sure the custom catalog file is loaded first. That way the translations in the custom catalog have precedence, and effectively they replace the default translations.

Internalizating content heavy pages into messagefiles seem cumbersome in play2?

Internalization in Play2 can be done with Message.get("home.title") and language files. What about when you internalizate a page full of textual content and not just one specific header or link?
For example doing Messagefile for a long page representing e.g. product info:
_First header_
Some paragraphs of text
...
_Tenth header_
Tenth paragraph and more text*
Messagefile
a)
product.info = "<many paragraphs of text including headers>"
or splitting one page into html elements
b)
product.info.h1 = "<first header>"
product.info.p1 = "<first para>"
product.info.p2 = "<2nd para>"
For me both solutions doesn't sound right. In first having a vast value for a single key seems bad convention and in latter separating a single page into dozens of keys doesn't sound good either.
Big websites often follow the convention www.site.com/en-us/product/1 of having the language in the URL. So the question is, how do i do in this way and is doing in this way a better way at all? I could easily end up not just translating to dozen languages but doing also dozen times layout changes.
I could use global codesnippets using Messagefile for elements that have a little text and doesn't change often e.g. navigation /view/global/header/somenavbar.scala.html but then i end up only having a complex folder structure.
Another way, a best practise, in Play 2 for internalization than messagefile?
Take a look to the Joscha Feth's solution in play_authenticate Java sample.
There are templates for emails in 3 languages for email confirmation, password reseting etc.
Template for each 'type' of email && each language is kept in single file ie:
_password_reset_en.scala.html
_password_reset_de.scala.html
_password_reset_pl.scala.html
_verify_email_en... etc
And for each 'type' there is an 'parent' template, which contains a condition (common Scala's match check the Tags section of template doc) which returns rendered view depending on detected language:
password_reset.scala.html
Finally, yes, at the beginning I also thought that some kind of madness, but believe me, that technique can be useful. There's field for further improvements I think. Maybe it would be better to move the language conditioning to the controller, hm I think that depends on many factors and it will be great if you'll find a time to investigate this topic.

Resources