Ok, here’s my take on a multilanguage site. One snippet, one TV, a folder for language files. That’s it, no hacked core modules or anything nasty.
Have the language home page documents in the root. i.e. "French", "Italian", "English". These are the only published documents in the root. These documents act as folders for the content for their respective languages. Anything else goes into unpublished folders.
Have language files to replace placeholders for any generic text, such as login forms, contact forms, etc. These kind of things are what would go in the unpublished folder and get called from all languages. The language files are named after the ID of the language home page, 3.php, 45.php, etc.
Use this modifed CSS Dropdown Menu snippet to create the language menu and seed the system with the $lang variables:
// CSSDropMenu
// simple drop=down menu for ModX
// usage: [[DropDown?id=x&tt=y]]
// where x is the parent of the documents to be listed
// and y is the text you want for the top of the menu
$id = isset($id)?$id:0;
$toptext = isset($tt)?$tt:"Menu";
$children = $modx->getActiveChildren($id);
if($children == false) return;
$childrenCount = count($children);
$lang = $modx->documentIdentifier;
$dm = "";
// a bit of javascript for those whose browsers aren't
// CSS2 compliant (and we all know who they are)
$dm .= "<script type='text/javascript'>
function showList(thistag) {
styleObj = document.getElementById(thistag).style;
if (styleObj.display=='none') {styleObj.display = 'block';}
else {styleObj.display = 'none';}
}
</script>";
// set up the style for the list
$dm .= "<style type='text/css'>
#CSSMenu {
position:relative;
width:100px;
z-index:10;
background:yellow;
}
#CSSMenu ul, #CSSMenu li {list-style:none;}
#cmTopItem {display:block;cursor:pointer;}
#cmTopItem ul {display: none;}
#cmTopItem:hover ul {display: block;}
</style>";
// generate the list
$dm .= "<div id='CSSMenu'>";
$dm .= "<ul class='cmList' id='cmTopList'>";
$dm .= "<li id='cmTopItem' class='cmItem' onClick='showList(\"cmList\");'>$toptext";
$dm .= "<ul class='cmList' id='cmList'";
// individual items
for($x=0; $x<$childrenCount; $x++) {
$dm .= "<li class='cmList'><a href='[~".$children[$x]['id']."~]&lang=".$children[$x]['id']."'>".$children[$x]['pagetitle']."</a></li>";
}
$dm .= "</ul></li></ul></div>";
return $dm;
Use this snippet to set the cookie; put it in each of your language home page documents:
// SetLangCookie snippet for ModX
// set cookie with language ID
$lang=$modx->documentIdentifier;
setcookie("Language",$lang,time()+604800, "/", "", 0);
And finally, this Template Variable to make the $lang variable available anywhere you like, such as the value for the id in the main menu generation snippet, or the logouthomeid in the web login snippet.
@EVAL
if(isset($_GET['lang'])) {$lang=$_GET['lang'];}
else if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
else {$lang=$modx->config['site_start'];}
return $lang;
Now, the user stays in the language area he selects, until he selects another.