Yii Framework Forum: Локализация - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Локализация Rate Topic: -----

#1 User is offline   carat 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 60
  • Joined: 12-February 09

Posted 25 February 2009 - 11:55 AM

делаю проект и по ходу разбираюсь в документации. сайт будет на 3-х
языках англ.(En), русский(Ru), испанский(Es). вроде в документации по
этой теме пробелы.

вот актуальные вопросы:

1. как сконфигурировать языки?
2. как выбор языков "играет" в строке запроса ($_GET['lang'])?
3. выбор актуального сообщения на текущем языке.
4. как вывести на форме ввода сразу 3 перевода (например, слово "Название")?
0

#2 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 25 February 2009 - 02:15 PM

Локализацией плотно не занимался, скажу что занаю, остальное надо у Qiang спрашивать на английском форуме. Если тебе сложно на англ. я могу спросить и перевести сюда, но это будет долго, время перевода+время "врубиться" в ответ.

Итак:
1. Перевод делается методом Yii::t(string $category, string $message, array $params=array ( ), string $source=NULL) и происходит в том случае, когда исходный язык и целевой язык различаются. Исходный язык задается с помощью свойства sourceLanguage. Конфигурируется так же как и любое другое свойство приложения - через конфиг. Целевой язык (на котором пользователь просматривает сайт) содержится в свойстве language приложения. Его т тоже можешь задать по дефолту, а после обработки параметров устанавливать как тебе надо. Чтобы его устанавливать, можно подписаться на событие onbeginRequest приложения. Подробнее про события - в разделе Компонент.
Для каждого языка тебе надо выбрать метод перевода - база, gettext, просто пхп-файлы. Я пробовал только последний. Он по умолчанию и идет.
Файлы перевода ложить сюда:/protected/messages/LocaleID/CategoryName.php
LocaleID - это то, что пишется в свойстве language. Для русского будет ru_RU, для английского великобритании - en_GB, для сша - en_US, посмотри код нужных тебе локалей.
2. Немного не понял вопрос. Я думаю. речь идет о том, как установить текущий язык? Это делается ручками. Либо подписываешся на событие, как  писал выше, либо создаешь фильтр, который переключает текущий язык. Например, в зависимости от $_GET. Можно например и в куках, тут только твоя фантазия. Про фильтры смотри в разделах Контроллер и Создание дополнений (англ).
3. Вызываешь Yii::t(); там где надо получить выводимое сообщение. Это, кстати написано в разделе интернационализации. Там есть три пункта, которые надо сделать, чтобы локализовать приложение
4. А вот это проблема. Не знаю, думал ли об этом Qiang, когда создавал движок. Сам спросишь на форуме или мне спросить? Ну "через задницу" - понятно - переключаем локаль и выводим. И так 3 раза, потом возвращаем в исходное. Но это глупо, надо как-то поумнее. А вообще-то я редко встречал хорошие сайты, где одновременно несколько языков было бы. Обычно юзеру дается вариант переключить язык и потом выводишь ему на выбранном языке. Но проблема остается, спорить не буду.

Резюме: Внимательнее перечитай раздел локализации. По №4 спроси на общем форуме, я не знаю. Если еще непонятки - давай, будем решать.
0

#3 User is offline   donga 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 22-February 09

Posted 26 February 2009 - 06:11 AM

Доброго времени суток!

Подготавливаюсь перенести проект на yii framework.

С четвертой проблемой я немного переписал для себя код, чтобы можно было принудительно выбрать язык перевода.

framework\YiiBase.php

public static function t($category,$message,$params=array(),$source=null,$language=null)
{
if(self::$_app!==null)
{
if($source===null)
$source=$category==='yii'?'coreMessages':'messages';
if(($source=self::$_app->getComponent($source))!==null)
$message=$source->translate($category,$message,$language);
}
if($params===array())
return $message;
if(isset($params[0])) // number choice
{
$message=CChoiceFormat::format($message,$params[0]);
unset($params[0]);
}
return $params!==array() ? strtr($message,$params) : $message;
}


framework\i18n\CMessageSource.php

public function translate($category,$message,$language=null)
{
        if($language!==null)
            return $this->translateMessage($category,$message,$language);
else if(($lang=Yii::app()->getLanguage())!==$this->getLanguage())
return $this->translateMessage($category,$message,$lang);
else
return $message;
}


Вызываем так:

echo Yii::t('category', 'word', null, null, 'en_us');
echo Yii::t('category', 'word', null, null, 'ru_ru');


Надеюсь, в скором времени Квонг как-то решит данную проблему.
0

#4 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 26 February 2009 - 08:31 AM

Обовите свн, qiang сказал что уже пофиксил эту штуку, я не проверял.
0

#5 User is offline   rosko 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 211
  • Joined: 04-January 09
  • Location:Kiev, Ukraine

Posted 26 February 2009 - 09:30 AM

Хех, быстро сработано. Спасибо, Костя.
Я тоже вот на днях столкнулся с этим, решил отложить, а тут это и пофиксили :)
0

#6 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 26 February 2009 - 10:31 AM

Ну я попросил - он сделал :)
Мне вот интересно, кем он работает если может опен-сорс проектом постоянно заниматься...

Документация еще не обновлена, кто посмотри как сделано - скажете как юзать?
0

#7 User is offline   donga 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 22-February 09

Posted 26 February 2009 - 03:23 PM

Quote

Мне вот интересно, кем он работает если может опен-сорс проектом постоянно заниматься...

Мне тоже. Вы спросите у него  :)

Quote

Документация еще не обновлена, кто посмотри как сделано - скажете как юзать?


Вы говорите про четвертую проблему? Чтобы через Yii::t() вывести перевод для определенного языка? Посмторел SVN v756, ничего не поменялось, связанное с переводами.

UPDATE:
В SVN v769 изменения добавлены. Спасибо.

/**
* Translates a message to the specified language.
* Starting from version 1.0.2, this method supports choice format (see {@link CChoiceFormat}),
* i.e., the message returned will be chosen from a few candidates according to the given
* number value. This feature is mainly used to solve plural format issue in case
* a message has different plural forms in some languages.
* @param string message category. Please use only word letters. Note, category 'yii' is
* reserved for Yii framework core code use. See {@link CPhpMessageSource} for
* more interpretation about message category.
* @param string the original message
* @param array parameters to be applied to the message using <code>strtr</code>.
* Starting from version 1.0.2, the first parameter can be a number without key.
* And in this case, the method will call {@link CChoiceFormat::format} to choose
* an appropriate message translation.
* @param string which message source application component to use.
* Defaults to null, meaning using 'coreMessages' for messages belonging to
* the 'yii' category and using 'messages' for the rest messages.
* @param string the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
* This parameter has been available since version 1.0.3.

* @return string the translated message
* @see CMessageSource
*/
public static function t($category,$message,$params=array(),$source=null,$language=null)
0

#8 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 28 February 2009 - 04:02 AM

Не стал заводить нову тему. Спрошу здесь!

Сейчас тоже начал разбираться с тем как перевести проект на Yii на разные языки.
С настройками языков (sourceLanguage и language) кажется разобрался.
Так вот вопрос...я правильно понял что для обеспечения многоязычности - необходимо все строковые константы заменить на вызов Yii::t().
Т.е. если в модели я пишу так:


  public function attributeLabels()
    {
        return array(
            'id'        => 'идентификатор',
            'firstName'  => 'Имя',
            'lastName'  => 'Фамилия',
            'secondName' => 'Отчество',
            'password'  => 'Пароль',
            'status'    => 'Статус',
            'accessLevel' => 'Уровень доступа'
        );
    }


то это необходимо заменить на

  public function attributeLabels()
    {
        return array(
            'id'        => Yii::t(....)
            'firstName'  => Yii::t(....),
            'lastName'  => Yii::t(....),
            'secondName' => Yii::t(....),
            'password'  => Yii::t(....),
            'status'    => Yii::t(....),
            'accessLevel' => Yii::t(....)
        );
    }



