Neurons to bytes

Использование Zend_Form без декораторов

Лично мне использование декораторов в формах в Zend Framework никогда не нравилось, потому что это никогда не было для меня удобным. Каждый раз, когда приходилось добавлять дополнительные элементы и разметку в довольно сложную форму, это превращалось в великую головную боль.

Кроме того, я почему-то уверен, что использование декораторов в Zend Form это не лучшее решение. В настоящей действительности все чаще приходится работать с готовой XHTML разметкой, которую предоставляет верстальщик. В таком случае, программисту приходится “переводить” уже сверстанную форму в php-код. Разве это удобно, разве это способствует продуктивности? Никак нет. Просто делается лишняя работа, вместо того, чтобы подставить в нужные места формы вывод ошибок и прочего.

Но как сделать так, чтобы наша форма сохраняла функциональность валидаторов, “зашитых” в ней, и при этом мы могли бы визуально видеть разметку формы? Как ни странно, но в этом нам поможет декоратор!

В стандартной поставке Zend Form существует декоратор viewScript, он то нам и поможет. Наиболее простым решением будет создать новый класс, унаследованный от Zend Form. От этого нового класса мы будем наследовать все остальные классы форм, используемые в проекте.

Посмотрим на код:

class Project_Form extends Zend_Form
{
    /**
     * Установить шаблон для формы
     *
     * @param string $template Имя файла с шаблоном без расширения
     */
    public function setTemplate($template)
    {
        $this->setDecorators(array(
            array('viewScript', array(
               'viewScript' => $template . '.html'
            )))
        );
    }

    /**
     * Добавление элемента в форму без декораторов
     *
     * @see Zend_Form::addElement()
     */
    public function addElement($element, $name = null, $options = null)
    {
        parent::addElement($element, $name, $options);

        if (isset($this->_elements[$name])) {
            $this->_elements[$name]->removeDecorator('Label');
            $this->_elements[$name]->removeDecorator('HtmlTag');
            $this->_elements[$name]->removeDecorator('DtDdWrapper');
            $this->_elements[$name]->removeDecorator('Description');
        }
    }

    /**
     * Создание элемента формы
     *
     * @see Zend_Form::createElement()
     */
    public function createElement($type, $name, $options = null)
    {
        $element = parent::createElement($type, $name, $options);
        $element->removeDecorator('Label');
        $element->removeDecorator('HtmlTag');
        $element->removeDecorator('DtDdWrapper');
        $element->removeDecorator('Description');
        return $element;
    }
}

Это наиболее простой способ удобного использования декоратора. Теперь, в ваших классах форм вам достаточно вызывать метод setTemplate() с указанием имени шаблона для формы. Так же мы видим два переопределенных метода: addElement() и createElement(). Они создают и добавляют элементы в форму без декораторов по-умолчанию, чтобы элементы формы не были обернуты ненужными нам тегами. Конечно, можно автоматизировать выбор шаблона, чтобы вам не приходилось вручную указывать его. Я показал наиболее простой пример использования, выбор реализации остается за вами.

При таком подходе, для каждой формы используется отдельный шаблон. Давайте взглянем на то, как может выглядеть шаблон:

<form
    action="<?=$this->element->getAction()?>"
    method="<?=$this->element->getMethod()?>">

    <div class="separate-field">
        <label for="sitemap-title"><?=$this->translate('Заголовок страницы')?></label>
        <?= $this->element->title ?>
    </div>

    <div class="edit-field">
        <?= $this->element->article ?>
    </div>

    <div class="action-bar">
        <?= $this->element->submit ?>
    </div>
</form>

Как мы видим, теперь все поля формы вставляются вручную. Теперь, у нас нет никаких декораторов. Радуемся :)

Я сейчас думаю над более комплексным решением для работы с формами под Zend Framework. Возможно, в моем решении пакет Zend Form вообще отпадёт за ненадобностью. Я сейчас использую Zend Form в основном для удобной валидации, так как все валидаторы на форму расположены в одном месте, в классе формы. Но я планирую делать валидацию в конечной точке пользовательского запроса - в модели. В этом случае, Zend Form мне уже не понадобится.

Программирование форм - это нудятина. Нам всем (веб-разработчикам) нужно искать средства избавления от нее :)

Надеюсь, было интересно :) Жду комментов.

Also interesting

Tag after , , ,

  1. atukai says:

    Вместо element->getAction()?> скорее всего form->getAction()?>

  2. Dr0n says:

    Можно назвать это хаком). Но для меня тоже подошло. Спасибо.
    Кстати не совсем понятно для чего нужен отдельный html шаблон для формы?
    Не проще ли также выводить эллементы формы но только во вььюхе контроллера конкретного акшена?
    Там где конечно необходимо повторно дублировать форму это поможет, но реально в целом проекте таких мест не так уж и много.
    И кстати вечная делема, где хранить инициализацию эллементов формы, ini, xml, или на лету создавая обьекты.
    зы кстати тоже совсем не нравяться формы, нудщятина которая занимает слишком много времени

  3. Dr0n says:

    Кстати поправте код:
    [php]
    if(null == $name ) {
    $name = $element->getName();
    }
    [/php]


(required)


(required but won't be displayed)