Вы не зашли.
Страницы 1
Есть как минимум два способа создать мультиязычные сайты. Но тут я распишу только один, который как мне кажется наиболее подходящий. На его создание меня подтолкнул ROZARD, за что ему большое спасибо.
Суть сводиться к клонированию двига. Это дает нам не только контент на другом языке, но также и карту сайта, RSS ленту и т.п. Хочу сразу сказать что данный вариант подходит под любой вид новостных сайтов. Итак начнем:
Сначала нам надо внести изменения из SVN http://trac.assembla.com/ngcms/changeset/891 и http://trac.assembla.com/ngcms/changeset/900, первое это изменения позволяющие в названия категорий использовать символы {}, второе делает доступным языковые блоки iflang
Шаг первый. Первое что нам нужно, разобраться как будут работать заголовки, для этого открываем functions.inc.php и находим там
$tvars = array ( 'vars' => array( 'pagination' => '', 'title' => $row['title']));
перед ней вставляем
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $row['title'], $parr)) {
foreach ($parr[0] as $k => $v) {
$row['title'] = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $row['title']);
}
}
теперь конструкция
[iflang:russian] Описание [/iflang]
[iflang:english] Description [/iflang] будет работать и для заголовков.
P.S.Если Вы планируете со временем расширение языков, то можно сделать так.
[iflang:russian] Заголовок / [/iflang] Header
Это нужно для того, чтоб при добавлении других языков, старые (уже опубликованные) новости отображали хоть какой то заголовок (если переделать все не представляется возможным)
Выглядеть в админке это будет так:
на сайте так:
Xочу заметить что не что не мешает заключить и заголовок на английском в языковой блок.
Сразу же "вычистим" конструкцию iflang из заголовков (для нормального отображения в браузере).
index.php, находим:
$template['vars']['titles'] = join(" : ", array_values($SYSTEM_FLAGS['info']['title']));
Заменяем на:
$titles = join(" : ", array_values($SYSTEM_FLAGS['info']['title']));
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $titles, $parr)) {
foreach ($parr[0] as $k => $v) {
$titles = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $titles);
}
}
$template['vars']['titles'] = $titles;
Шаг второй. В движке используются языковые переменные (вида {l_variable}), которые пригодятся и нам. Как в самом контенте, так и в заголовках категорий.
Начнем с категорий, открываем файл engine/core.php в самом низу дописываем следующий код:
$timer->registerEvent('* CORE.PHP is complete');
foreach ($catz as $catid => $catdata) {
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $catz[$catid]['name'], $larr)) {
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
$catz[$catid]['name'] = str_replace('{'.$v.'}', isset($lang[$name_larr])?$lang[$name_larr]:'[LANG_LOST:'.$name_larr.']', $catz[$catid]['name']);
}
}
}
затем открываем /engine/actions/categories.rpc.php :
Находим:
$tvars['vars'] = array(
'token' => genUToken('admin.categories'),
'php_self' => $PHP_SELF,
'rid' => $row['id'],
'name' => $row['name'],
После вставляем:
// Transcode category name
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $row['name'], $larr)) {
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
$row['name'] = str_replace('{'.$v.'}', isset($lang[$name_larr])?($lang[$name_larr].' <span style="color: red;">(UNIV)</span>'):'[LANG_LOST:'.$name_larr.']', $row['name']);
}
}
// Кстати <span style="color: red;">(UNIV)</span> - это дает возможность подсвечивать категории в которых используется переменная а не название (очень удобно)
ВАЖНО: переменные прописываются в папке lang/язык/common.ini имеют вид
nw_unknow = "Категория неизвестна", nw_unknow = "Category unknown" и т.д. по аналогии, а в название категории Вы прописываете {l_nw_unknow}
В админке это будет выглядеть так:
на сайте так:
Шаг третий. Теперь сделаем так чтоб языковые переменные работали в контенте для этого открываем файл engine\includes\inc\functions.inc.php
Находим там строчку:
function newsFillVariables($row, $fullMode, $page = 0, $disablePagination = 0, $regenShortNews = array()) {
ниже вставляем
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $data, $larr)) {
// Show language variables
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
$data = str_replace('{'.$v.'}', isset($lang[$name_larr])?$lang[$name_larr]:'[LANG_LOST:'.$name_larr.']', $data);
}
}
Все, двиг начал обрабатывать языковые переменные и в контенте. Теперь пропишем сами переменные
открываем \engine\lang\ЯЗЫК\site\news.ini и вписываем свои переменные.
Например: Если сделать такую запись
archive = "Архив"
то станет доступна переменная {l_archive}
Собственно для чего нужны языковые переменные, когда есть блоки. Иногда внутри новости нам нужно обозначить характеристики (размер) или формат, и пользоваться блоками не очень удобно, т.к. они огромны.
Пример использования в админке:
А вот как это будет выглядеть на сайте:
Теперь что касается самих языковых блоков, снова открываем functions.inc.php
Находим:
if ($config['blocks_for_reg']) { $short = $parse -> userblocks($short); $full = $parse -> userblocks($full); }
ниже добавляем:
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $short, $larr)) {
// Show language variables
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $data, $larr)) {
// Show language variables
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
$data = str_replace('{'.$v.'}', isset($lang[$name_larr])?$lang[$name_larr]:'[LANG_LOST:'.$name_larr.']', $data);
}
} $short = str_replace('{'.$v.'}', isset($lang[$name_larr])?$lang[$name_larr]:'[LANG_LOST:'.$name_larr.']', $short);
}
}
if (preg_match_all('/(?<=\{)l_(.*?)(?=\})/i', $full, $larr)) {
// Show language variables
foreach ($larr[0] as $k => $v) {
$name_larr = substr($v, 2);
$full = str_replace('{'.$v.'}', isset($lang[$name_larr])?$lang[$name_larr]:'[LANG_LOST:'.$name_larr.']', $full);
}
}
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $short, $parr)) {
foreach ($parr[0] as $k => $v) {
$short = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $short);
}
}
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $full, $parr)) {
foreach ($parr[0] as $k => $v) {
$full = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $full);
}
}
Теперь нам будет доступна следующая конструкция
На сайте будет выглядеть так:
Причем как многие наверняка уже поняли конструкция может быть абсолютно любой
например:
[iflang:russian]На русском[/iflang]
[iflang:english]На английском[/iflang]
КАРТИНКА
[iflang:russian]На русском[/iflang]
[iflang:english]На английском[/iflang]
КАРТИНКА
еще КАРТИНКА
[iflang:russian]На русском[/iflang]
КАРТИНКА
[iflang:english]На английском[/iflang]
Шаг четвертый: Убираем конструкцию iflang из RSS
Открываем плагин, находим:
$output .= " <title><![CDATA[".((extra_get_param('rss_export','news_title') == 1)&&GetCategories($row['catid'],true)?GetCategories($row['catid'], true).' :: ':'').secure_html($row['title'])."]]></title>\n";
перед ней вставляем:
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $row['title'], $parr)) {
print "<pre>".var_export($parr, true)."</pre>";
foreach ($parr[0] as $k => $v) {
$row['title'] = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $row['title']);
}
}
теперь лента выглядит так:
Шаг пятый: Убираем конструкцию iflang из плагина breadcrumbs (спасибо ROZARD)
Открываем breadcrumbs.php, находим
$catids = $SYSTEM_FLAGS['news']['db.categories'];
$location_last = $SYSTEM_FLAGS['info']['title']['item'];
после добавить:
if (preg_match_all('/\[iflang\:(.+?)\](.+?)\[\/iflang\]/is', $location_last, $parr)) {
foreach ($parr[0] as $k => $v) {
$location_last = str_replace($v,($config['default_lang'] == $parr[1][$k])? $parr[2][$k]:'', $location_last);
}
}
и последнее что нам нужно сделать, клонировать двиг. Для этого нам нужно взять "чистый двиг", и из старого взять все файлы кроме папки uloads и скопировать в папку с чистым двигом. Причем тут есть два варианта. Наример eng версия может находиться по адресу http://youdesigner.kz/en/, а старая соответственно http://youdesigner.kz или же как у меня сейчас для eng отдельный домен http://youdesigner.net
Теперь осталось зайти в файл engine/conf/config.php
и заменить следующие строки (допустим вы выбрали вариант, при котром у Вас eng версия храниться в папке en того же домена)
'home_url' => 'http://domain.kz/en/',
'admin_url' => 'http://domain.kz/en/engine',
теперь войдя в админку не забудьте переименовать сайт и указать дефолтный язык.
в плагине rss который уже будет в папке en/engine/plugins/rss_export также переименуйте сайт
Английская карта сайта и rss будут находиться соответственно тут
http://domain.kz/en/plugin/gsmg/
http://domain.kz/en/rss.xml
Ну вот и все, одно оформление на любом из сайтов и инфа доступна сразу на двух.
и еще раз для тех у кого будет строго два языка Вы можете заголовки заключить в два языковых блока и тогда в Русской версии не будет английского названия и наоборот.
P.S. ОГРОМНОЕ СПАСИБО vitaly, ROZARD, Wolverine - эти ребята гении :)
Изменено easmik (2012-06-24 17:55:22)
Не в сети
Если ты уже столько пропатчил, то допатчить еще карту сайта и RSS это как-то разумнее, чем делать новую инсталляцию движка.
А switcher вроде переключает языки в зависимости от домена.
Не в сети
Не в сети
easmik, как я уже с тобой обсуждать, чето меня немного напрягает это вот штука
[iflang:english]
както не кошерно все это, если б ктото взялся доделать до состояни хорошого юзабилити (хотяби какимито кнопочками или хз), то было б супер
Не в сети
Не в сети
Попробовал сегодня сделать патч по этой инструкции.
1. В ней не всё чисто, кое-что пришлось допиливать руками. Но возможно всё связано с различием в версиях (делал патчи для текущей SVN версии)
2. Решение действительно достаточно простое и интересное
3. Поддержка нескольких языков и правда ОЧЕНЬ нужна в NG
А вообще - спасибо за инструкцию!
Не в сети
vitaly, тебе спасибо Ты написал мне первую обработку iflang для контента и от туда я уже начал "плясать"
Было бы неплохо вшить в двиг поддержку блоков во всем что только есть (чтоб была уже полная поддержка мультиязычности). Хотя с заголовками что то нужно думать, как сейчас это не айс, а пять языков туда уже просто не влезут из-за ограничения длинны поля.
Хотя можно сделать как я уже когда то предлагал http://ngcms.ru/forum/viewtopic.php?pid=23429#p23429 (пункт 4)
А для контента конструкцию лучше чем iflang просто не придумать (очень удобно и понятно даже обычному контент менеджеру), только разве что кнопочки доделать по типу bb кодов (или выпадающий список) как предлагал legenda
p.s. vitaly а в контенте у тебя iflang так и не заработал открой любой пост из раздела блог
Не в сети
$template['vars']['titles'] = join(" : ", array_values($SYSTEM_FLAGS['info']['title']));
в functions.inc.php такого не найдено, 0.9.3 Release
И нужно ли делать - http://trac.assembla.com/ngcms/changeset/891 и http://trac.assembla.com/ngcms/changeset/900 для 0.9.3 версии?
Die Krupps Fan Community[ [NG CMS]
Не в сети
UriyZenkov, я не проверял, http://youdesigner.kz работает на 0.9.3 SVN 900, тогда твига еще не было.
Не в сети
UriyZenkov, круто, я забыл что писал это. У меня как раз в этой версии SVN только это и не работало Там на самом деле не много поменялось, если копировать код который я писал и искать в файле, то не найдешь, а если брать часть и искать, то там все легко.
Если время будет то может быть переделаю под последнюю SVN в воскресенье (но нечего не обещаю)
Не в сети
Страницы 1