Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Сайт на двух (или более) языках. Как лучше и проще сделать поддержку многоязычности? (Victor Feketa, оценка: 5)
Goto page 1, 2  Next
Author Message
Victor Feketa
Заглянувший



Joined: 19 Jun 2004
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Tue Mar 08, 2005 1:14 pm (написано за 1 минуту 53 секунды)
   Post subject: Сайт на двух языках - как это лучше и проше сделать?
Reply with quote

Как лучше сделать сайт на двух языках, то есть каждая страничка и любой текст должны быть в двух вариантах, между которыми можна переключаться в любой момент с помощью кнопочек? И еще вопросЖ как узнать в скрипте адрес текущей странички,
Back to top
View user's profile Send private message
Евгений Галашин
Модератор



Joined: 29 Dec 2003
Posts: 1861
Карма: 32
   поощрить/наказать


PostPosted: Tue Mar 08, 2005 1:50 pm (спустя 36 минут; написано за 27 секунд)
   Post subject:
Reply with quote

Victor Feketa wrote:
И еще вопросЖ как узнать в скрипте адрес текущей странички,
$SERVER['REQUEST_URI']
Back to top
View user's profile Send private message
2ko
Участник форума



Joined: 07 Mar 2005
Posts: 28
Карма: 1
   поощрить/наказать

Location: Гомель / Беларусь

PostPosted: Tue Mar 08, 2005 6:16 pm (спустя 4 часа 25 минут; написано за 6 минут 11 секунд)
   Post subject:
Reply with quote

есть файл index.php(например), вот, в нем должна быть обработка переменной:

$lang = $GLOBALS['lang'];
$defaultlang = 'rus';

./lang/rus.php
./lang/eng.php - файлы в папке с примерно таким содержимым:
Code (php): скопировать код в буфер обмена
<?php
$lang = array (www.php.net/array)(
'title' => 'hello';
);
?>
Code (php): скопировать код в буфер обмена
if (!empty (www.php.net/empty)($lang))
{
   $lang = (!file_exists (www.php.net/file_exists)("./lang/{$lang}.php")) ? $defaultlang : $lang;
}

require "./lang/{$lang}.php";
В каждой функции сделай глобальной - $lang, или если это класс - что-то типа $site -> lang = $lang;

обращаться так:
если функция - $lang['title'] = выводит hello
или $site -> lang['title'], - если это класс

удачи..
Back to top
View user's profile Send private message
Vladimir Sergeev
Участник форума



Joined: 18 Feb 2004
Posts: 89
Карма: 11
   поощрить/наказать


PostPosted: Tue Mar 08, 2005 8:00 pm (спустя 1 час 44 минуты; написано за 1 минуту 7 секунд)
   Post subject:
Reply with quote

Хорошее решение, GetText, которое фактически является стандартом, изложено здесь:
phpclub.ru/talk/showthread.php?s=&threadid=58523
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 411
   поощрить/наказать


PostPosted: Wed Mar 09, 2005 3:55 am (спустя 7 часов 54 минуты; написано за 17 секунд)
   Post subject:
Reply with quote

Bred Vilchec, вах!
+2
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 411
   поощрить/наказать


PostPosted: Wed Mar 09, 2005 3:55 am (спустя 26 секунд)
   Post subject:
Reply with quote


М

Сама статья: php.russofile.ru/Using_GetText.html
Перенесено из форума: Разное :: PHP.
Перенесено в форум: Склад готовых решений :: PHP.
Back to top
View user's profile Send private message Send e-mail
Punisher
Заглянувший



Joined: 16 Nov 2004
Posts: 12
Карма: -1
   поощрить/наказать


PostPosted: Fri Mar 11, 2005 11:11 pm (спустя 2 дня 19 часов 16 минут; написано за 5 минут 40 секунд)
   Post subject:
Reply with quote

GetText очень полезная утилита, но имеет один очень большой недостаток: системы созданные на его основе практически невозможно будет распространять (продавать) как самостоятельные пакеты, которые легко установить на хостинге. Кроме того, что будет требоваться установка самой системы, дополнительно ещё необходимо будет установить GetText. Более того, не каждый хостер позволит сделать это, т.к. не все дают возможность работать с php.ini. Также, ещё минус в том, что решение не кросс-платформенное, да ещё в видндовс дополнительные сложности с установкой.
В итоге, лишая себя проблемы с мультиязычностью, мы добавляем себе проблемы с установкой и более высокими требованиями к хостеру.

Кстати, не подскажите, iconv в этом отношении хуже или нет?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 411
   поощрить/наказать


PostPosted: Fri Mar 11, 2005 11:17 pm (спустя 6 минут; написано за 58 секунд)
   Post subject:
Reply with quote

