Pull to refresh

Zend_Form и ini-файлы

Reading time6 min
Views1.8K
Zend Framework обсосан с многих сторон и имеет неплохую документацию. Но работа с формами через Zend_Form имеет свои подводные камни, обусловленные массой возможностей, которые даже в официальной документации не освещены достаточно хорошо.

Я хочу рассказать о настройке форм через ini-файлы. Это будет полезно программистам и верстальщикам.

Полагаю, что вы уже примерно знаете, что представляет собой Zend Framework и знаете где находится его документация. Возможно, вы даже используете Zend_Form в своих проектах.

Если нет, то вот базовые понятия:
  • Элемент. Собсно, формализованный html-элемент формы. Стандартные называются Zend_Form_Element_* и являются потомками Zend_Form_Element. Собственные элементы создаются путем расширения стандартных. Подробнее тут.
  • Декораторы. Отвечают за генерацию html. Почему-то одна из самых сложных для понимания штук, но при этом весьма мощный и гибкий инструмент. Подробнее тут, тут и тут.
  • Валидаторы. Занимаются проверкой данных и генерацией сообщений об ошибках. Подробнее тут.
  • Фильтры. Фильтруют и изменяют данные полученные из формы. Например, если пользователь вводит " вася пупкин ", то приведением к виду «Вася Пупкин» занимаются фильтры. Подробнее тут.
  • Группа элементов. DisplayGroup — инструмент для визуального объединения элементов в группы.
  • Трансляторы. Поддержка нескольких языков. Подробнее тут.

Для проверки форм вам понадобятся два файла form.php и form.ini. Первый тут, а о втором я сейчас расскажу.
<?php

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

$view = new Zend_View();
$view->doctype(Zend_View_Helper_Doctype::XHTML1_STRICT);

$conf = new Zend_Config_Ini('form.ini');

$form = new Zend_Form($conf);
$form->setView($view);

echo 
$form;


Структура ini-файла


В файле указываются атрибуты тега <form>, глобальные значения, элементы, значения по-умолчанию для элементов и т.п.

Атрибуты


Все нераспознанные ключи интерпретируются как атрибуты тега <form>. Но их можно указать и явно через attrs.*.
;;;;
;;;; form.ini
;;;;


action = /some/url

; post | get | put | delete
method = post

; "application/x-www-form-urlencoded" | "multipart/form-data"
enctype = "custom-enctype"

; требует декоратора Description
description = "form description"

; требует декоратора Fieldset
legend = "form legend"

; <form name="">
name = "attr name"

; int - порядок для SubForm (когда форма является частью другой формы)
order = 1

; true | false - выключить установку и загрузку декораторов по-умолчанию
; При использовании ini-файлов абсолютно бесполезная опция (см. decorators.*)

disableLoadDefaultDecorators = false

; true | false - выключение трансляторов
disableTranslator = false

; attribs.* - явная установка атрибутов тега <form>
attribs.action = /yet/another/url ; перезапишет значение action если указано после него
attribs.my_pretty_cool_attr = value ; <form my_pretty_cool_attr="value"/>

; defaults.* - установка значений полей по-умолчанию.
defaults.myfield = "Default value for my field"
defaults.anotherfield = "Pretty nice value for another field""

Пути к классам


; prefixPath - префиксы для автоматической загрузки классов элементов и декораторов
; Дефолтное значение:

prefixPath.prefix = Zend_Form_
prefixPath.path = Zend/Form/

; Для декораторов префикс и путь будут изменены на Zend_Form_Decorator_MyDecorator
; и Zend/Form/Decorator/MyDecorator.php
; Для элементов соответственно на Zend_Form_Element_MyElement и Zend/Form/Element/MyElement.php
; В случае, если классы нужно искать в нескольких местах, то:

prefixPath.zend.element.prefix = Zend_Form_Element_
prefixPath.zend.element.path = Zend/Form/Element/
prefixPath.zend.decorator.prefix = Zend_Form_Decorator_
prefixPath.zend.decorator.path = Zend/Form/Decorator/
prefixPath.custom.prefix = MyProject_Form_
prefixPath.custom.path = MyProject/Form/

; elementPrefixPath - префиксы, которые будут установлены каждому элементу формы elements.*
; Устанавливаются для декораторов, фильтров и валидаторов
; В остальном, так же как и prefixPath.*

elementPrefixPath.decorator.prefix = Zend_Form_Decorator_
elementPrefixPath.decorator.path = Zend/Form/Decorator/
elementPrefixPath.filter.prefix = Zend_Filter_
elementPrefixPath.filter.path = Zend/Filter/
elementPrefixPath.validate.prefix = Zend_Validate_
elementPrefixPath.validate.path = Zend/Validate/

