The idea is to set up ISO 639-1 language code prefixes for urls (e.g. en/, de/, fr/), and set global variables {global:lang}
and {global:lang_dir}
for use in your templates.
In the control panel create a category group "languages" and populate it with your languages, setting the category url title to the appropriate 2-letter language code. Assign the category group to the channels you want to translate.
For example:
Category Name | Category URL Title |
---|---|
Deutsch (de) | de |
English (en) | en |
Français (fr) | fr |
日本語 (ja) | ja |
한국의 (ko) | ko |
中文 (zh) | zh |
Then set up these rules with Resource Router:
<?php
$config['resource_router'] = array(
// set the default language and direction for all routes
'(.*)' => function($router, $wildcard) {
// default language, when there is no language code prefix
$lang = 'en';
$router->setGlobal('global:lang', $lang);
// default direction
$router->setGlobal('global:lang_dir', 'ltr');
// setup default language category meta data
$router->setWildcard(1, $lang);
$wildcard->isValidCategoryUrlTitle();
return; // signify this rule does not match a route
},
// do we have a language code in the first segment?
'([a-z]{2})/:all' => function($router, $lang) {
// yes - check the 2-letter language code is a valid category url title
// if found, this will set the category meta data as global variables
if (FALSE === $lang->isValidCategoryUrlTitle())
{
$router->set404();
}
// set the current language
$router->setGlobal('global:lang', $lang);
// reverse the text direction for known RTL languages
switch($lang) {
case 'ar' : case 'fa' : case 'ur' :
$router->setGlobal('global:lang_dir', 'rtl');
break;
}
// remove the language segment
array_shift(ee()->uri->segments);
// overwrite {segment_x} variables in templates
foreach(ee()->uri->segments as $key => $value) {
$router->setGlobal('segment_'.($key+1), $value);
}
// overwrite the uri string too
ee()->uri->uri_string = implode('/', ee()->uri->segments);
return; // signify this rule does not match a route
},
/* any custom routes here */
/* re-route any url prefixed with a country code not matched by above rules */
'([a-z]{2})/(.*)' => function($router, $lang, $url) {
$router->setTemplate($url);
}
);
Now you can either use an asynchronous approach whereby separate entries are created for each language, or a synchronous approach where a single entry is translated into multiple languages via prefixed custom fields. In either case assigning the entries to the relevant language category(s) provides a native and fast mechanism for filtering entries by current language category id, which Resource Router makes available as {route_1_cat_id}
. For example:
{!-- list blog entries in the current language --}
{exp:channel:entries
channel="blog"
category="{route_1_cat_id}"
dynamic="no"
disable="member_data|pagination"
}
Here's an EE3 version: