Давно начал использовать для создания мультиязычных сайтов плагин EasyLingual, так как для таких решений был самым удобным.
Но мне вывода TV не хватало, поскольку зачастую использую так же самописные сниппеты, ну и конешно нехватало перевода отдельных фраз в шаблонах и чанках. Для этого приходилось часто делать чанки в виде сниппетом, в которых был массив с переводами и через switch по сессии выбирать какой-же брать массив с фразами и выводить. Со временнем это мне надоело, а как известно "Лень - двигатель прогреса", решил написать модуль и плагин.
Прошу сильно не пинать, код не претендует на универсальность, хочеться донести саму идею и пищу для мозгов..
Итак, начнем. В моем варианте - перевод для 3-х языков (английский, русский и украинский).
UPD: Код изменнен. За критику и подсказки спасибо
AKots
1. Создаем отдельну таблицу в нашей БД:
(modx_lang - префикс незабываем менять на свой!)
CREATE TABLE IF NOT EXISTS `modx_lang` (
`en` varchar(255) NOT NULL,
`ru` varchar(255) NOT NULL,
`uk` varchar(255) NOT NULL,
UNIQUE KEY `en` (`en`),
KEY `en_2` (`en`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
2. Создаем модуль Translate:
(В нем и будем заполнять поля перевода фраз)
if(isset($_POST['save'])){
$table = $modx->getFullTableName( 'lang' );
foreach($_POST as $lns){
if($lns!='save'){
$sql = "INSERT INTO ".$modx->getFullTableName( 'lang' )." (en,ru,uk) VALUES ('" . $lns['en'] . "','" . $lns['ru'] . "','" . $lns['uk'] . "')
ON DUPLICATE KEY UPDATE ru= '" . $lns['ru'] . "', uk = '" . $lns['uk'] . "' ";
mysql_query($sql);
}
}
}
$content ='<html><head><link href="media/style/MODxCarbon/style.css" type="text/css" rel="stylesheet">
<style>
table tr th{font-size:14px; width:200px}
table tr td{font-size:12px; width:200px}
table tr td input{font-size:12px;width:200px}
</style>
</head><body>';
$langs=array();
$res = $modx->db->select("content", $modx->getFullTableName('site_templates'), "content LIKE '%\[\%t \`%'");
$members = $modx->db->makeArray( $res );
$langs = array_merge($langs, $members);
$rescont = $modx->db->select("content", $modx->getFullTableName('site_content'), "content LIKE '%\[\%t \`%'");
$lncont = $modx->db->makeArray( $rescont );
$langs = array_merge($langs, $lncont );
$restv = $modx->db->select("value", $modx->getFullTableName('site_tmplvar_contentvalues'), "value LIKE '%\[\%t \`%'");
$lntv = $modx->db->makeArray( $restv );
$langs = array_merge($langs, $lntv);
$ressp = $modx->db->select("snippet", $modx->getFullTableName('site_snippets'), "snippet LIKE '%\[\%t \`%' ");
$lnsp = $modx->db->makeArray( $ressp);
$langs = array_merge($langs, $lnsp);
$content .='<form method="post"><table><tr><th>English</th><th>Russian</th><th>Ukrainian</th></tr>';
$mathcln = array();
foreach($langs as $scont )
{
preg_match_all("~\[\%t \`(.*)\`\%\]~U", $scont['content'], $matches);
$mathcln = array_merge($mathcln, $matches[1]);
preg_match_all("~\[\%t \`(.*)\`\%\]~U", $scont['snippet'], $matches);
$mathcln = array_merge($mathcln, $matches[1]);
}
$lnuniq = array_unique($mathcln);
$i=0;
foreach($lnuniq as $lnen){
$content .='<tr>';
$content .= '<td>'.$lnen.' <input type="hidden" name="'.$i.'[en]" value="'.$lnen.'"></td>';
$ress = $modx->db->select("ru, uk", $modx->getFullTableName('lang'), "en = '".$lnen."' ");
if(mysql_num_rows($ress)>0){
$content .= '<td><input type="text" name="'.$i.'[ru]" value="'.mysql_result($ress, 0, 0).'"></td>';
$content .= '<td><input type="text" name="'.$i.'[uk]" value="'.mysql_result($ress, 0, 1).'"></td>';
}else{
$content .= '<td><input type="text" name="'.$i.'[ru]" value=""></td>';
$content .= '<td><input type="text" name="'.$i.'[uk]" value=""></td>';
}
$content .='</tr>';
$i++;
}
$content .= '</table><input type="submit" value="Зберігти" name="save"></form></body></html>';
return $content;
3. Модифицируем плагин EasyLingual:
Дописываем после
// Remove lowercased tags when current lang is default lang
if($default_lang == $_SESSION['lang'])
$lang_att = $language = "";
следующее
$res = $modx->db->select("*", $modx->getFullTableName('lang'));
$lnarray = $modx->db->makeArray($res);
preg_match_all("~\[\%t \`(.*)\`\%\]~U", $modx->documentOutput, $matchesz);
foreach($matchesz[1] as $ln){
foreach($lnarray as $lnf){
if($lnf['en'] == $ln){
$modx->documentOutput = str_replace("[%t `".$ln."`%]", $lnf[$LANG_ATT], $modx->documentOutput);
}
}
}
Теперь всюду, где необходимо, встаем плейсхолдер вида
[%t `фраза на английском`%]
Вот вроде бы и все. Спасибо за внимание.