Вы имеете в виду, что расширение gettext стоит не у всех хостеров?
Но есть же, наверное, библиотека на чистом PHP? Там же вроде во время исполнения особенных возможностей не нужно...

iconv совсем не для этого предназначен, а для перекодирования из одной кодировки в другую.
Back to top
View user's profile Send private message Send e-mail
Punisher
Заглянувший



Joined: 16 Nov 2004
Posts: 12
Карма: -1
   поощрить/наказать


PostPosted: Sat Mar 12, 2005 1:01 am (спустя 1 час 43 минуты; написано за 4 минуты 5 секунд)
   Post subject:
Reply with quote

Quote:
Но есть же, наверное, библиотека на чистом PHP?
Как бы я хотел узнать, что это за библиотека! Уже несколько недель бьюсь в тщетных попытках найти такую. Или хотя бы принцип её реализации. А то, что gettext стоит не у всех хостеров, то это верно и именно об этом я и говорил. Даже вернее сказать, что мало у кого он вообще стоит. Российские хостеры в этом отношении ещё более или менее молодцы, но вот СНГшные (а особенно ЦА) - это ужас... И не будет же пользователь, купивший BOX-версию продукта, самостоятельно заниматься его установкой.

Я перечитал кучу статей и здесь и на форума РНР-клуба, но ничего готового, кроме gettext пока не нашёл.
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 411
   поощрить/наказать


PostPosted: Sat Mar 12, 2005 1:19 am (спустя 18 минут; написано за 41 секунду)
   Post subject:
Reply with quote

Что значит - "принцип реализации"? Почитайте документацию на gettext, посмотрите, как он работает, и сделайте то же самое, но на PHP. Там же ничего, кроме парсинга текстовых файлов, нет, по идее.
Back to top
View user's profile Send private message Send e-mail
melfar
Заглянувший



Joined: 17 Apr 2005
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Sun Apr 17, 2005 2:21 pm (спустя 1 месяц 5 дней 13 часов 2 минуты; написано за 2 минуты 12 секунд)
   Post subject:
Reply with quote

Если текст генерирует скрипт, в несложных случаях мне хватало:
Code (any language): скопировать код в буфер обмена
$lang = "ru";
function lang ($ru, $en)
{
        return $lang == "ru" ? $ru : $en;
}
echo lang ("Отменить", "Cancel");
И то же самое в js.
Back to top
View user's profile Send private message
Saturn
Заглянувший



Joined: 08 Sep 2004
Posts: 10
Карма: 1
   поощрить/наказать

Location: Кракозия

PostPosted: Tue Jun 07, 2005 12:03 am (спустя 1 месяц 19 дней 9 часов 41 минуту; написано за 3 минуты 8 секунд)
   Post subject:
Reply with quote

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

GetText мне не подошёл.
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 411
   поощрить/наказать


PostPosted: Tue Jun 07, 2005 11:57 am (спустя 11 часов 54 минуты; написано за 6 секунд)
   Post subject:
Reply with quote

Перекликающаяся тема: xpoint.ru/forums/computers/dbms/misc/thread/31618.xhtml
Back to top
View user's profile Send private message Send e-mail
Supercelt
Заглянувший



Joined: 29 May 2005
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Sat Jun 11, 2005 12:03 am (спустя 3 дня 12 часов 5 минут; написано за 45 секунд)
   Post subject:
Reply with quote

Можно ещё с помощью switch-case сделать, тогда не надо создавать массив
Back to top
View user's profile Send private message
netghost
Участник форума



Joined: 06 May 2005
Posts: 53
Карма: 2
   поощрить/наказать

Location: планета Земля, город-герой Москва

PostPosted: Sat Jun 11, 2005 5:01 pm (спустя 16 часов 58 минут; написано за 2 минуты 46 секунд)
   Post subject:
Reply with quote

Жалко исчезли информеры с www.translate.ru Раньше можно было разместить один такой на сайте и будет обеспечен перевод на 5 европейских языков!!! Может есть ещё такие ресурсы, с которых можно получить такой информер? Если кто знает, подскажите пожалуйста
Back to top
View user's profile Send private message
Vasiliy
Участник форума



Joined: 16 Mar 2004
Posts: 50
Карма: 0
   поощрить/наказать


PostPosted: Sun Jun 26, 2005 1:40 pm (спустя 14 дней 20 часов 38 минут; написано за 15 секунд)
   Post subject:
Reply with quote

Многоязычные приложения - Способы хранения динамических данных (php.russofile.ru/multilagual_dynamic_data.html)

