Drupal 7 total language fallback
Reasons for language fallback
Let's assume you have a website divided by countries. The site structure is:
- Global (en, de, fr)
- Germany (de)
- France (fr)
- Switzerland (de, fr)
You have your content translated to three languages. Normally, this works, but there could be cases when you need languages per country. Words might have a slightly different meaning from country to country (examples) or spelling might be different (en-US vs en-GB, or using "ß" in de-DE vs "ss" in de-CH). Or, for example, the "Contact us" page can contain a country specific information - locations.
So, the site structure can be turned to:
- Global (en, de, fr)
- Germany (de-DE)
- France (fr-FR)
- Switzerland (de-CH, fr-CH)
This can bring a translation nightmare until you have a language fallback ;)
Having the language fallback, you would only translate strings/content to the "base" languages and, in special cases, you may also translate to "country" languages.
Fortunately, there is a module for that. The Language fallback.
Language fallback 7.x-1.x
The first version of the module provides language fallback only for locale strings (strings that are passed through the t() function). After the module installation, you can find the "Language fallback" option at the language edit form.
If a string translation is missing for the de-CH language, the translation from the fallback language (de) will be used in this case.
How the locale fallback works
There is a strings override feature in Drupal 7 core. Basically, you can define translations for some strings via variables. For example, you can put something like that into your settings.php file:
$conf['locale_custom_strings_de-CH']['']['Home'] = 'Startseite';
While this possibility is used really rarely, the Language fallback module transforms it into the real power. It saves instances of the localeWithFallback class to locale_custom_strings_* variables. The localeWithFallback implements ArrayAccess, thus it can return string translations automagically.
Language fallback 7.x-2.x
We also want to have the language fallback for our content translated via the Entity Translation module. The second version of the Language fallback module provides this feature.
This option enables the translation fallback for entities on the field level. For example, if an entity does not have a certain field translated to the de-CH language, the de translation of this field will be used for the entity rendering.
How the entity translation fallback works
Actually, this ability is provided by the core Locale module. The Language fallback module just hooks into the process.
Here is the call stack describing how it works:
The last function does the job.
Language fallback chains
That's another feature only available from language fallback 7.x-2.x.
Now, on the language edit form, you can define several fallback languages in a particular order.
Language fallback 7.x-2.x-amazee
If you try to use the language-per-country workflow with the Language fallback module, the first thing you'll miss is the i18n support. The Internationalization module helps us to deal with the translation of menu links, field labels, panels, etc. So, we started work in this direction and have prepared a patch.
After the patch was tested, we found that it would be quite useful to have the fallback information displayed right on the translation overview pages. We implemented this feature, too.
We've submitted a patch containing both improvements to #2322883: Add support for i18n strings.
After using the new overview pages for some time, we decided to also improve the entity translation overview pages, since it improves the usability for content editors.
This developed into another patch #2444203: Show fallback information on the translation overview. This time, for the Entity translation module. (Be sure to enable the "Show fallback statuses on overview pages" checkbox on the admin/config/regional/entity_translation page after you have applied the patch.)
Language fallback for path aliases
There was an issue we have met implementing language fallback on our projects. The Pathauto module only generates aliases for the existing node translations. To fill that gap we have created the Path alias force module. It forces creation of aliases for all languages. Furthermore, it supports language_fallback, so aliases respect the fallback rules which is nice.
Total language fallback
Having all these patches applied, we have the complete solution for the language fallback on Drupal 7 websites. Now the language-per-country workflow can be used for real projects.
BTW. If you don't want to apply patches, you can use the Amazee Labs repositories which contain all required changes:
Let us know if you have any issues!