1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.view.scripts">
5 <title>Скрипты видов</title>
8 После того, как ваш контроллер определил переменные и вызвал
9 метод <code>render()</code>, <classname>Zend_View</classname> включает
10 требуемый скрипт вида и выполняет его в области
11 видимости экземпляра <classname>Zend_View</classname>. Поэтому в вашем скрипте
12 вида ссылки на $this в действительности будут ссылаться на
13 сам экземляр <classname>Zend_View</classname>.
17 Переменные, устанавливаемые в контроллере для скрипта вида, являются
18 свойствами экземпляра <classname>Zend_View</classname>. Например, если контроллер
19 установил переменную 'something', то в скрипте вида вы можете ссылаться
20 на нее следующим образом: <varname>$this->something</varname>. Это дает
21 возможность отслеживать, какие переменные были установлены
22 извне для скрипта, и какие были установлены в самом скрипте.
26 Ниже приведен пример скрипта вида из введения:
29 <programlisting language="php"><![CDATA[
30 <?php if ($this->books): ?>
32 <!-- Таблица из нескольких книг. -->
39 <?php foreach ($this->books as $key => $val): ?>
41 <td><?php echo $this->escape($val['author']) ?></td>
42 <td><?php echo $this->escape($val['title']) ?></td>
50 <p>Нет книг для отображения.</p>
55 <sect2 id="zend.view.scripts.escaping">
57 <title>Экранирование вывода</title>
60 Одной из наиважнейших задач, которую должен решать скрипт вида,
61 является обеспечение того, что вывод должным образом
62 экранирован; помимо прочего, это помогает
63 предотвратить XSS-атаки.
64 За исключением тех случаев, когда используются функции,
65 методы или помощники, которые сами производят экранирование,
66 вы должны всегда экранировать переменные, когда выводите их.
70 <classname>Zend_View</classname> снабжен методом <code>escape()</code>,
71 который выполняет экранирование.
74 <programlisting language="php"><![CDATA[
79 echo $this->escape($this->variable);
83 По умолчанию метод <code>escape()</code> использует функцию PHP
84 <code>htmlspecialchars()</code> для экранирования. Но, в зависимости
85 от вашего окружения, может потребоваться выполнять экранирование
86 по-иному. Используйте метод <code>setEscape()</code> на уровне
87 контроллера, чтобы указать <classname>Zend_View</classname>, какую
88 экранирующую функцию обратного вызова использовать.
91 <programlisting language="php"><![CDATA[
92 // создание экземпляра Zend_View
93 $view = new Zend_View();
95 // приказываем ему использовать htmlentities
96 // в качестве экранирующей функции обратного вызова
97 $view->setEscape('htmlentities');
99 // либо приказываем ему использовать статический метод класса
100 $view->setEscape(array('SomeClass', 'methodName'));
102 // или даже метод экземпляра
103 $obj = new SomeClass();
104 $view->setEscape(array($obj, 'methodName'));
106 // и затем воспроизводим вид
107 echo $view->render(...);
111 Функции или методы обратного вызова должны принимать значение,
112 которое требуется экранировать, как первый параметр,
113 все остальные параметры должны быть необязательными.
118 <sect2 id="zend.view.scripts.templates">
120 <title>Использование других шаблонизаторов</title>
123 Хотя PHP сам по себе представляет собой мощный шаблонизатор,
124 многие разработчики считают его избыточным или сложным для
125 верстальщиков и предпочитают использовать другие
126 шаблонизаторы. <classname>Zend_View</classname> предоставляет два пути для
127 этого: первый - через скрипты вида, второй - посредством реализации
128 интерфейса <classname>Zend_View_Interface</classname>.
131 <sect3 id="zend.view.scripts.templates.scripts">
132 <title>Шаблонизаторы c использованием скриптов видов</title>
135 Скрипт вида может использоваться для инстанцирования и
136 манипулирования отдельным объектом шаблона (это могут быть
137 шаблоны в стиле PHPLIB).
140 <programlisting language="php"><![CDATA[
141 include_once 'template.inc';
142 $tpl = new Template();
146 "booklist" => "booklist.tpl",
147 "eachbook" => "eachbook.tpl",
150 foreach ($this->books as $key => $val) {
151 $tpl->set_var('author', $this->escape($val['author']);
152 $tpl->set_var('title', $this->escape($val['title']);
153 $tpl->parse("books", "eachbook", true);
156 $tpl->pparse("output", "booklist");
158 $tpl->setFile("nobooks", "nobooks.tpl")
159 $tpl->pparse("output", "nobooks");
164 Это может соответствовать следующему файлу шаблона:
167 <programlisting language="html"><![CDATA[
168 <!-- booklist.tpl -->
177 <!-- eachbook.tpl -->
184 <p>Нет книг для отображения.</p>
189 <sect3 id="zend.view.scripts.templates.interface">
190 <title>Шаблонизаторы с использованием Zend_View_Interface</title>
193 Некоторые считают более удобным использовать совместимый с
194 <classname>Zend_View</classname> шаблонизатор.
195 <classname>Zend_View_Interface</classname>
196 предоставляет минимально необходимый для
197 совместимости интерфейс:
200 <programlisting language="php"><![CDATA[
202 * Возвращает объект используемого шаблонизатора
204 public function getEngine();
207 * Устанавливает путь к шаблонам или скриптам вида
209 public function setScriptPath($path);
212 * Устанавливает базовый путь ко всем необходимым скрипту вида ресурсам
214 public function setBasePath($path, $prefix = 'Zend_View');
217 * Устанавливает дополнительный базовый путь к необходимым скрипту вида ресурсам
219 public function addBasePath($path, $prefix = 'Zend_View');
222 * Возвращает текущие пути к скриптам
224 public function getScriptPaths();
227 * Переопределение методов для присвоения значений переменным шаблонов как
230 public function __set($key, $value);
231 public function __get($key);
232 public function __isset($key);
233 public function __unset($key);
236 * "Ручная" установка значения переменной шаблона или одновременное присвоение
237 * значений нескольким переменным
239 public function assign($spec, $value = null);
242 * Удаление всех переменных шаблона
244 public function clearVars();
247 * Вывод шаблона с именем $name
249 public function render($name);
253 Используя этот интерфейс, относительно легко сделать "обертку"
254 для шаблонизаторов сторонних разработчиков. В примере показан
255 вариант "обертки" для Smarty:
258 <programlisting language="php"><![CDATA[
259 class Zend_View_Smarty implements Zend_View_Interface
270 * @param string $tmplPath
271 * @param array $extraParams
274 public function __construct($tmplPath = null, $extraParams = array())
276 $this->_smarty = new Smarty;
278 if (null !== $tmplPath) {
279 $this->setScriptPath($tmplPath);
282 foreach ($extraParams as $key => $value) {
283 $this->_smarty->$key = $value;
288 * Возвращение объекта шаблонизатора
292 public function getEngine()
294 return $this->_smarty;
298 * Установка пути к шаблонам
300 * @param string $path Директория, устанавливаемая как путь к шаблонам
303 public function setScriptPath($path)
305 if (is_readable($path)) {
306 $this->_smarty->template_dir = $path;
310 throw new Exception('Invalid path provided');
314 * Извлечение текущего пути к шаблонам
318 public function getScriptPaths()
320 return array($this->_smarty->template_dir);
324 * Метод-"псевдоним" для setScriptPath
326 * @param string $path
327 * @param string $prefix Не используется
330 public function setBasePath($path, $prefix = 'Zend_View')
332 return $this->setScriptPath($path);
336 * Метод-"псевдоним" для setScriptPath
338 * @param string $path
339 * @param string $prefix Не используется
342 public function addBasePath($path, $prefix = 'Zend_View')
344 return $this->setScriptPath($path);
348 * Присвоение значения переменной шаблона
350 * @param string $key Имя переменной
351 * @param mixed $val Значение переменной
354 public function __set($key, $val)
356 $this->_smarty->assign($key, $val);
360 * Получение значения переменной
362 * @param string $key Имя переменной
363 * @return mixed Значение переменной
365 public function __get($key)
367 return $this->_smarty->get_template_vars($key);
371 * Позволяет проверять переменные через empty() и isset()
376 public function __isset($key)
378 return (null !== $this->_smarty->get_template_vars($key));
382 * Позволяет удалять свойства объекта через unset()
387 public function __unset($key)
389 $this->_smarty->clear_assign($key);
393 * Присвоение переменных шаблону
395 * Позволяет установить значение к определенному ключу или передать массив
396 * пар ключ => значение
399 * @param string|array $spec Ключ или массив пар ключ => значение
400 * @param mixed $value (необязательный) Если присваивается значение одной
401 * переменной, то через него передается значение переменной
404 public function assign($spec, $value = null)
406 if (is_array($spec)) {
407 $this->_smarty->assign($spec);
411 $this->_smarty->assign($spec, $value);
415 * Удаление всех переменных
419 public function clearVars()
421 $this->_smarty->clear_all_assign();
425 * Обрабатывает шаблон и возвращает вывод
427 * @param string $name Шаблон для обработки
428 * @return string Вывод
430 public function render($name)
432 return $this->_smarty->fetch($name);
438 В этом примере вы можете инстанцировать класс
439 <classname>Zend_View_Smarty</classname> вместо <classname>Zend_View</classname> и
440 использовать его так же, как используется
441 <classname>Zend_View</classname>.
444 <programlisting language="php"><![CDATA[
445 //Пример 1. В initView() инициализатора
446 $view = new Zend_View_Smarty('/path/to/templates');
448 new Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
449 $viewRenderer->setView($view)
450 ->setViewBasePathSpec($view->_smarty->template_dir)
451 ->setViewScriptPathSpec(':controller/:action.:suffix')
452 ->setViewScriptPathNoControllerSpec(':action.:suffix')
453 ->setViewSuffix('tpl');
455 //Пример 2. Использование в контроллере действии остается тем же
456 class FooController extends Zend_Controller_Action
458 public function barAction()
460 $this->view->book = 'Zend PHP 5 Certification Study Guide';
461 $this->view->author = 'Davey Shafik and Ben Ramsey'
465 //Пример 3. Инициализация вида в контроллере действий
466 class FooController extends Zend_Controller_Action
468 public function init()
470 $this->view = new Zend_View_Smarty('/path/to/templates');
471 $viewRenderer = $this->_helper->getHelper('viewRenderer');
472 $viewRenderer->setView($this->view)
473 ->setViewBasePathSpec($view->_smarty->template_dir)
474 ->setViewScriptPathSpec(':controller/:action.:suffix')
475 ->setViewScriptPathNoControllerSpec(':action.:suffix')
476 ->setViewSuffix('tpl');