После прочтения статьи я просто прозрел – как может быть всё просто! После небольших экспериментов пришёл к следующему:
Если организовать метод класса осуществляющий запрос к БД в виде
Code (php): скопировать код в буфер обмена
class DB {
...
    //
    //    Запрос к БД. Текст запроса передается переметром $sql
    //    Если параметр $r равен 1 - возвращаем массив записей,
    //          если 0 - возвращаем массив одной записи
    //    Параметр $type отвечает за то, в каком виде будет вернувшийся массив. См. ман!
    //
    function select($sql, $r=1, $type=MYSQL_ASSOC) {
        $output = array (www.php.net/array)();
        if ($res = $this->request($sql)) {
            if ($r) {
                $i=0;
                while ($res_arr = mysql_fetch_array (www.php.net/mysql_fetch_array)($res, $type)){
                  $output[$res_arr['id']][$res_arr['lang']]=$res_arr;
                }
                return ( (empty (www.php.net/empty)($output)) ? 0 : $output );
            }
            else return mysql_fetch_array (www.php.net/mysql_fetch_array)($res, $type);
        }
        return 0;
    }
Самое интересное здесь вот это
Code (php): скопировать код в буфер обмена
                while ($res_arr = mysql_fetch_array (www.php.net/mysql_fetch_array)($res, $type)){
                  $output[$res_arr['id']][$res_arr['lang']]=$res_arr;
                }
Если организовать SQL-запрос опр. вида (см. пример в архиве), то мы НИКОГДА не получим пустой массив и при необходимости всегда можно подсунуть текст на языке по умолчанию, уведомив об этом пользователя, опять же см. пример в архиве. Небольшая оговорка, говоря НИКОГДА, я подразумевал, что все поля в таблице для языка по умолчанию будут заполнены, но это забота уже других "служб".

И параллельно просьба к сообществу – не могли бы помочь в организации индексов для этого конкретного случая, а то у меня что-то не выходит дружить с MYSQL.

Заранее благодарен.


example.zip
 Description:

Download
 Filename:  example.zip
 Filesize:  2.81 KB
 Downloaded:  1613 Time(s)

Back to top
View user's profile Send private message
Vasiliy
Участник форума



Joined: 16 Mar 2004
Posts: 50
Карма: 0
   поощрить/наказать


PostPosted: Mon Jun 27, 2005 12:38 pm (спустя 22 часа 58 минут; написано за 6 секунд)
   Post subject:
Reply with quote

Многоязычные приложения. Профессиональная работа. (php.russofile.ru/multilagual_applycations.html)
Back to top
View user's profile Send private message
bæv
Модератор «Дзена»



Joined: 27 Aug 2003
Posts: 7275
Карма: 9995
   поощрить/наказать


PostPosted: Mon Jun 27, 2005 12:47 pm (спустя 8 минут; написано за 10 секунд)
   Post subject:
Reply with quote

PHPIns!de #12, Май'2005 Мультиязычные веб-приложения (detail.phpclub.net/magazine/2005/05/)
Back to top
View user's profile Send private message
Pavel A. Brilow
Guest





Карма: 386
   поощрить/наказать


PostPosted: Tue Jun 28, 2005 6:58 pm (спустя 1 день 6 часов 10 минут; написано за 5 минут 55 секунд)
   Post subject:
Reply with quote

Если известно что языка два - русский и английский допустим, и известно 100% что других языков не будет, то я выбрал для себя не очень сложный путь - проверка приблизительно так как описано выше, а вывод текста в файлах (не шаблонных, файлах-кашах) идет в виде
Code (php): скопировать код в буфер обмена
echo (www.php.net/echo) langprint("Русская строка","English string");
а langprint определена в файле с глобальными функциями и имеет содержание что-то вроде
Code (php): скопировать код в буфер обмена
function langprint($russtring,$engstring) {
        global (www.php.net/global) $l //
        if ($l=='eng') return $engstring;
        else return $russtring;
}
Плюс в том что при условии что многие тексты, фразы и т.д. не повторяются на сайте - не нуэжно выдумывать для них уникальные ключи массива и искать их потом в отдельных файлах. все под рукой - там-же где сам код.

Знаю что принципиально вариант кривой, также как и плохо что логика с дизайном вперемешку, но разговор о дешевых быстрых проектах, когда в сверстанный ХТМЛ вставляются куски логики на PHP.

Вобщем просто на заметку.
Back to top
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 194
   поощрить/наказать

Location: 007 495

PostPosted: Tue Jun 28, 2005 7:05 pm (спустя 7 минут; написано за 54 секунды)
   Post subject:
Reply with quote

Pavel A. Brilow
Хм, интересная идея :). Вот только нужно функцию назвать ещё короче, а то неудобно каждый раз печатать длинное «langprint». Можно например называть функцию «l_» (т.к. «_» уже занято).
Back to top
View user's profile Send private message Send e-mail
Pavel A. Brilow
Заглянувший