аналогично и во view для вывода статичных сообщений.

Я прав?? Или что-то не так понял??
0

#9 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 28 February 2009 - 08:00 AM

Все верно, именно так :)
0

#10 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 28 February 2009 - 10:42 AM

Предлагаю обсудить еще один вопрос.
А именно,если файл с переводом - это простой php файл, содержащий массив сообщений, то в случае большого сайта - размер такого файла, и следовательно занимаемый им объем - будет велик. Следовательно целесообразно разделить его на несколько более мелких.
Как это правильнее и структурнее сделать??
У меня есть следующие варианты:
1) Оставить все в одном файле - (не подходит)
2) Создавать файлы перевода для каждого контроллера и его представлений (view)
3) Создать один общий файл перевода (для каких то общеупотребительных терминов), а так же создавать файлы для каждого контроллера

Может есть еще какие то варианты??
0

#11 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 28 February 2009 - 10:53 AM

Я думаю, проще всего разбить по контроллерам. А для перевода по кнтексту есть первый параметр в методе Yii::t().
0

#12 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 28 February 2009 - 11:28 AM

Так я как раз и хотел - использовать контекст в качестве имени контроллера
пример
Yii:t('User','имя')
где User - это название файла перевода и одновременно название контроллера, сообщения которого переводятся.
0

#13 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 28 February 2009 - 11:31 AM

ага, только с маленькой буквы. Так же как в пути к контроллеру, соблюдая соглашения (http://www.yiiframew...sics.convention)
0

#14 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 28 February 2009 - 11:33 AM

И плюс еще не забудь, Yii выдает стандартные сообщения. Где-то они там у него уже переведены, но надо в фреймворке смотреть и проверять русскую грамматику - мало ли как перевели, а тебе проект сдавать. /yii/messages/ru/yii.php
0

#15 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 28 February 2009 - 11:38 AM

Ну конечно же  ;)
0

#16 User is offline   carat 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 60
  • Joined: 12-February 09

Posted 19 March 2009 - 03:23 PM

Quote

1. как сконфигурировать языки?

2. как выбор языков "играет" в строке запроса ($_GET['lang'])?

3. выбор актуального сообщения на текущем языке.

4. как вывести на форме ввода сразу 3 перевода (например, слово "Название")?


1.  организация папок см. скриншот. в файле конфигурации:
[tt].....
'sourceLanguage'=>'ru_ru',
'language'=>'ru_ru',
.....[/tt]
3.  [tt]Yii::t('admin.label','Дата');[/tt]
4.  [tt]Yii::app()->messages->translate('admin.label','Название','en_us');[/tt]


2.

Quote

