Трюк с переключением языков
21.10.2011 14:19:39Пока я реализовывал вывод на своем сайте перепробовал несколько вариантов как сделать зеркальную смену языков и в конце всех изысканий пришел к одному не плохому варианту...
для начала код из .htaccess
RewriteEngine On
RewriteRule ^([^/]*)\.html?$ /index.php?str=$1 [L]
До смешного простая реализация, строго говоря я не очень люблю modrewrite, хоть регулярные выражения и не плохо знаю, все равно с ним всегда возникают заморочки.
В данном выражении у нас все адреса из корня сайта с расширением htmlотправляются в переменную "str". Знак караты "^" в начале выражения указывает на то что преобразования происходили только на корне, это надо чтобы он не портил адреса в других папках например в CMS. Карата в квадратных скобках имеет другое значение она указывает что искаться должен любой символ кроме слеша "/", ладно не будем углубляться в регулярные выражения, главное что работает :).
Перейдем к другому вопросу, а именно мы получили переменную и что же дальше?
А дальше мы думаем о разделителе... Дело в том что вложенность у нас на сайте может быть разная, т. е. Могут быть статьи, новости, каталог и самое главное простые страницы, а еще у нас есть много языков и все это должно указываться в URL и пониматься скриптом выводящим все. Я например использую в качестве разделителя тире, еще можно знак подчеркивания, но увы в моем случае подчеркивание не подходит так как им заменяются пробелы и другие символы при формировании адреса, в моей CMS , поэтому я остановился на тире. Конечно еще можно было бы использовать слеши "/" но не люблю я их для них надо писать сложный modrewrite.
Теперь получая переменную для начала сделаем так чтобы если она не пришла надо присвоить пустое значение и за одно для языка тоже...
$str = isset($_GET['str']) ? $_GET['str']: '';
$lang = '';
Далее парсим полученную переменную, не пугайтесь при слове парсим, на самом деле все проще, есть замечательная функция explode(), описывать не буду думаю из кода будет понятно
$url_vars = explode('-',$str);
Теперь мы получили массив из аргументов, сразу определим его длину...
$url_vars_c = count($url_vars);
А дальше встает проблема, первым параметром может быть передан язык, а может быть и не передан. При этом нам нужно чтобы другие аргументы не плавали, чтобы каждый отвечал за уровень вложенности. Далее привожу то как я этого добился:
if($url_vars_c > 1){
$lang =($url_vars[0] == 'en')||($url_vars[0] == 'kz') ? $url_vars[0] : '';
if ($lang != ''){unset($url_vars[0]);$url_vars = array_values($url_vars);}
}
Если длина больше еденицы значит мы получили больше одного аргумента , а это значит что среди них может быть и язык, а может и не быть :) вот в чем вопрос.
Определение языка во второй строчке предыдущего кода, а вот в третьей строчке, мы спрашиваем был ли определен язык среди аргументов если да то удаляем нулевой элемент массива, но в PHP беда с этим делом, так как даже если удалишь элемент массива то индексы все равно останутся старыми и поэтому пришлось воспользоваться функцией которая переносит значения из одного массива в другой (без индексов) array_values(), думаю ей можно даже переделать ассоциативный массив в индексный. Теперь у нас массив опять начинается с нуля и можно легко обратится к нужному аргументу по его индексу.
Далее нам пригодятся несколько переменных отвечающих за префиксы к полям базы и выводимым URL, и вот они встречайте (секреты строения базы на моем сайте :))
$MLP = $lang != '' ? $lang . '_' : '';
$ULP = $lang != '' ? $lang . '-' : '';
Почему так назвал не знаю, помню что "P" означает префикс, "L" язык, "U" ="URL", а "M" забыл :)
В общем $MLP отвечает за прификсы к полям бызы, кстати при его использовании обязательно слешем перед отправкой в базу есть функция ->real_escape_string() и mysql_real_escape_string().
$ULP добавляем при генерации ссылок для того чтобы при переключении языков адреса выдачи менялись.
Про вывод не буду писать у каждого фантазия своя и всего не распишешь...
напишу лучше про то как сделать ссылки для переключения языков и тут нам на помощь придет обратная уже использованной в начале (explode()) теперь мы используем implode() она соберет массив аргументов в строку
<a href="<?=implode('-',$url_vars)?>.html"><img src="media/ru.gif"></a>
<a href="kz-<?=implode('-',$url_vars)?>.html"><img src="media/kz.gif"></a>
<a href="en-<?=implode('-',$url_vars)?>.html"><img src="media/en.gif"></a>
Ничего сложного, но зато так язык будет переключаться зеркально и на ту же страницу на которой мы находились только на другом языке!
Есть важное замечание! Данный способ реализации многоязычности подходит только в том случае, если все поля нуждающиеся в переводе находятся в одной таблице. Т.е данная структура не подходит для сайтов в которых языковые версии находятся в разных таблицах и имеют разные id! К сожалению таких движков, CMS и сайтов 99% в Казахстане, а между тем Казахстан является многонациональной страной и пока имеет два государственных языка Русский и Казахский, а на Государственных сайтах обычно делается три языка, третий английский.
Мне так больно смотреть на эти сайты, а еще более страшно за тех веб-мастеров (верстальщиков) которым приходится заполнять такие сайты, ведь если языковые версии не находятся в одной строке таблицы базы данных, то как правило сложно найти элемент соответствующий другой версии языка из-за чего тратится много времени и сил на синхронизацию языковых версий. Собственно именно этот факт и побудил меня создать свою CMS без этого недостатка.
Но с другой стороны это достоинство может стать огромной проблемой, в случае если владельцы сайта будут халатно относится к заполнению других языковых версий. Например новости на сайт часто приходят только для одной языковой версии, а если заполнять только одну то на другой будут пустые элементы. Поэтому перед тем как выбрать такой способ необходимо хорошо обговорить вопрос многоязычности с заказчиком. Но как правило заказчик скажет одно, а на деле получится другое, поэтому хорошо бы узнать возможности исполнителей, непосредственно тех кто будет собирать контент для сайта.
На этом пока все... Всем Удачи!
Статья нуждается в переводе на Казахский
Рейтинг $r-- [2] $r++
Показать коментарии (vkontakte.ru)