Joined: 28 Jun 2005
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Wed Jun 29, 2005 11:55 am (спустя 16 часов 50 минут; написано за 4 минуты 57 секунд)
   Post subject:
Reply with quote

Да, ну и расширяемость впринципе возможна, правда требует уже усилий... С геттекстом проще конечно...
т.е. при добавлении языка можно расширить функцию и сделать что-то вроде
Code (php): скопировать код в буфер обмена
function l_($russtring,$engstring,$kazstring='') {
        global (www.php.net/global) $l //Получено идущими выше проверками
        switch($l) {
                case eng:
                return $engstring;
                break;

                case kaz:
                if($kazstring!='') return $kazstring;
                else return $russtring
                break;

                default:
                return $russtring;
                break;
        }
}
Code (php): скопировать код в буфер обмена
<?=l_("Привет","Hello","Салем");?>
И добавлять этот язык птихоньку в нужные файлы - де перевод на этот язык есть - будет показываться казахский, а где нет - будет показываться русский.
Для корпоративных сайтов такой подход помоему приемлем, если учесть что больше трех языков в таких проектах не бывает обычно, и структурировать и систематизировать языковую библиотеку по ним будет сложновато.
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 386
   поощрить/наказать


PostPosted: Wed Jun 29, 2005 3:44 pm (спустя 3 часа 48 минут; написано за 1 минуту 30 секунд)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
[m]Сама статья: php.russofile.ru/Using_GetText.html

Перенесено из форума: Разное :: PHP.
Перенесено в форум: Склад готовых решений :: PHP.[/m]
Я (автор указанной вверху статьи) написал еще два больших материала на тему создания многоязычных сайтов, может кому бедт интересно:
php.russofile.ru/ru/authors/multilangual/php_gettext_prof/ - PHP и GetText - проф. использование - с картинками и все такое.
php.russofile.ru/ru/authors/multilangual/dynamic/ - Многоязычные приложения: Способы хранения динамических данных
Back to top
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 194
   поощрить/наказать

Location: 007 495

PostPosted: Wed Jun 29, 2005 5:56 pm (спустя 2 часа 12 минут; написано за 30 секунд)
   Post subject:
Reply with quote

Pavel A. Brilow
Ну, в принципе, это действительно очень похоже на идею GetText, только в более «локализованном» виде. В принципе, это может быть и удобнее, если языков не очень много и разработчиков очень мало
Back to top
View user's profile Send private message Send e-mail
gimnazist
Guest





Карма: 386
   поощрить/наказать


PostPosted: Fri Sep 23, 2005 11:02 am (спустя 2 месяца 23 дня 17 часов 6 минут; написано за 2 минуты 33 секунды)
   Post subject:
Reply with quote

Я пользуюсь еще таким вариантом.
Code (php): скопировать код в буфер обмена
public function langueges($lang, $file_ini)
{
        $parse = array (www.php.net/array)();
      if(file_exists (www.php.net/file_exists)($lang . '_' . $file_ini . '.ini'))
                    $parse = parse_ini_file (www.php.net/parse_ini_file)($lang . '_' . $file_ini . '.ini', TRUE);
      if(count (www.php.net/count)($parse) > 0)
              return $parse;
}
и во время инициализации объекта смотрим результат из файла eng_lang.ini или ru_lang.ini
Code (php): скопировать код в буфер обмена
function __construct()
{
        if(!empty (www.php.net/empty)($_GET['lang']) AND $_GET['lang'] == 'eng')
            {
                $this->langarray = self::langueges('eng', 'lang');
      }
      else
      {
              $this->langarray = self::langueges('ru', 'lang');
      }
}
Back to top
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 180
   поощрить/наказать

Location: Москва

PostPosted: Wed Dec 07, 2005 2:06 pm (спустя 2 месяца 14 дней 3 часа 3 минуты; написано за 8 минут 19 секунд)
   Post subject:
Reply with quote

А я в шаблонах вызываю вот эту функцию:
Code (php): скопировать код в буфер обмена
    /**
     * Возвращает локализованную строку текста в зависимости от текущего языка веб-страницы
     *
     * @param  array   ассоциативный массив, например:
     *                 array('ru' => 'текст по-русски',
     *                       'en' => 'english text')
     * @return string
     */

    function loc($a)
    {
        return $a[$_REQUEST['lang']];
    }
В таблице БД локализованные поля имеют окончание "__xx", например: caption__ru, caption__en
Все тексты хранятся в UTF-8.
Данные из таблицы БД достаются одним простым запросом и могут быть показаны на странице _одновременно_ на нескольких языках.
Очень удобно!
Back to top
View user's profile Send private message Send e-mail
KK Project
Guest





