Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Drupal 7 total language fallback

Parent Feed: 

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 ;)

Languages

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.

Edit language

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.

Language fallback settings

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:

  • field_language()
  • hook_field_language_alter()
  • locale_field_language_alter()
  • locale_field_language_fallback()
  • language_fallback_get_candidates()
  • hook_language_fallback_candidates_alter()
  • language_fallback_language_fallback_candidates_alter()

The last function does the job.

Language fallback chains

That's another feature only available from language fallback 7.x-2.x.

Edit language

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.

Before:

I18n overview, no patch

After:

I18n overview with patch

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.

Entity translations overview

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!

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web