можно подписаться на событие onbeginRequest приложения. Подробнее про события - в разделе Компонент
- нельзя. еще не пропарсена строка запроса. (можно организовать это вручную, но овчинка выделки не стоит, дублируется)
--------------------------------------------------------------------------
что бы языки "заиграли" в запросе GET, в конфигурации прописал так:
[tt]        'urlManager'=>array(
          'rules'=>array(
// localhost/EN/news, либо localhost/ES/news
              '<lang:(EN|ES)>/news/<id:\d+>'=>'news',
              '<lang:(EN|ES)>/news'=>'news/table',
              '<lang:(EN|ES)>/news/page/<id:\d+>'=>'news/page',
              '<lang:(EN|ES)>/news/add'=>'news/add',
              '<lang:(EN|ES)>/news/edit/<id:\d+>'=>'news/edit',
              '<lang:(EN|ES)>/news/delete/<id:\d+>'=>'news/delete',
// русский, язык по умолчанию  localhost/news
              'news/<id:\d+>'=>'news',
              'news'=>'news/table',
              'news/page/<id:\d+>'=>'news/page',
              'news/add'=>'news/add',
              'news/edit/<id:\d+>'=>'news/edit',
              'news/delete/<id:\d+>'=>'news/delete',
[/tt]возможно можно шаблон прописать и короче для "пустого"
русского языка, но не силен в регулярных дебрях, сорри
на данный момент перестал работать контроллер по умолчанию,
типа: localhost/ , localhost/EN.  чешу репу.....

дописываем в конфиг и заработало:
  [tt] '<lang:(EN|ES)>'=>'контроллер по умолчанию',
'<lang:(EN|ES)>'=>'',  //либо пустую строку[/tt]
--------------------------------------------------------------------------
формирование ссылок в системе пока сделал так:
[tt]//  localhost/EN/news, либо localhost/ES/news, либо localhost/news
$lang = (isset($_GET['lang']) ? array('lang'=>$_GET['lang']) : array());
$id = array('допустим_GET_парамерт_id'=>$row['id']);
$this->createUrl('имя_экшана', array_merge($lang, $id));[/tt]
--------------------------------------------------------------------------
установка языка в системе и формирование ссылок.
- в контроллерах использ. внешний фильтр:
[tt]    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
            array(
                'application.filters.InitLang',  //создать папку private/filters
            ),
        );
    }
[/tt]
- файл InitLang.php:
[tt]class InitLang extends CFilter
{
    protected function preFilter($filterChain)
    {
        $_GET['lang'] = (isset($_GET['lang']) ? $_GET['lang'] : 'RU');
        switch ($_GET['lang']) {
            case 'EN':
                Yii::app()->language = 'en_us';
                Yii::app()->params['lang'] = array('lang'=>$_GET['lang']);  // запомнить в конфигурации
                break;
            case 'ES':
                Yii::app()->language = 'es_es';
                Yii::app()->params['lang'] = array('lang'=>$_GET['lang']);
                break;
            //default:  - инициализировано в кунфигурации
            //    Yii::app()->language = 'ru_ru';
            //    Yii::app()->params['lang'] = array();
        }
        return true; // false - в случае когда следует запретить выполнение экшна
    }
    protected function postFilter($filterChain)
    {
        // код, выполянемый после запуска экшна
    }
}[/tt]
- конфигурация:
[tt]    'params'=>array(
        'adminEmail'=>'webmaster@example.com', // this is used in contact page
        'lang'=>array(), //для ссылок, filter InitLang, пустой array() для 'RU'
        .........[/tt]
- формирование ссылок в системе:
$params = array_merge(Yii::app()->params['lang'], array('id'=>$row['id']));
$this->createUrl('edit', $params);
--------------------------------------------------------------------------
это все. спасабо всем кто принял обсуждение в топике

Attached File(s)

  • Attached File  langs.PNG (6.72K)
    Number of downloads: 19

0

#17 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 25 March 2009 - 02:54 AM

Quote

Quote

можно подписаться на событие onbeginRequest приложения. Подробнее про события - в разделе Компонент
- нельзя. еще не пропарсена строка запроса. (можно организовать это вручную, но овчинка выделки не стоит, дублируется)


А знаешь, мне кажется в тыщу раз проще именно подписаться на это событие :) Тогда:
1) Избегаешь таких сложных правил в урл менеджере
2) Вообще можешь не учитывать язык там (потому что после парсинга, а фактически просто считывания первых 3х символов запроса, ты язык просто убираешь, пусть Yii самостоятельно разбирает дальше)
3) Проблема с "пустым" языком решается элементарно

А как насчет записывать выбранный язык не в параметры приложения (которые в теории не должны сохраняться от запроса к запросу. А если и сохраняются - то для всех юзеров), а в Yii::app()->user->lang='EN' для зарегистрированных и в сессии - для незарегистрированных. Доступ к сессии - тоже через свойство CWebApplication, посмотри доки.

По поводу конфигурации можешь еще глянуть мое дополнение для сохранения конфига в базе - http://www.yiiframew...ension/dbparam/
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users