Интернационализация

Я использую в приложении CPagination.

В конфиге указываю:




    'charset'=>'cp1251',

    'sourceLanguage'=>'en',

    'language'=>'ru',



Естественно перевод получается не очень… Насколько я понял, переводы внутри фреймворка используют юникод. Возможно добится постраничного просмотра по-русски при использовании cp1251?

Разобрался.

В конфиге пишем:




'components'=>array( 

    ...

    'coreMessages'=>array(

            'class'=>'CPhpMessageSource',

            'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'messages',

        ),

    ...

),



В директории приложения protected/messages создём папку "ru" c файлом "yii.php". (Можно скопировать из директории фреймворка.)

В этом файле пишем какие угодно переводы сообщений фреймворка.

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

Не подскажете как это сделать, судя по исходникам


framework/i18n/CLocale.php

data - прописан жестко, и нельзя его инициализировать через приложение. Очень бы не хотелось помнить и менять локализацию всередине framework из utf-8 на cp1251 путем тупо перекодирования файла локали.

Да, действительно… Думаю, можно попробовать унаследовать свой класс от CLocale. А у вас какой-то конкретный случай, или просто научный интерес? Может быть озвучите подробности?

Когда я вывожу данные из mysql, то для отображения локализированных дат с учетом мое локали, я написал функцию:




function sql_date_to_human( $sql_date, $with_time = false )

{

  $timestamp = CDateTimeParser::parse( $sql_date, 'yyyy-MM-dd hh:mm:ss');

  if ( !$timestamp ){

    $timestamp = CDateTimeParser::parse( $sql_date, 'yyyy-MM-dd');

  }


  if ( $with_time ){

    return app()->locale->dateFormatter->formatDateTime( $timestamp, 'long' );

  }else{

    return app()->locale->dateFormatter->formatDateTime( $timestamp, 'long', null );

  }

}



Но локаль, берется для кодировки utf-8. Не понятно често говоря, почему разработчики не предусмотрели вариант использования локали в других кодировках.

Похоже, унаследовать свой клас от CLocale - тот способ. Либо форматировать дату самостоятельно.

Например так:




protected $birthDateF;

    

public function getBirthDateF()

{

    return date('d.m.Y',strtotime($this->birthDate));

}



это конечно жесткий оффтоп, но раз создается новый проект на новом фреймворке, то зачем utf-8 не использовать сразу, к чему этот cp1251 ?

В моем случае я действительно начинал на utf-8, немного с извратом, так как базы у меня была в cp1251 и не было возможности ее перекодировать так как она не моя и я с нее только читал, то я выкрутился через дополнительный класс, который наследовал для каждой таблицы CActiveRecord





/**

 * Специальный прокси класс, который при возврате данных полей из

 * SQL-запросов конвертирует их из cp1251 в UTF8

 */

class CActiveRecordIconv extends CActiveRecord

{


    /**

     * Прописываем методы, специально для того, чтобы конвертировать данные

     * по выбраным полям из cp1251 а utf-8

     * Так как Yii - базируется на кодировке utf-8.

     */

    public function onAfterFind(){

         

        foreach( array_keys( $this->attributeLabels() ) as $key ){

            $meta_cols = $this->getTableSchema()->getColumn( $key );

            if ( $meta_cols->type == 'string' )

                $this->setAttribute($key, iconv('cp1251', 'utf-8', $this->getAttribute( $key ) ) );

        }

         

    }


    public static function fix_in_charset( $str ){

      return iconv( 'utf-8', 'cp1251', $str );

    }

    

}



И все было хорошо и красиво, пока я не столкнулся с такой дикой особенность в другом проєкте, когда я создавал форму CFormModel, а там прописывал валидатор ‘length’, то при валидации формы, мне на поля с кириличными значениями, кричало, что превышина длина строк, так как в


CStringValidator

, есть кусочек как мне кажется глупого кода, когда длина строки определяется, через strlen даже для utf-8 кодировки.




	/**

	 * Validates the attribute of the object.

	 * If there is any error, the error message is added to the object.

	 * @param CModel the object being validated

	 * @param string the attribute being validated

	 */

	protected function validateAttribute($object,$attribute)

	{

		$value=$object->$attribute;

		if($this->allowEmpty && ($value===null || $value===''))

			return;

		$length=strlen($value);

		if($this->min!==null && $length<$this->min)

		{

			$message=$this->tooShort!==null?$this->tooShort:Yii::t('yii','{attribute} is too short (minimum is {min} characters).');

			$this->addError($object,$attribute,$message,array('{min}'=>$this->min));

		}

		if($this->max!==null && $length>$this->max)

		{

			$message=$this->tooLong!==null?$this->tooLong:Yii::t('yii','{attribute} is too long (maximum is {max} characters).');

			$this->addError($object,$attribute,$message,array('{max}'=>$this->max));

		}

		if($this->is!==null && $length!==$this->is)

		{

			$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is of the wrong length (should be {length} characters).');

			$this->addError($object,$attribute,$message,array('{length}'=>$this->is));

		}

	}



Вы сами понимаете, что необходимо смотреть на кодировку, чтобы использовать правильную функцию для определения страницы, это меня и подтолкнуло перевести проект на cp1251. Но там появились сложности віше описанные :-).

P.S. Я совсем недавно пишу на Yii, мое мнение он еще сыроват, но я готов помогать в его разработке. Переиодически пишу issues и их таки там исправляют, что не может не радовать.