Карма: 386
   поощрить/наказать


PostPosted: Sun Mar 05, 2006 5:33 pm (спустя 2 месяца 29 дней 3 часа 27 минут; написано за 4 минуты 42 секунды)
   Post subject:
Reply with quote

У меня проще, как мне кажется:
// Index.php
require_once('Utilities.php');
...
$txt = array();
...
...
LangsInit()

echo $txt['01']; // index.php?language=russian, "ШалЁм".
...

// Utilities.php
...
...
function LangsInit()
{
global $txt;
...
...
...
// $siteLng = язык по умолчанию
if (isset($GLOBALS['_GET']['language']) && $GLOBALS['_GET']['language'] == 'russian' || isset($siteLng) && $siteLng == 'russian')
    require_once($headDir . '/langs/' . $installedLangs['r']); // rus
elseif (isset($GLOBALS['_GET']['language']) && $GLOBALS['_GET']['language'] == 'english' || isset($siteLng) && $siteLng == 'english')
    require_once($headDir . '/langs/' . $installedLangs['e']); // eng
elseif (isset($GLOBALS['_GET']['language']) && $GLOBALS['_GET']['language'] == 'japanese' || isset($siteLng) && $siteLng == 'japanese')
    require_once($headDir . '/langs/' . $installedLangs['j']); // jp
else
    fatalError('Language not set!', __FILE__, 'LangsInit()', __LINE__);
}

// Russian.php
$txt['01'] = 'ШалЁм';
// English.php
$txt['01'] = 'HeLLyo!';
Back to top
y0prst
Участник форума



Joined: 20 May 2004
Posts: 101
Карма: 9
   поощрить/наказать

Location: Вологда

PostPosted: Mon Mar 06, 2006 12:37 pm (спустя 19 часов 3 минуты; написано за 5 минут 56 секунд)
   Post subject:
Reply with quote

KK Project wrote:
У меня проще
Конечно, проще!
Но не факт, что эффективнее. Почитайте тему с самого начала и поймете, почему. Я сам использовал только похожий на ваш вариант и понимаю его недостатки:
  1. при отсутствии какой-то "языковой константы" не выводится ничего (или выводится ошибка. Что из этого лучше - спорный вопрос.)
  2. сложно поддерживать проект даже с двумя языками: как правило, я забывал добавить аналогичную переменную в языковой файл с английским языком.
  3. нужно придумывать идентификаторы для каждой надписи, в результате получается "нечитабельный" скрипт со всякими $txt['01'], $txt['indexTitle'] и т.п. В GetText это кстати автоматизировано, насколько я понимаю.
К тому же никак не учитывается проблема с динамическим контентом.
Back to top
View user's profile Send private message
KK Project-
Guest





Карма: 386
   поощрить/наказать


PostPosted: Sat Mar 11, 2006 8:20 pm (спустя 5 дней 7 часов 43 минуты; написано за 7 минут 20 секунд)
   Post subject:
Reply with quote

Quote:
при отсутствии какой-то "языковой константы" не выводится ничего (или выводится ошибка. Что из этого лучше - спорный вопрос.)
Quote:
сложно поддерживать проект даже с двумя языками: как правило, я забывал добавить аналогичную переменную в языковой файл с английским языком
Нужно учиться делать хотя бы языковые файлы без синтаксических ошибок :-) Я например для начала полностью сделаю русский файл, а только потом приступаю за англиЦкий копируя полностью содержимое русского, и уже потом переводя :-) И ни каких ошибок с недостающими переменными :)
Quote:
нужно придумывать идентификаторы для каждой надписи, в результате получается "нечитабельный" скрипт со всякими $txt['01'], $txt['indexTitle'] и т.п.
Невижу в этом варианте ничего нечитабельного. Мне например удобнее присваивать такие имена - $txt['номер'], кому-то проще так - $txt['indexTitle'], так или иначе:
1. Пишущий этот код программер недолжен запутаться, если конечно голова на месте
2. В моем случае, я создаю движки в первую очередь для пользователей.

Можно, конечно, пример сделать более разнообразным, типа loadLanguage('index');, а языковые файлы разделить так - index.russian.php, admin.russian.php, settings.english.php и так далее, а loadLanguage будет загружать файлы через другую специальную функцию, которая прежде чем файл загрузить - его как следует обработает на наличие как синтаксических ошибок, так и каких-то других, а потом выдать соотвествующие предупреждение скажем в случае неимения какой-то переменной, или вывести сам .php файл(не полностью, скажем - 5 строк вверх и 5 вниз) с подсвеченным синтаксисом и указателем на место ошибки, в случае синтаксической ошибки.
Back to top
Олег Тaрусoв
Участник форума



