Формы и кодировка

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
‡[анти]КИЉЕР‡
Сообщения: 14
Зарегистрирован: 2010.06.20, 13:23

Формы и кодировка

Сообщение ‡[анти]КИЉЕР‡ »

Вообще тема уже была затронута в viewtopic.php?f=3&t=1108&p=8048
Но вот обязательно ли для каждой модели прописывать attributeLabels() или все же можно как то сделать чтобы по дефолту в label возвращались верные кодировки.

К тому же что делать для стандартных форм. Например в форме ввода логина и пароля:

Код: Выделить всё

    <p class="note">Поля, помеченные <span class="required">*</span> обязательны для заполнения.</p>

    <div class="row">
        <?php echo $form->labelEx($model,'Логин'); ?>
        <?php echo $form->textField($model,'username'); ?>
        <?php echo $form->error($model,'username'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'Пароль'); ?>
        <?php echo $form->passwordField($model,'password'); ?>
        <?php echo $form->error($model,'password'); ?>
        <p class="hint">
            Подсказка: Для входа пользователем используйте <tt>itsUser/pgta</tt>, а для входа под администратором <tt>admin/pgta</tt>.
        </p>
    </div>

    <div class="row rememberMe">
        <?php echo $form->checkBox($model,'rememberMe'); ?>
        <?php echo $form->label($model,'Запомнить меня'); ?>
        <?php echo $form->error($model,'rememberMe'); ?>
    </div>
Вместо подписей к полям "логин", "пароль" и "Запомнить меня" выводятся крякозяблы.

В общем есть ли какой-то решение, чтобы без добавления новых методов и переопределения, скажем LoginForm всё отображалось как нужно.

P.S. Естественно всё в utf-8 кодировке
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Формы и кодировка

Сообщение mitallast »

Читайте документацию! Даже если не знать английский (лично у меня была тройка, хотя по-честному могли поставить и кол), видно из параметнов метода
http://www.yiiframework.com/doc/api/CAc ... lEx-detail
что второй атрибут не сама надпись в label, а атрибут, для которого выводится label. Имя атрибута инкапсулируется в классе, описывающем модель - дабы небыло нужды менять все лейблы по ctrl+H по проекту.

В конечном счете можно перегрузить метод getAttributeLabel (или как там он зовется) чтобы прогонял запрашиваемый атрибут через перевод Yii::t();

А проблемы с кодировками, скорее всего, в фиче реализации метода, генерирующего label по названию атрибута. Если память не изменяет, класс CModel и метод generateAttributeLabel($attribute);
Поскольку писать названия атрибутов класса на расовом языке, а не на английском считается моветоном, то естественно отсутствие в том методе модификатора u в preg_replace каком-нибуть.
‡[анти]КИЉЕР‡
Сообщения: 14
Зарегистрирован: 2010.06.20, 13:23

Re: Формы и кодировка

Сообщение ‡[анти]КИЉЕР‡ »

Проблема решена. Если вдруг кому-то понадобится - выкладываю решение:
Итак, проблема была действительно в методе класса CModel

Код: Выделить всё

    public function generateAttributeLabel($name)
    {
        return ucwords(trim(strtolower(str_replace(array('-','_','.'),' ',preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $name)))));
    } 
А именно в том, что функция strtolower не корректно работает с двухбайтовыми кодировками и коверкает utf-8 кириллицу.
А так, как запускается это всё дело из виджета CActiveForm я решил перегрузить методы этого виджета, передавая дальше текст в однобайтовой кодировке:

Код: Выделить всё

<?php
class Form extends CActiveForm
{
  public function labelEx($model,$attribute,$htmlOptions=array())
    {
      $attribute=iconv('utf-8','windows-1251',$attribute);
      return iconv('windows-1251','utf-8',CHtml::activeLabelEx($model,$attribute,$htmlOptions));
    }
    
  public function label($model,$attribute,$htmlOptions=array())
    {
      $attribute=iconv('utf-8','windows-1251',$attribute);
      return iconv('windows-1251','utf-8',CHtml::activeLabel($model,$attribute,$htmlOptions));
    }
}
?>
Собственно всё! Конечно, может это не совсем корректное решение передавать параметры не в той кодировке, в которой они должны работать в принципе, и везде придётся использовать вместо $this->beginWidget('CActiveForm',........ виджет $this->beginWidget('Form',... но зато голова о кириллице в формах больше болеть не будет.
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Формы и кодировка

Сообщение mitallast »

Неверно.
Во первых, откройте для себя набор функций, работающих с мультибайтовыми кодировками - в данном случае требуется mb_strtolower().

Во вторых, еще раз повторю - прочтите наконец документацию и перестаньте изобретать велосипед. Для кастомизации отображения лейбла требуется всего лишь :
$form->label( $model , "foo", array(
"label" => "the foo label"
));

Т.е нужно то было передать значение ключа label в параметре htmlOptions
gamark
Сообщения: 13
Зарегистрирован: 2010.12.02, 16:50

Re: Формы и кодировка

Сообщение gamark »

mitallast, спасибо за хороший вариант решения проблемы. Действительно удобно с label... ;)


зы кому надо вот пример такого кода в стандартном блоге, файл protected/views/site/login.php

Код: Выделить всё

<div class="row">
        <?php echo $form->labelEx($model,'password', array("label"=>"Пароль")); ?>
        <?php echo $form->passwordField($model,'password'); ?>
        <?php echo $form->error($model,'password'); ?>
        <p class="hint">
            Hint: You may login with <tt>demo/demo</tt>.
        </p>
</div>
а вообще mb_* ведь достаточно громоздкий модуль?
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Формы и кодировка

Сообщение mitallast »

а вообще mb_* ведь достаточно громоздкий модуль?
А есть альтернативы ;) ? Я в принципе не особо вижу проблему мультибайтных кодировок при грамотной разработке средств, работающих со строками.
Даже если брать уровень С++ , какая разница ? Поведение управления памятью по идее должно быть инкапсулированно в классе, представляющем строки.
splatt
Сообщения: 1
Зарегистрирован: 2012.01.28, 23:05

Re: Формы и кодировка

Сообщение splatt »

Несмотря на то, что темка старая, объясню ситуацию новичкам, которые могут столкнуться с этой проблемой, как и я.
С толку сбивает реализация CHtml::activeLabel, которая в случае отсутствия атрибута создает его через CModel->generateAttributeLabel (и при этом парсит строку через preg_replace, из-за чего сбивается кодировка). Именно поэтому я (и, скорее всего, автор топика), был сбит тем, что при вызове $form->label($model,'mytitle') корректно отобразиться созданный атрибут mytitle, но некорректно отобразятся русские символы.
Поэтому, тут три варианта действий:
1) Если у модели есть конкретное поле, которое вы выводите в форме, просто добавьте атрибут в модель:

Код: Выделить всё

    public function attributeLabels()
    {
        return array('title' => 'Заголовок');
    } 
2) Если вам нужно вывести текст из базы данных (мой случай), можно указать поле:

Код: Выделить всё

    public function attributeLabels()
    {
        return array('title' => $this->title);
    } 
3) Ну а если вам нужно вывести совсем кастомный текст, и отсутствует возможность внести его в модель атрибутом, то тут уже написал mitallast:

Код: Выделить всё

$form->label( $model , "sometext", array("label" => "Текст!"));
 
Ответить