W-gent and ObBot / Архив / Архив публикаций / Language hack для любой CMS

Language hack для любой CMS

Страница:  1 2 3
Редирект с YouTube shorts на страницу видео
Быстро, дёшево и качественно
Правильный генератор паролей
Language hack для любой CMS
Сложный парсер даты и времени начала и окончания мероприятия, написанных человеком
Простое решение парадокса Ферми
Thank God For The Bomb
Неверные загадки
Распахивание больших картинок на jQuery

В названии этой статьи нет опечатки: речь идёт не о языковом пакете, а именно о языковом хаке, позволяющем сделать многоязычным практически любой сайт, не вдаваясь в особенности его CMS.


Всё, что для этого нужно - это:


1. Придумать какую-то разметку, отделяющую фрагменты текста на одних языках от фрагментов на других и от фрагментов, не требующих перевода, и какой-нибудь способ дать скрипту понять, что от него требуется тот или иной язык.

2. Найти и переписать на сайте все текстовые фрагменты (самая объёмная и кропотливая работа, не требующая, впрочем, особого интеллекта - её можно поручить кому-нибудь попроще).

3. Перехватить вывод HTML-кода веб-страницы и изъять из него все фрагменты кроме нужного языка.


Вот как это делаю я на двуязычном русско-английском сайте:


1. В качестве разметки я использую последовательности символов  "{R}", "{E}" и "{A}". Например, заключённое в отдельный тэг <span> слово "Контакты", которое должно в английской версии сайта выглядеть как "Contacts", записывается так:

<span>{R}Контакты{E}Contacts{A}</span>

Понятно, что затем в английской версии я должен удалить всё между "{R}" и следующей открывающейся фигурной скобкой, в русской - всё между "{E}" и "{", и затем в обеих версиях подчистить оставшиеся  "{R}", "{E}" и "{A}".

В качестве параметра, задающего переключение с русской версии на английскую, лично я использую поддомен-синоним en.MyDomain.com, и в самом начале выполнения /index.php определяю задающую язык константу E следующим образом:

define(  "E", ( preg_match("/^en./", $_SERVER["HTTP_HOST"]) )  );

Это проще всего, если у вас есть возможность добавлять поддомены в качестве синонимов к основному сайту. Но можно и просто хранить языковый параметр в сессии, извлекая его инструкцией типа такой:

if(!isset($_SESSION)) session_start();
define( "E", (@$_SESSION["lang"]=="en") );

При этом в скрипте, вызываемом для переключения с русского языка на английский, запишем:

if(!isset($_SESSION)) session_start();
$_SESSION["lang"]="en"; 

а в скрипте, производящем обратное переключение - соответственно,

if(!isset($_SESSION)) session_start();
$_SESSION["lang"]="ru";  


2. Ну вы поняли. Найдите кого-нибудь, кому не лень и озадачьте его заменой всех найденных на сайте текстовых фрагментов (как в дизайне и скриптах, так и в базе данных) по вышеописанной схеме {R}{E}{A}


3. Вот теперь - самое сложное. Нужно точно определить, в каком месте CMS сайта начинает вывод HTML-кода и в каком заканчивает. Простой поиск в коде   практически любой современной CMS фрагментов "<html" и "</html>", скорее всего, завалит вас огромным количеством этих фрагментов во всевозможных темплейтах, из которых CMS собирает готовые веб-страницы. Перспективнее всего открыть файл /index.php и попытаться найти начало и конец вывода в нём. Как правило, в этом файле будет сначала подключение файла с настройками, затем определение, что же именно запросил пользователь, и лишь затем обработка и вывод информации.

Идите по дереву подгружаемых файлов - как правило, они подгружаются функциями include(), include_once(), require() или require_once(). Если в качестве аргумента у функции какая-то переменная или неизвестная вам константа - временно добавьте в код её вывод на экран, чтобы посмотреть, какой именно файл инклюдится.

Добавляйте по мере продвижения временные инструкции типа die("PREVED");, чтобы определить, начался уже вывод собственно HTML или всё ещё выводятся хидеры, закончился или ещё нет.


Определив начало и конец вывода HTML-кода, добавьте перед началом инструкцию:

ob_start();

, а после конца вывода - следующий код:

echo lang( ob_get_clean() );
// И затем пишем саму функцию lang() 
// (если какая-то функция с именем lang() уже существует и вы получаете соответствующую ошибку, 
// то назовите функцию как-нибудь по-другому, например, MySuperPuperCoolHackLanguageFunction() )
function lang($s){
  if(E) $s=preg_replace("/\{r\}[^\{]*\{/U", "{", $s); // Если нужна английская версия, то удаляем русскую часть
  else $s=preg_replace("/\{e\}[^\{]*\{/U", "{", $s); // Если нужна русская версия, то удаляем английскую часть 
  $s=preg_replace("/\{(R|E|A)\}/", "", $s); // Подчищаем остатки нашей разметки
  return $s;
}



Собственно, на этом и всё! Удачи вам!