We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9130
    • 171 Posts
    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;
    	}
    ?>