1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.view.helpers" xmlns:xi="http://www.w3.org/2001/XInclude">
5 <title>Помощники видов</title>
8 Часто бывает так, что в скриптах вида необходимо повторно выполнять
9 определенный набор функций; например, формирование даты,
10 генерация элементов формы, отображение ссылок. Вы можете использовать
11 помощников для выполнения этих действий.
15 Помощник представляет собой просто класс. Скажем, нам нужен помощник
16 'fooBar'. По умолчанию имя класса помощника начинается с
17 <code>'Zend_View_Helper_'</code> (вы можете указать другой префикс при
18 установке путей к помощникам видов), последней частью имени класа
19 является имя помощника. Все слова этой части должны писаться слитно,
20 первые буквы слов - в верхнем регистре (TitleCapped); таким образом мы
21 получаем имя класа <classname>Zend_View_Helper_FooBar</classname>. Класс должен
22 содержать как минимум один метод, названный по имени помощника в формате
23 camelCase: <code>fooBar()</code>.
27 <title>Следите за регистром</title>
29 Имена помощников всегда должны быть в стиле camelCased, т.е. они
30 никогда не начинаются с символа в верхнем регистре. Имя класса
31 имеет стиль MixedCase (т.е. начинается с символа в верхнем регистре),
32 но реально выполняемый метод должен быть в стиле camelCase.
37 <title>Используемый по умолчанию путь к помощникам</title>
40 Используемый по умолчанию путь к помощникам всегда указывает на
41 помощники Zend Framework-а, т.е. 'Zend/View/Helper/'. Даже если вы
42 вызываете <code>setHelperPath()</code> для перезаписи существующих
43 путей, этот путь всегда будет использоваться для обеспечения работы
44 помощников, входящих в поставку Zend Framework-а
50 Для того, чтобы использовать помощника в своем скрипте вида, вызывайте
51 его, используя <varname>$this->имяПомощника()</varname>.
52 В этом случае <classname>Zend_View</classname> загрузит класс
53 <code>Zend_View_Helper_ИмяПомощника</code>, создаст его экземпляр и
54 вызовет его метод <code>имяПомощника()</code>. Экземпляр объекта
55 сохраняется в экземпляре <classname>Zend_View</classname> и будет повторно
56 использоваться им во всех будущих вызовах
57 <varname>$this->имяПомощника()</varname>.
60 <sect2 id="zend.view.helpers.initial">
62 <title>Начальный набор помощников</title>
65 <classname>Zend_View</classname> поставляется с начальным набором помощников,
66 большинство из которых связано с генерацией элементов форм и
67 автоматически экранирует весь вывод. Кроме этого, есть помощники для
68 создания HTML-списков, URL-ов на основе маршрутов, и объявления
69 переменных. В настоящее время в поставляемый набор входят:
75 <code>declareVars():</code> В основном предназначен для
76 использования вместе с <code>strictVars()</code>. Этот
77 помощник может использоваться для объявления переменных
78 шаблонов, которые не обязательно присутствуют в объекте
79 вида, и для установки значений по умолчанию.
80 Массивы, переданные методу в качестве аргуметов, будут
81 использованы для установки значений по умолчанию; иначе, если
82 переменная не существует, то ее значением будет пустая строка.
86 <code>fieldset($name, $content, $attribs):</code> Создает
87 XHTML-элемент <code>fieldset</code> (набор полей). Если массив
88 <varname>$attribs</varname> содержит в ключ 'legend', то это значение
89 используется для элемента <code>legend</code>. Элемент
90 <code>fieldset</code> будет содержать в себе значение
91 параметра <varname>$content</varname>, переданного помощнику.
95 <code>form($name, $attribs, $content):</code> Генерирует
96 XHTML-элемент <code>form</code> (форма). Все элементы массива
97 <varname>$attribs</varname> и добавляются как аттрибуты тега
98 <code>form</code>. Если параметр <varname>$content</varname> передан и
99 не имеет значение false, то это содержимое добавляется между
100 открывающим и закрывающим тегами формы. Если же
101 <varname>$content</varname> имеет булево значение false (значение по
102 умолчанию), то будет сгенерирован только открывающий тег формы.
106 <code>formButton($name, $value, $attribs)</code>: Создает элемент
107 <code><button /></code>.
112 <code>formCheckbox($name, $value, $attribs, $options)</code>:
113 Создает элемент <code><input type="checkbox" /></code>
118 По умолчанию, если не был передан параметры <varname>$value</varname>
119 и <varname>$options</varname>, то значение '1' соотвествует
120 выбранному состоянию, '0' - не выбранному. Если был передан
121 параметр <varname>$value</varname>, но
122 не передан <varname>$options</varname>, то значение
123 <varname>$value</varname> соотвествует выбранному состоянию.
127 <varname>$options</varname> должен быть массивом. Если это
128 индексный массив, то первое значение соответствует
129 выбранному состоянию, второе - не выбранному состоянию,
130 все остальные значения игнорируются. Вы можете также
131 передавать массив с ключами 'checked' и 'unChecked'.
135 Если параметр $options был передан, и <varname>$value</varname>
136 соответствует значению в выбранном состоянии, то элемент
137 будет помечен как выбранный. Вы можете также помечать
138 элемент как выбранный или не выбранный путем передачи
139 значения булевого типа для атрибута 'checked'.
143 Наверное, лучше всего проиллюстрировать это примерами:
146 <programlisting language="php"><![CDATA[
147 // '1' и '0' в качестве значений для выбранного/ не выбранного состояний
149 echo $this->formCheckbox('foo');
151 // '1' и '0' в качестве значений для выбранного/ не выбранного состояний
153 echo $this->formCheckbox('foo', null, array('checked' => true));
155 // 'bar' и '0' в качестве значений для выбранного/ не выбранного состояний
157 echo $this->formCheckbox('foo', 'bar');
159 // 'bar' и '0' в качестве значений для выбранного/ не выбранного состояний
161 echo $this->formCheckbox('foo', 'bar', array('checked' => true));
163 // 'bar' и 'baz' в качестве значений для выбранного/ не выбранного состояний
165 echo $this->formCheckbox('foo', null, null, array('bar', 'baz');
167 // 'bar' и 'baz' в качестве значений для выбранного/ не выбранного состояний
169 echo $this->formCheckbox('foo', null, null, array(
174 // 'bar' и 'baz' в качестве значений для выбранного/ не выбранного состояний
176 echo $this->formCheckbox('foo', 'bar', null, array('bar', 'baz');
177 echo $this->formCheckbox('foo',
179 array('checked' => true),
182 // 'bar' и 'baz' в качестве значений для выбранного/ не выбранного состояний
184 echo $this->formCheckbox('foo', 'baz', null, array('bar', 'baz');
185 echo $this->formCheckbox('foo',
187 array('checked' => false),
192 Во всех случаях разметка предваряется скрытым элементом
193 <code><input type="hidden" /></code>
194 со значением для не выбранного состояния. Таким образом,
195 и в том случае, если флажок опций не был выбран, вы будете
196 получать корректное значение, возвращаемое вашей форме.
202 <code>formErrors($errors, $options):</code> Генерирует
203 ненумерованный список XHTML для вывода сообщений об ошибках.
204 <varname>$errors</varname> должен быть строкой или массивом строк.
205 <varname>$options</varname> должен заключать в себе все аттрибуты,
206 которые вы хотите поместить в открывающий тег списка.
210 Вы можете указать альтернативный открывающий, закрывающий и
211 разделяющий код путем вызова нескольких методов данного
217 <code>setElementStart($string)</code>; по умолчанию
219 '<ul class="errors"%s"><li>', где %s
220 заменяется аттрибутами, указанными в
221 <varname>$options</varname>.
225 <code>setElementSeparator($string)</code>; по
226 умолчанию используется '</li><li>'.
230 <code>setElementEnd($string)</code>; по умолчанию
231 используется '</li></ul>'.
237 <code>formFile($name, $attribs)</code>: Создает
238 элемент <code><input type="file" /></code>.
242 <code>formHidden($name, $value, $attribs)</code>: Создает
243 элемент <code><input type="hidden" /></code>.
247 <code>formLabel($name, $value, $attribs):</code> Создает элемент
248 <label>, устанавливая значение аттрибута <code>for</code>
249 равным значению <varname>$name</varname>, и содержимое элемента равным
250 значению <varname>$value</varname>. Если в <varname>$attribs</varname> был
251 передан <code>disable</code>, то ничего не будет возвращено.
255 <code>formMultiCheckbox($name, $value, $attribs, $options,
257 Создает список флажков опций. <varname>$options</varname> должен
258 быть ассоциативным массивом, который может быть произвольной
259 глубины. <varname>$value</varname> может быть скалярным значением или
260 массивом выбранных значений, которые соответствуют ключам в
261 массиве <varname>$options</varname>. <varname>$listsep</varname> по
262 умолчанию является переносом строки в HTML ("<br />"). По
263 умолчанию этот элемент интерпретируется как массив - все флажки
264 опций имеют одно и то же имя и передаются как массив.
268 <code>formPassword($name, $value, $attribs)</code>: Создает
269 элемент <code><input type="password" /></code>.
273 <code>formRadio($name, $value, $attribs, $options)</code>: Создает
274 последовательность элементов <code><input type="radio" /></code>
275 (переключатель опций). В массиве <varname>$options</varname> ключ
276 является значением переключателя, значение является содержимым
277 элемента <code>label</code> к переключателю. Переключатель опций
278 со значением <varname>$value</varname> будет предварительно выбранным.
282 <code>formReset($name, $value, $attribs)</code>: Создает
283 элемент <code><input type="reset" /></code>.
287 <code>formSelect($name, $value, $attribs, $options)</code>:
288 Создает блок <code><select>...</select></code>,
289 с опциями <code><option></code>, соотвествующими
290 элементам массива <varname>$options</varname>. В массиве
291 <varname>$options</varname> ключ является значением опции,
292 значение - текстом опции. Опция со значением
293 <varname>$value</varname> будет предварительно выбранной.
297 <code>formSubmit($name, $value, $attribs)</code>: Создает
298 элемент <code><input type="submit" /></code>.
302 <code>formText($name, $value, $attribs)</code>: Создает
303 элемент <code><input type="text" /></code>.
307 <code>formTextarea($name, $value, $attribs)</code>: Создает
308 блок <code><textarea>...</textarea></code>.
312 <code>url($urlOptions, $name, $reset):</code> Создает строку
313 URL, основываясь на машруте с именем <varname>$name</varname>.
314 <varname>$urlOptions</varname> должен быть ассоциативным массивом пар
315 ключ-значение для использования в данном маршруте.
319 <code>htmlList($items, $ordered, $attribs, $escape):</code>
320 Генерирует маркированный или нумерованный список на основе
321 <varname>$items</varname>. Если <varname>$items</varname> является
322 многомерным массивом, то будут построены вложенные списки. Если
323 <varname>$escape</varname> установлен в true (значение по умолчанию),
324 то все пункты будут экранированы с использованием механизма,
325 зарегистрированного в объекте вида. Передавайте значение false,
326 если хотите использовать разметку в своих списках. Если
327 <varname>$ordered</varname> установлен в false (значение по
328 умолчанию), то генерируется маркированный список, иначе -
335 Использовать их в скрипте вида очень просто, вот пример.
336 Обратите внимание, все, что вам нужно - это вызывать их,
337 помощники будут загружаться и инстанцироваться автоматически, по
341 <programlisting language="php"><![CDATA[
342 // в скрипте вида $this ссылается на экземпляр Zend_View
344 // предположим, вы уже имеете последовательность опций $countries
345 // в виде массива ('us' => 'United States', 'il' =>
346 // 'Israel', 'de' => 'Germany')
348 <form action="action.php" method="post">
349 <p><label>Your Email:
350 <?php echo $this->formText('email', 'you@example.com', array('size' => 32)) ?>
352 <p><label>Your Country:
353 <?php echo $this->formSelect('country', 'us', null, $this->countries) ?>
355 <p><label>Would you like to opt in?
356 <?php echo $this->formCheckbox('opt_in', 'yes', null, array('yes', 'no')) ?>
362 Результирующие выходные данные этого скрипта вида будут выглядеть
363 примерно следующим образом:
366 <programlisting language="php"><![CDATA[
367 <form action="action.php" method="post">
368 <p><label>Your Email:
369 <input type="text" name="email" value="you@example.com" size="32" />
371 <p><label>Your Country:
372 <select name="country">
373 <option value="us" selected="selected">United States</option>
374 <option value="il">Israel</option>
375 <option value="de">Germany</option>
378 <p><label>Would you like to opt in?
379 <input type="hidden" name="opt_in" value="no" />
380 <input type="checkbox" name="opt_in" value="yes" checked="checked" />
385 <xi:include href="Zend_View-Helpers-Action.xml">
386 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Action.xml" /></xi:fallback>
388 <xi:include href="Zend_View-Helpers-Cycle.xml">
389 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Cycle.xml" /></xi:fallback>
391 <xi:include href="Zend_View-Helpers-Partial.xml">
392 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Partial.xml" /></xi:fallback>
394 <xi:include href="Zend_View-Helpers-Placeholder.xml">
395 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Placeholder.xml" /></xi:fallback>
397 <xi:include href="Zend_View-Helpers-Doctype.xml">
398 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Doctype.xml" /></xi:fallback>
400 <xi:include href="Zend_View-Helpers-HeadLink.xml">
401 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HeadLink.xml" /></xi:fallback>
403 <xi:include href="Zend_View-Helpers-HeadMeta.xml">
404 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HeadMeta.xml" /></xi:fallback>
406 <xi:include href="Zend_View-Helpers-HeadScript.xml">
407 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HeadScript.xml" /></xi:fallback>
409 <xi:include href="Zend_View-Helpers-HeadStyle.xml">
410 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HeadStyle.xml" /></xi:fallback>
412 <xi:include href="Zend_View-Helpers-HeadTitle.xml">
413 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HeadTitle.xml" /></xi:fallback>
415 <xi:include href="Zend_View-Helpers-HtmlObject.xml">
416 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-HtmlObject.xml" /></xi:fallback>
418 <xi:include href="Zend_View-Helpers-InlineScript.xml">
419 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-InlineScript.xml" /></xi:fallback>
421 <xi:include href="Zend_View-Helpers-Json.xml">
422 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Json.xml" /></xi:fallback>
424 <xi:include href="Zend_View-Helpers-Navigation.xml">
425 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Navigation.xml" /></xi:fallback>
427 <xi:include href="Zend_View-Helpers-Translate.xml">
428 <xi:fallback><xi:include href="../../en/module_specs/Zend_View-Helpers-Translate.xml" /></xi:fallback>
432 <sect2 id="zend.view.helpers.paths">
434 <title>Пути к классам помощников</title>
437 Как и для скриптов вида, ваш контроллер может задать
438 стек путей, в которых <classname>Zend_View</classname> должен искать
439 классы помощников. По умолчанию <classname>Zend_View</classname>
440 ищет классы помощников в <code>Zend/View/Helper/*</code>. Используя
441 методы <code>setHelperPath()</code> и <code>addHelperPath()</code>,
442 вы можете укзать <classname>Zend_View</classname>, чтобы он искал классы
443 помощников в других местах. Кроме этого, вы можете указать префикс
444 класса, используемый для помощников, находящихся в данном пути;
445 префикс обеспечивает пространство имен. Если префикс не указан, то
446 по умолчанию используется 'Zend_View_Helper_'.
449 <programlisting language="php"><![CDATA[
450 $view = new Zend_View();
452 // Устанавливает путь /path/to/more/helpers с префиксом 'My_View_Helper'
453 $view->setHelperPath('/path/to/more/helpers', 'My_View_Helper');
457 Вы можете "складывать" в стек пути, используя метод
458 <code>addHelperPath()</code>. Если вы добавили
459 пути в стек, то <classname>Zend_View</classname> будет искать запрошенный
460 класс помощника в этих путях, начиная с пути, добавленного
461 последним. Это дает возможность добавлять своих
462 помощников к начальному набору (или даже замещать имеющиеся).
465 <programlisting language="php"><![CDATA[
466 $view = new Zend_View();
467 // Добавить /path/to/some/helpers с префиксом для классов 'My_View_Helper'
468 $view->addHelperPath('/path/to/some/helpers', 'My_View_Helper);
469 // Добавить /other/path/to/helpers с префиксом для классов 'Your_View_Helper'
470 $view->addHelperPath('/other/path/to/helpers', 'Your_View_Helper');
472 // теперь, когда вы вызываете $this->helperName(), Zend_View будет искать
473 // "/path/to/some/helpers/HelperName" с классом
474 // "Your_View_Helper_HelperName", затем "/other/path/to/helpers/HelperName.php"
475 // с классом "My_View_Helper_HelperName", и под конец
476 // "Zend/View/Helper/HelperName.php" с классом "Zend_View_Helper_HelperName".
481 <sect2 id="zend.view.helpers.custom">
483 <title>Написание собственных помощников</title>
486 Написать собственного помощника довольно легко, просто следуйте
493 Хотя это и не является совершенно необходимым, мы рекомендуем
494 при создании своего помощника реализовывать интерфейс
495 <classname>Zend_View_Helper_Interface</classname>
496 или наследовать от класса <classname>Zend_View_Helper_Abstract</classname>.
497 Добавленные в версии 1.6.0, они определяют только метод
498 <code>setView()</code>, но в будущих релизах
499 мы планируем реализовать паттерн "стратегия", который
500 значительно упростит следование правилам по именованию,
501 изложенным ниже. Следование этой рекомендации сейчас
502 поможет в будущем избежать изменений в вашем коде.
506 Имя класса должно, как минимум, заканчиваться именем
507 помощника в стиле MixedCaps (СмешанныйРегистр). Т.е. если вы
508 пишете помощника с именем "specialPurpose", то наиболее короткое
509 имя класса должно быть "SpecialPurpose". Вы можете
510 (и должны) давать классам имена с префиксом, рекомендуется
511 использовать 'View_Helper' как часть этого префикса:
512 "My_View_Helper_SpecialPurpose". Вам нужно будет передать этот
513 префикс с или без завершающего знака подчеркивания методу
514 <code>addHelperPath()</code> или <code>setHelperPath()</code>.
518 Класс должен иметь открытый метод, имя которого
519 соответствует имени помощника. Это метод, который будет
520 вызываться, когда в вашем шаблоне производится вызов
521 <varname>$this->specialPurpose()</varname>. В нашем примере с
522 помощником "specialPurpose" объявление требуемого метода должно
523 быть <code>public function specialPurpose()</code>.
527 Обычно класс не должен выполнять вывод, вместо этого
528 он должен возвращать значение для вывода. Возвращаемое значение
529 должно быть экранировано должным образом.
533 Класс должен быть в файле, названном по имени класса.
534 Снова используя пример с помощником "specialPurpose", мы
535 должны дать файлу имя "SpecialPurpose.php".
540 Размещайте класс помощника где-либо в одном из находящихся в
541 стеке путей к помощникам, и <classname>Zend_View</classname> будет
542 автоматически загружать, инстанцировать, сохранять и выполнять его.
546 Вот пример кода нашего помощника <code>SpecialPurpose</code>:
549 <programlisting language="php"><![CDATA[
550 class My_View_Helper_SpecialPurpose extends Zend_View_Helper_Abstract
552 protected $_count = 0;
553 public function specialPurpose()
556 $output = "I have seen 'The Jerk' {$this->_count} time(s).";
557 return htmlspecialchars($output);
563 Далее в скрипте вида вы можете вызывать помощника
564 <code>SpecialPurpose</code> сколько угодно раз. Он будет
565 инстанцирован один раз, и существует, пока существует
566 экземпляр <classname>Zend_View</classname>.
569 <programlisting language="php"><![CDATA[
570 // помните, что в скрипте вида $this ссылается на экземпляр Zend_View
571 echo $this->specialPurpose();
572 echo $this->specialPurpose();
573 echo $this->specialPurpose();
577 Результат должен быть примерно следующим:
579 <programlisting language="php"><![CDATA[
580 I have seen 'The Jerk' 1 time(s).
581 I have seen 'The Jerk' 2 time(s).
582 I have seen 'The Jerk' 3 time(s).
586 Иногда бывает, что нужен доступ к объекту <classname>Zend_View</classname> -
587 например, нужно получить зарегистрированное значение кодировки
588 или произвести рендеринг другого скрипта вида как часть
589 действий, выполняемых вашим помощником. Для того, чтобы можно было
590 получить доступ к объекту вида, ваш класс помощника должен иметь
591 метод <code>setView($view)</code>, его пример показан ниже:
594 <programlisting language="php"><![CDATA[
595 class My_View_Helper_ScriptPath
599 public function setView(Zend_View_Interface $view)
604 public function scriptPath($script)
606 return $this->view->getScriptPath($script);
612 Если ваш класс помощника имеет метод <code>setView()</code>, то он
613 будет вызываться при первом инстанцировании класса помощника и его
614 передаче текущему объекту вида. Реализация
615 сохранения объекта вида и доступа к нему в вашем классе помощника
616 остаются на ваше усмотрение.
620 Если вы наследуете своего помощника от
621 <classname>Zend_View_Helper_Abstract</classname>, то вам не нужно определять
622 этот метод, поскольку он уже определен в родительском классе.