; displayGroupPrefixPath - аналогично prefixPath.* для групп элементов

; defaultDisplayGroupClass - класс для обработки групп полей.
; По-умолчанию это Zend_Form_DisplayGroup

defaultDisplayGroupClass = Zend_Form_DisplayGroup

Декораторы


; decorators.* - настройка декораторов формы.
; Упоминание тут хоть одного декоратора отменит декораторы по-умолчанию.
; ВАЖНО: Если забыть про декоратор FormElements, то элементы формы не будут отрендерены!
; Пример для декораторов по-умолчанию:

decorators.elements = FormElements
decorators.tag = HtmlTag
decorators.tag.options.tag = dl
decorators.tag.options.class = zend_form
decorators.form = Form

; displayGroupDecorators.* - декораторы для групп полей
; устанавливает декораторы для всех групп полей
; Декораторы для конкретных групп устанавливаются через displayGroups.groupName.options.decorators.*
; Если не указывать displayGroupDecorators.*, то будет использован аналог такого определения:

displayGroupDecorators.el = FormElements
displayGroupDecorators.tg = HtmlTag
displayGroupDecorators.tg.options.tag = dl
displayGroupDecorators.fs = Fieldset
displayGroupDecorators.dt = DtDdWrapper

; elementDecorators.* - дефолтные декораторы для полей формы
; Частные декораторы устанавливаются аналогично через elements.myfield.options.decorators.*
; Если не указывать elementDecorators.*, то будут использованы декораторы идентичные такому определению:

elementDecorators.vh = ViewHelper
elementDecorators.er = Errors
elementDecorators.ht = HtmlTag
elementDecorators.ht.options.tag = dd
elementDecorators.lb = Label
elementDecorators.lb.options.tag = dt

Элементы формы


; elementsBelongTo - имя массива по-умолчанию, в который будут сгруппированы значения полей.
; Полезно при использовании SubForm’s.
; Если не указывать этот параметр, то имя поля будет as is (например, <input name="myfield"/>)
; А если сделать так:

elementsBelongTo = wholeFormElements
; то имя поля будет внутри указанного массива
; (для примера выше станет так: <input name="wholeFormElements[myfield]"/>
; ВНИМАНИЕ: Изменить дефолтное значение для конкретного поля с помощью
; elements.myfield.options.belongsTo уже не удастся


; elementFilters.* - фильтры по-умолчанию для всех элементов
elementFilters.flt1.filter = StringTrim
elementFilters.flt1.options.chatList = " _-"
; этот пример будет триммить не только пробелы, но и дефисы и символы подчеркивания
; значение .filter - это название класса фильтра без Zend_Filter_


; elements.* - элементы формы
; elements.FIELDNAME.type - суффикс имени класса Zend_Form_Element_
; elements.FIELDNAME.type = Text - будет использован Zend_Form_Element_Text

elements.myfield.type = Button
elements.myfield.options.label = "Click me ;-)"

; elements.foobar.name = FIELDNAME - удобно когда у элемента много опций:
elements.a.name = myfield
elements.a.type = Text
elements.a.options.required = true
...

; elements.FIELDNAME.options.* - опции элемента: декораторы, валидаторы, фильтры, атрибуты и т.п.

Группы элементов


; displayGroups.* - группы полей. По-умолчанию объединяются тегом <fieldset/>
displayGroups.foo.name = mygroup
displayGroups.foo.options.legend = "Display Group Visible Title"
displayGroups.foo.options.order = 1
displayGroups.foo.options.description = "Cool fields" ; требуется декоратор Description
displayGroups.foo.options.decorators.* ; аналогично displayGroupDecorators.*
displayGroups.foo.elements.a = myfield1 ; поле, определенное в elements.myfield1
displayGroups.foo.elements.b = myfield2 ; аналогично

И напоследок. Хранение форм в ini-файлов удобно и их формату можно обучить верстальщиков и дизайнеров, но есть и ложка дегтя — производительность. При таком использовании форм мы получаем пенальти на чтении файла, его разборе и настройке формы.
Чтобы избежать этого, я кеширую объект Zend_Form, который был создан по ini-файлу.

PS: Если статья окажется полезной не только мне, то в следующих статьях я подробно опишу настройку элементов, фильтров, валидаторов и декораторов.
Tags:
Hubs:
Total votes 6: ↑5 and ↓1+4
Comments7

Articles