After building a multi language site using the Languages snippet from the wiki page the site got bigger and managing the languages and ids manually became too much work to maintain.
The solution: a new multi language snippet that follows a convention over configuration paradigm. Everything is defined once in the snippet configuration, no more TV’s to edit and maintain on every page.
The snippet assumes that the document tree aliases/paths are the same for each language:
mysite.com/en/category/product/car.html
mysite.com/de/category/product/car.html
The snippet requires that each document on the tree has an alias but it works even when not using friendly urls or enabling alias paths (although with a performance impact).
The snippet allows for some configuration options:
- You define the languages available in the snippet as in the original wiki snippet
- You can select to use language flag images or use just the language names as links
- If an equivalent page in another language does not exist or is not yet published you can select whether to link to the other language home page or not show a link at all.
Hope someone finds it useful,
Erez
<?php
//START OF USER CONFIGURATION & SETTINGS
//array of languages and their names
$langnames = array(
"he" => "עברית",
"en" => "English",
"es" => "Español"
);
//array of languages and their index page
$langhomepages = array(
"he" => 1,
"en" => 111,
"es" => 20
);
//use general language homepage when no matching document exists
$uselanghomepages = true;
//use images (country flags) or plain text
$useimages = false;
//seperator to use between language links
$seperator = " | ";
//END OF USER CONFIGURATION
if($modx->config['friendly_urls'] == 1 && $modx->config['use_alias_path'] == 1)
{
//already cached
$idbyalias = $modx->documentListing;
}
else
{
//must build everything from scratch
$idbyalias = array();
// build aliases path (based on manager/processors/cache_sync.class.processor.php)
$tmpPath = '';
$dbase = $modx->db->config['dbase'];
$table_prefix = $modx->db->config['table_prefix'];
$sql = "SELECT IF(alias='', id, alias) AS alias, id, contentType, parent FROM $dbase.`".$table_prefix."site_content` ORDER BY parent, menuindex";
$rs = $modx->db->query($sql);
$limit_tmp = mysql_num_rows($rs);
for ($i_tmp=0; $i_tmp<$limit_tmp; $i_tmp++) {
$tmp1 = mysql_fetch_assoc($rs);
$tmpPath = getParents($tmp1['parent']);
$alias= (strlen($tmpPath) > 0 ? "$tmpPath/" : '').$tmp1['alias'];
$alias= mysql_escape_string($alias);
$idbyalias[$alias] = $tmp1['id'];
}
}
//build current document path
$aliasbyid = array_flip($idbyalias);
$currentid = $modx->documentIdentifier;
$currentpath = $aliasbyid[$currentid];
//get current document language
$findlang = preg_match_all("/^(\w+)\//U", $currentpath , $matches);
$currentlang = $matches['1']['0'];
//check that this is a valid language
if(!$langnames[$currentlang])return '<!-- Current page has no language defined ('.$currentlang.') --!>';
//build other language links
$output = "";
$tempseperator = "";
foreach($langnames as $lang=>$name)
{
if($lang != $currentlang)
{
$newpath = preg_replace("/^".$currentlang."\//U", $lang."/" , $currentpath);
$newid = $idbyalias[$newpath];
//check if document is published
if($newid)
{
$isActive = $modx->getPageInfo($newid,1);
if(empty($isActive)) $newid = NULL;
}
//check if document path exists, replace with language homepage if needed
if(!$newid && $uselanghomepages)
{
$newid = $langhomepages[$lang];
}
if($newid)
{
//create html
if($useimages)
{
$image = '<img src="assets/images/'.$lang.'.gif" width="16" height="11" border="0" alt="'.$name.'" />';
}
else
{
$image = $name;
}
$output .= $tempseperator.'<a href="'.$modx->makeUrl($newid).'">'.$image.'</a>';
$tempseperator = $seperator;
}
}
}
return $output;
function getParents($id, $path = '') { // taken from manager/processors/cache_sync.class.processor.php
global $modx, $dbase, $table_prefix;
$sql = "SELECT id, alias, parent FROM $dbase.`".$table_prefix."site_content` WHERE id = '$id'";
$qh = $modx->db->query($sql);
if ($qh && mysql_num_rows($qh) > 0) {
$row = mysql_fetch_assoc($qh);
$path = ($row['alias'] ? $row['alias'] : $row['id']) . ($path != '' ? '/' : '') . $path;
mysql_free_result( $qh );
return getParents($row['parent'], $path);
}
return $path;
}
?>