Skip to main content
Contact us on +32 2 306 02 11 or mail us at info@desk02.be

Custom language negotiation in Drupal

When Desk02 created their own award-winning CMS MyCMS they had a clear vision on how the multilingual part of websites should work. The language switcher part was briefly discussed in my previous post and today I'd like to discuss the language negotiation part. Drupal offers out-of-the-box three different language negotiation methods. Two try to retrieve the language from the url and a third one uses the domain name. Since we've started using Drupal exclusively the past year-and-a-half we've been using these methods but were not really happy with how they function. Moreover they're tied to default language setting which has its own problems.

Default language negotiation options.

Default language and i18n

When you use the i18n module to translate taxonomies or block titles you should really be careful with the default language setting. When translating taxonomy terms or block titles through the i18n functionality Drupal will assume the source language is the default language of the site. For the rest of the interface English will alway be the default language. This means that if you start your site and you start creating taxonomy terms in English and translating them and you decide to modify the default language (eg. because you want the root page "/" to be in another language) you loose your translations but you can also restart entering the taxonomy term in the new default language. For this reason we wanted a solution where we can choose which language is active on the root page independent of the current default language.

Default language negotation drawbacks

The language negotiation options that Drupal provides have their own shortcomings. With the "Path prefix with language fallback" you have the problem that one url path can show different content depending on who visits the site since it uses the browser language to fall back to when the language prefix isn't in the url. We don't like the "Path prefix only" option because it doesn't show the language prefix for the default language. That means it's not immediately clear which language the url points to and it also means paths become invalid if you switch your default language. The third and last option "Domain name only" introduces new technical hurdles. You need to configure your http server and DNS. Managing sessions and cookies becomes more challenging and you scatter your content across different domains which might influence your search ranking.

What we wanted

We wanted a Drupal that worked the same way MyCMS worked before. Each page must have a language prefix and it should be able to configure if the root page is language independent (eg. when you want to use that page for a language/country chooser) or if it should be the home page for a particular language. Changing this setting also shouldn't break translation that were already made. An example to illustrate this. Say you have a site with two active languages: English (en) and Dutch (nl). If you set the language of the root page to Dutch you will have the following paths:

http://example.com → the home page in Dutch
http://example.com/en → the home page in English
http://example.com/nl → should redirect to /

All other nodes and views should always be prefixed, meaning that all other url's should start with en or nl.

If you set the setting to "language independent" it should work like this:

http://example.com → the site's home page, probably a language chooser
http://example.com/en → the home page in English
http://example.com/nl → the home page in Dutch

All other nodes and views should always be prefixed.

What we did

Since what we wanted didn't exist and we're Drupal developers we created it! We developed a small module called language_negotiation which modifies the language negotiation configuration screen and provides a core patch that introduces a new negotiation algorithm. It was not possible to completely encapsulate the functionality in a separate module since the language negotiation actively alters the path and should be run before the rest of the path bootstrapping code runs. There are no hooks that allow you to modify this behavior.

Customized language negotiation options.

Drupal 7

In Drupal 7 the language negotiation part has extensively been rewritten. There are now hooks to step in and modify the default behavior to your wishes. The concept of "interface language" and "content language" was introduced together with a lot of other things. If you want to know more you can start here:

I'll discuss the highlights of these changes and what they mean for site builders in another post. I'll probably also suggest a session about this for DrupalCon Copenhagen, so be sure to check back and vote for it.

Tags: Drupal, i18n

Comments

This awkward behaviour has been bugging me too.

We worked around the frontpage problem by creating a redirect in .htaccess for the root page when no language prefix was available.

This way, example.com always redirects to example.com/nl and no unpredicatable browser language fallback is ever used for the frontpage.

I installed the module and did the change and it does not work and the language switcher dissapears, am Idoing something wrong

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby>. The supported tag styles are: <foo>, [foo].
  • Feweb - Federatie van webontwikkelaars
  • Lid van Drupal Association
  • Sugar CRM