Joined: 31 Jan 2006
Posts: 23
Карма: 2
   поощрить/наказать

Location: Санкт-Петербург

PostPosted: Fri Mar 17, 2006 12:17 am (спустя 5 дней 3 часа 57 минут; написано за 1 минуту 7 секунд)
   Post subject:
Reply with quote

KK Project- wrote:
или вывести сам .php файл(не полностью, скажем - 5 строк вверх и 5 вниз) с подсвеченным синтаксисом и указателем на место ошибки, в случае синтаксической ошибки.
А если ошибка будет в середине?
Back to top
View user's profile Send private message
Programmer
Участник форума



Joined: 23 Sep 2005
Posts: 43
Карма: 2
   поощрить/наказать


PostPosted: Sun Mar 26, 2006 7:55 pm (спустя 9 дней 19 часов 37 минут; написано за 4 секунды)
   Post subject:
Reply with quote

Простой класс для обработки создания многоязычного сайта:
Code (php): скопировать код в буфер обмена
<?php

/*
define (www.php.net/define)("OPTIONS_FILE", "lang_*.ini");

/*
interface Options {
    public static (www.php.net/static) function load($file);
}

/*
class Options_ini implements Options {
    public static (www.php.net/static) function load($l) {
        $f = str_replace (www.php.net/str_replace)("*", $l, OPTIONS_FILE);
        return file_exists (www.php.net/file_exists)($f) ? parse_ini_file (www.php.net/parse_ini_file)($f) : exit (www.php.net/exit)("Language file not found");
    }
}

class Language {
    //
    private $classLoad;
    //
    private $language;
    private $langArray;

    public function __construct($classLoad = "ini", $language = "ru") {
        $this->classLoad = $classLoad;
        $this->language = $language;
        $this->langArray = array (www.php.net/array)();
        $this->load();
    }

    public function __get($name) {
        if(array_key_exists (www.php.net/array_key_exists)($name, $this->langArray)) {
            return $this->langArray[$name];
        } else {
            return "null";
        }
    }

    public function __call($f, $a) {
        $c = "Options_" . $this->classLoad;
        if(class_exists (www.php.net/class_exists)($c)) {
            $this->langArray = call_user_func (www.php.net/call_user_func)(array (www.php.net/array)($c, "load"), $this->language);
        }
    }
}

?>
Пример использования:
Code (php): скопировать код в буфер обмена
$test = new Language();
print (www.php.net/print) $test->text;
при lang_ru.ini:
Code (any language): скопировать код в буфер обмена
Back to top
View user's profile Send private message
KK Project
Guest





Карма: 386
   поощрить/наказать


PostPosted: Wed Mar 29, 2006 8:03 am (спустя 2 дня 12 часов 8 минут; написано за 50 секунд)
   Post subject:
Reply with quote

Quote:
А если ошибка будет в середине?
А тут и предполагается что ошибка произошла в середине (5 строк вверх и 5 вниз), в случае если произошла в начале файла - первые 5 вниз, если в конце - первые 5 вверх. Все просто. У меня такая функция уже давно реализована.
Back to top
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Wed Jun 14, 2006 2:22 am (спустя 2 месяца 15 дней 18 часов 19 минут; написано за 14 минут 12 секунд)
   Post subject:
Reply with quote

А что если вместо ключа использовать значение языка по умолчанию? Пример:
lang.php
Code (php): скопировать код в буфер обмена
// Массив доступных языков (первый элемент - язык по умолчанию)
$av_langs = array (www.php.net/array)('ru','ua','en');
// Определяем язык пользователя
$loc_lang = ( isset (www.php.net/isset)($_REQUEST['lang']) && in_array (www.php.net/in_array)($_REQUEST['lang'],$av_langs) ? $_REQUEST['lang'] : $av_langs[0] );

// Массив значений (может храниться и в ini и в БД)
$lang = array (www.php.net/array)(
    'Привет' => array (www.php.net/array)(
        'en' => 'Hello',
        'ua' => 'Привiт',
    ),
    'Яблоко' => array (www.php.net/array)(
        'en' => 'Apple',
        'ua' => 'Яблуко',
    ),
);

function lang($key,$special_lang=NULL) {
    global (www.php.net/global) $lang, $loc_lang;
    $needle_lang = ( $special_lang ? $special_lang : $loc_lang );
    return ( isset (www.php.net/isset)($lang[$key][$needle_lang]) ? $lang[$key][$needle_lang] : $key );
}
Пример использования:
index.php?lang=en
Code (php): скопировать код в буфер обмена
require_once('lang.php');
echo (www.php.net/echo) lang("Яблоко"); // Выведет: Apple
echo (www.php.net/echo) lang("Ананас"); // Выведет: Ананас
echo (www.php.net/echo) lang("Привет","ua"); // Выведет: Привiт
 
Ну и т.д.

Проблема заключается в том, что если мы захотим отредактировать значение языка по умолчанию (в данном случае, русского).. к примеру, вместо "Яблоко", нам захочется чтобы было "Красное яблоко". Тогда придется редактировать все исходные коды, где есть строки lang("Яблоко");.
Во всем остальном, это очень удобно. Я это придумал, еще когда не знал о других всяких методах мультиязычности, и даже об этом форуме. Короче, изобрел велосипед на необитаемом острове (:
Back to top
View user's profile Send private message Send e-mail
Dark-Demon
Участник форума
Banned


Joined: 04 Feb 2007
Posts: 45
Карма: -4
   поощрить/наказать

Location: spb

PostPosted: Sun Feb 04, 2007 8:12 am (спустя 7 месяцев 20 дней 5 часов 49 минут; написано за 20 минут 49 секунд)
   Post subject:
Reply with quote

есть два типа текста:
1. контент - обычно хранится в БД
2. системный текст - например, сообщения об ошибках и прочая статичная информация. лучше располагать его в файлах.
статической инфе место в темплейте.
системным сообщениям - в скрипте.
смысла выделять текст в отдельные языковые файлы - не вижу смысла. более того, для каждого языка нужен свой темплейт, ибо одна и та же фраза на разных языках может быть разной степени многословности, а от этого исходный дизайн может поехать.

поэтому наиболее правильным вариантом я считаю такой:
в темплейте:
Code (any language): скопировать код в буфер обмена
либо сразу на нужном языке, если у нас множественные темплейты.
в основном скрипте аналогично:
Code (any language): скопировать код в буфер обмена
опять же не выносим в отдельный файл, ибо текст ошибки должен быть рядом с местом её возникновения (чтобы чётко понимать, как правильно перевоить).

функция l должна в случае ненахожения варианта для определённого языка должна занести это в логи и тем или иным образом уведомить админа или переводчика с указанием имени файла и номера строки вызова функции. при переводе переводчик врубает поиск текста "l('" и скачет по вхождениям, добавляя перевод.
язык лучше задавать не ввиде одного значения, а ввиде массива, где значения выстроенны обратно приоритету. приоритет берётся из 3х место по очереди (в порядке возрастания приоритета):
1. исходные, записанные в конфиге
2. переданные в заголовке http-запроса
3. переданные через $_GET
с БД всё сильно проще (отдельное поле с указанием языка), правда с оптимизацией запросов могут возникнуть трудности....
при выводе контента можно (и даже лучше) в случае необнаружения нужной языковой версии писать что-то типа: "Данная статья ещё не переведена на ваш язык, но вы можете ознакомиться с ней на следующих языках:" и далее перечисление языков.

ещё раз повторюсь: вынесение локализованного текста в отдельные файлы пагубно ввиду того, что переводчик теряет контекст их использования и следовательно появляются сложности с адэкватным переводом, для программиста же это оборачивается громадным геморроем с регистрацией новых фраз.
Back to top
View user's profile Send private message
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 180
   поощрить/наказать

Location: Москва

PostPosted: Sun Feb 04, 2007 4:09 pm (спустя 7 часов 57 минут; написано за 47 секунд)
   Post subject:
Reply with quote

Dark-Demon
Все правильно пишите.
+1
Back to top
View user's profile Send private message Send e-mail
bmg1
Участник форума



Joined: 25 Dec 2006
Posts: 29
Карма: -6
   поощрить/наказать

Location: Оттуда...

PostPosted: Fri Mar 16, 2007 7:20 am (спустя 1 месяц 11 дней 15 часов 10 минут; написано за 23 минуты 43 секунды)
   Post subject:
Reply with quote

Мы в латвии, уже 10 лет этим занимаемся...

Last edited by bmg1 on Mon Apr 16, 2007 8:17 pm; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
Bu-Bu
Guest





Карма: 386
   поощрить/наказать


PostPosted: Sat Mar 17, 2007 1:31 am (спустя 18 часов 10 минут; написано за 1 минуту 28 секунд)
   Post subject:
Reply with quote

А define никто не пробовал? Буржуйские скрипты многие на define построены. Правда все равно приходится писать языковые файлы, но работает достаточно просто.
Back to top
Ramzes
Участник форума



Joined: 30 May 2004
Posts: 66
Карма: 5
   поощрить/наказать


PostPosted: Wed Mar 28, 2007 7:07 am (спустя 11 дней 5 часов 35 минут; написано за 7 минут 27 секунд)
   Post subject:
Reply with quote

У меня давно была идея написать форум, но т.к. это довольно долгая и муторная затея, пишу я его до сих пор =)) гыы.. Ну вот, т.к. у меня используются компилирующиеся шаблоны я юзал следущий метод. Во время компиляции шаблона выполняется следущий код:
Code (php): скопировать код в буфер обмена
        function clb_translate($text)
        {
                global (www.php.net/global) $langpack;
                if (isset (www.php.net/isset)($langpack[$text[1]])) return $langpack[$text[1]];
                else return 'No translation: '.$text[1];

        }
// ..........
                if ($this->translate)
                $tmp=preg_replace_callback (www.php.net/preg_replace_callback)('#<lang>(.+?)</lang>#s','clb_translate',$tmp); // переведем если надо
                $tmp=str_replace (www.php.net/str_replace)(array (www.php.net/array)('<lang>','</lang>'),'',$tmp);
А сами ленгпаки подключаются из файлика и такого вот содержания:
/langpack/rus.php
Code (php): скопировать код в буфер обмена
$langpack = array (www.php.net/array)(
'Forum'=>'Форум',
'Topics'=>'Тем',
'Posts'=>'Сообщений',
'Last post'=>'Последнее сообщение',
'Topic'=>'Название темы',
'Views'=>'Просмотров',
'Moderators'=>'Модераторы',
);
И шаблоны с такими вот включениями:

/skins/default/templates/forumlist.tpl:
Code (html): скопировать код в буфер обмена
<tr (december.com/html/4/element/tr.html) class="head"> (december.com/html/4/element/.html)<td (december.com/html/4/element/td.html) colspan=5><a (december.com/html/4/element/a.html) href="/forum/{[urlname]}/"> (december.com/html/4/element/.html){[name]}</a></td></tr>
<tr (december.com/html/4/element/tr.html) class="title"> (december.com/html/4/element/.html)
<td (december.com/html/4/element/td.html) colspan=2><lang>Forum< (december.com/html/4/element/.html)/lang></td>
<td> (december.com/html/4/element/td.html)<lang>Topics< (december.com/html/4/element/.html)/lang></td>
<td> (december.com/html/4/element/td.html)<lang>Posts< (december.com/html/4/element/.html)/lang></td>
<td> (december.com/html/4/element/td.html)<lang>Last post< (december.com/html/4/element/.html)/lang></td>
</tr>
Получается так, что сам шаблон на английском языке, а остальные языки подцепляются из ленгпака, переводя английские слова на любой другой...

Шаблоны компилируются в разные файлы в зависимости от языка.

Не знаю к чему меня это приведет, но пока метод нравится... Единственное только впадлу постоянно на двух языках шаблоны делать и неудобно постоянно вставлять теги <lang></lang>

Удобство такого ленгпака заключается в том, что человек, если будет переводить, должен знать хотя бы один из уже переведенных языков, либо английский... И не обязан сидеть, курить мануалы и шаблоны в поисках: "А где же эта долбаная константа {$this->ipsclass->lang['to_post_alt']} и че она вообще означает?!"
Back to top
View user's profile Send private message
bmg1
Участник форума



Joined: 25 Dec 2006
Posts: 29
Карма: -6
   поощрить/наказать

Location: Оттуда...

PostPosted: Wed Mar 28, 2007 3:49 pm (спустя 8 часов 42 минуты; написано за 24 секунды)
   Post subject:
Reply with quote

А как это меняется?
Code (php): скопировать код в буфер обмена
<lang>Last post</lang>
Back to top
View user's profile Send private message Send e-mail
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 269
   поощрить/наказать

Location: Питер

PostPosted: Wed Mar 28, 2007 4:10 pm (спустя 21 минуту)
   Post subject:
Reply with quote

Что интересно, всё делается много проще.
Code (php): скопировать код в буфер обмена
l('string');
и всё тут.

Что делает l()
1. проверяет в базе (или ещё где) есть ли 'string' в текущей локали
2. если нет - добавляет
3. отдаёт строчку из базы

Дальше переводчик тем или иным способом редактирует строчки.
Огромный плюс данного подхода в том, что приложение может быть переведено по-кусочкам с минимальными затратами.
Минус стандартный -- иногда надо проводить валидацию базы, чтобы удалить неиспользуемые строки.
Back to top
View user's profile Send private message
Ramzes
Участник форума



Joined: 30 May 2004
Posts: 66
Карма: 5
   поощрить/наказать


PostPosted: Wed Mar 28, 2007 4:15 pm (спустя 4 минуты; написано за 32 секунды)
   Post subject:
Reply with quote

bmg1 wrote:
А как это меняется?
Не понял сути вопроса... preg_replace_callback`ом при компиляции...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Goto page 1, 2  Next
Page 1 of 2    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML