DEPRECATION WARNING

This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.

Language router

Build Status

A simple extension providing redirects to languages or pages, both for single- and multi-tree setups, based on user agent language and/or geoip.

TypoScript Example:

plugin.tx_languagerouter.settings {
    redirectCookie {
        // Redirect regardless if a redirect has already been made (which sets a cookie).
        // This is especially useful if you have a visitable landing page that not just redirects.
        disregard = 1
        
        // Alternatively, setting disregard = 0 (default) but an expiration date, the
        // cookie will expire after the given amount of seconds, leading to a redirect
        // each time a cookie is either expired or not set.
        expirationInSeconds = 21600
    }
    
    routes {
        // First priority: Route by country, detected from geoIP.
        1 {
            // This will return a 2-char country code.
            detection = country
            targets {
                // Redirect to the current page with L = 1.
                DE.L = 1
                
                // Redirect to our special page (id = 13) in default language (L = 0) to choose country language.
                CH {
                    L = 0
                    id = 3
                }
            }
        }
        
        // Second priority: Route by browser language
        2 {
            // This will return a locale.
            detection = acceptedLanguages
            
            settings {
                qualityTreshold = 0.6
            }
            
            targets {
                // Redirect to our special page (id = 4) in German (L = 1).
                de_CH {
                    L = 1
                    id = 4
                }
                
                // Redirect to our special page (id = 4) in French (L = 2).
                fr_CH {
                    L = 2
                    id = 4
                }
                
                // Redirect to our special page (id = 4) in Italian (L = 3).
                it_CH {
                    L = 3
                    id = 4
                }
                
                // Fallback and general German language: Redirect to the current page with L = 1.
                de_DE.L = 1
            }
        }
        
        // Third priority: If 1. and 2. don't match anything.
        3 {
            detection = fallback
            
            // Attention: "No detection" can't have multiple targets, that' why it's "target".
            target {
                L = 23
            }
        }
    }
}

Usage

Language router can be used in two ways:

  1. Include the provided plugin element on a landing page that is intended to redirect your visitors to the correct starting point.
  2. Add the plugin via TypoScript

Be aware that the plugin is of type USER_INT which leads to the page(s) it is used on being uncached.

Detection types.

Language router provides the following detection types:

Detection: acceptedLanguages

The acceptedLanguage detection mode reads the HTTP_ACCEPT_LANGUAGE parameter and parses all accepted languages. This parameter usually contains one locale (like de_CH) and a few language codes that are also supported (like de, en, fr). Language codes are also converted to locales (as in de_DE for de, en_EN for en and fr_FR for fr) to have a consistent configuration.

Explanative exampleIf your operating system has set English as its preferred language, and German as it's second one, your browser may send an HTTP_ACCEPT_LANGUAGE header that looks like this:

en-US,en;q=0.8,de;q=0.6,fr;q=0.4

This will then process en_US, en_EN, de_DE, fr_FR, in this order. You can skip languages below a certain quality level by setting settings.qualityTreshold.

Before any redirect, the current page uid and language parameter is compared to the configured one, in order to not end up in a redirect loop.

Detection: country

The country detection relies on php-geoip being available. If it is not available, the country detection configuration is being ignored. To get information about whether you can or cannot use this detection type, a status report is provided, which you'll find in the System > Reports backend module.

In order to compare the current page's country with the configured one, you must set config.country for any language condition block, otherwise language router will not know to which country the currently rendered page belongs to, and ends up in a redirect loop.

Example:

[globalVar = GP:L=1]
    config {
        sys_language_uid = 1
        language = de
        locale_all = de_CH
        country = CH
        htmlTag_setParams = lang="de" class="lang-de"
    }
[end]

Detection: fallback

As its name says, it's not a real detection, but a fallback. Use this type of configuration if you need to redirect to a fallback page in case any previous route does not match.

Examples

Countries with both one or more languages

Assuming the following language configuration:

| Country | Language | Locale | sys_language_uid | | ----------- | -------- | ------ | ------------------ | | Switzerland | German | de_CH | 0 | | Switzerland | French | fr_CH | 1 | | Germany | German | de_DE | 2 | | Belgium | Dutch | nl_BE | 3 | | Belgium | French | fr_BE | 4 | | (Any) | English | en_EN | 5 |

The routes to match the setup from above may look like this:

plugin.tx_languagerouter.settings {
    routes {
      /*
       * Route by browser language first in order to
       * handle countries with multiple languages first.
       *
       * This only works if the operating system of a visitor
       * has set the correct locale for the country the
       * visitor is living in!
       */
      1 {
        detection = acceptedLanguages
        targets {
          fr_CH.L = 1
          fr_BE.L = 4
        }
      }
      
      /*
       * Any unmatched routes from the previous
       * by-browser-language configuration will be
       * routed by the country they're living in.
       */
      2 {
        detection = country
        targets {
          CH.L = 0
          DE.L = 2
          BE.L = 3
        }
      }
      
      /*
       * If neither the first nor the second rule matched,
       * a fallback to our logical "default" language is made.
       */
      3 {
        detection = fallback
        target {
          L = 5
        }
      }
    }
  }

Common errors

Here's a list of common errors experienced when implementing. Please make sure to double-check these before filing a bug report.

.htaccess redirects

Using rewrite rules to ensure that an URL contains a language part may break language routing due to the rewrite redirecting away from the plugin before it can be executed.

Example:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/en/(.*)$
RewriteCond %{REQUEST_URI} !^/de/(.*)$
RewriteCond %{REQUEST_URI} !^/fr/(.*)$
RewriteRule ^(.*)$ /en/$1 [L,R=301]

If your .htaccess (or NGINX configuration) contains redirects as displayed in the example above, remove them and properly configure language routing by e.g. using the fallback detection.