| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.view.scripts">
- <title>Скрипты видов</title>
- <para>
- После того, как ваш контроллер определил переменные и вызвал
- метод <code>render()</code>, <classname>Zend_View</classname> включает
- требуемый скрипт вида и выполняет его в области
- видимости экземпляра <classname>Zend_View</classname>. Поэтому в вашем скрипте
- вида ссылки на $this в действительности будут ссылаться на
- сам экземляр <classname>Zend_View</classname>.
- </para>
- <para>
- Переменные, устанавливаемые в контроллере для скрипта вида, являются
- свойствами экземпляра <classname>Zend_View</classname>. Например, если контроллер
- установил переменную 'something', то в скрипте вида вы можете ссылаться
- на нее следующим образом: <varname>$this->something</varname>. Это дает
- возможность отслеживать, какие переменные были установлены
- извне для скрипта, и какие были установлены в самом скрипте.
- </para>
- <para>
- Ниже приведен пример скрипта вида из введения:
- </para>
- <programlisting language="php"><![CDATA[
- <?php if ($this->books): ?>
- <!-- Таблица из нескольких книг. -->
- <table>
- <tr>
- <th>Author</th>
- <th>Title</th>
- </tr>
- <?php foreach ($this->books as $key => $val): ?>
- <tr>
- <td><?php echo $this->escape($val['author']) ?></td>
- <td><?php echo $this->escape($val['title']) ?></td>
- </tr>
- <?php endforeach; ?>
- </table>
- <?php else: ?>
- <p>Нет книг для отображения.</p>
- <?php endif;?>
- ]]></programlisting>
- <sect2 id="zend.view.scripts.escaping">
- <title>Экранирование вывода</title>
- <para>
- Одной из наиважнейших задач, которую должен решать скрипт вида,
- является обеспечение того, что вывод должным образом
- экранирован; помимо прочего, это помогает
- предотвратить XSS-атаки.
- За исключением тех случаев, когда используются функции,
- методы или помощники, которые сами производят экранирование,
- вы должны всегда экранировать переменные, когда выводите их.
- </para>
- <para>
- <classname>Zend_View</classname> снабжен методом <code>escape()</code>,
- который выполняет экранирование.
- </para>
- <programlisting language="php"><![CDATA[
- // плохая практика
- echo $this->variable;
- // хорошая практика
- echo $this->escape($this->variable);
- ]]></programlisting>
- <para>
- По умолчанию метод <code>escape()</code> использует функцию PHP
- <code>htmlspecialchars()</code> для экранирования. Но, в зависимости
- от вашего окружения, может потребоваться выполнять экранирование
- по-иному. Используйте метод <code>setEscape()</code> на уровне
- контроллера, чтобы указать <classname>Zend_View</classname>, какую
- экранирующую функцию обратного вызова использовать.
- </para>
- <programlisting language="php"><![CDATA[
- // создание экземпляра Zend_View
- $view = new Zend_View();
- // приказываем ему использовать htmlentities
- // в качестве экранирующей функции обратного вызова
- $view->setEscape('htmlentities');
- // либо приказываем ему использовать статический метод класса
- $view->setEscape(array('SomeClass', 'methodName'));
- // или даже метод экземпляра
- $obj = new SomeClass();
- $view->setEscape(array($obj, 'methodName'));
- // и затем воспроизводим вид
- echo $view->render(...);
- ]]></programlisting>
- <para>
- Функции или методы обратного вызова должны принимать значение,
- которое требуется экранировать, как первый параметр,
- все остальные параметры должны быть необязательными.
- </para>
- </sect2>
- <sect2 id="zend.view.scripts.templates">
- <title>Использование других шаблонизаторов</title>
- <para>
- Хотя PHP сам по себе представляет собой мощный шаблонизатор,
- многие разработчики считают его избыточным или сложным для
- верстальщиков и предпочитают использовать другие
- шаблонизаторы. <classname>Zend_View</classname> предоставляет два пути для
- этого: первый - через скрипты вида, второй - посредством реализации
- интерфейса <classname>Zend_View_Interface</classname>.
- </para>
- <sect3 id="zend.view.scripts.templates.scripts">
- <title>Шаблонизаторы c использованием скриптов видов</title>
- <para>
- Скрипт вида может использоваться для инстанцирования и
- манипулирования отдельным объектом шаблона (это могут быть
- шаблоны в стиле PHPLIB).
- </para>
- <programlisting language="php"><![CDATA[
- include_once 'template.inc';
- $tpl = new Template();
- if ($this->books) {
- $tpl->setFile(array(
- "booklist" => "booklist.tpl",
- "eachbook" => "eachbook.tpl",
- ));
- foreach ($this->books as $key => $val) {
- $tpl->set_var('author', $this->escape($val['author']);
- $tpl->set_var('title', $this->escape($val['title']);
- $tpl->parse("books", "eachbook", true);
- }
- $tpl->pparse("output", "booklist");
- } else {
- $tpl->setFile("nobooks", "nobooks.tpl")
- $tpl->pparse("output", "nobooks");
- }
- ]]></programlisting>
- <para>
- Это может соответствовать следующему файлу шаблона:
- </para>
- <programlisting language="html"><![CDATA[
- <!-- booklist.tpl -->
- <table>
- <tr>
- <th>Author</th>
- <th>Title</th>
- </tr>
- {books}
- </table>
- <!-- eachbook.tpl -->
- <tr>
- <td>{author}</td>
- <td>{title}</td>
- </tr>
- <!-- nobooks.tpl -->
- <p>Нет книг для отображения.</p>
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.view.scripts.templates.interface">
- <title>Шаблонизаторы с использованием Zend_View_Interface</title>
- <para>
- Некоторые считают более удобным использовать совместимый с
- <classname>Zend_View</classname> шаблонизатор.
- <classname>Zend_View_Interface</classname>
- предоставляет минимально необходимый для
- совместимости интерфейс:
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * Возвращает объект используемого шаблонизатора
- */
- public function getEngine();
- /**
- * Устанавливает путь к шаблонам или скриптам вида
- */
- public function setScriptPath($path);
- /**
- * Устанавливает базовый путь ко всем необходимым скрипту вида ресурсам
- */
- public function setBasePath($path, $prefix = 'Zend_View');
- /**
- * Устанавливает дополнительный базовый путь к необходимым скрипту вида ресурсам
- */
- public function addBasePath($path, $prefix = 'Zend_View');
- /**
- * Возвращает текущие пути к скриптам
- */
- public function getScriptPaths();
- /**
- * Переопределение методов для присвоения значений переменным шаблонов как
- * свойствам объекта
- */
- public function __set($key, $value);
- public function __get($key);
- public function __isset($key);
- public function __unset($key);
- /**
- * "Ручная" установка значения переменной шаблона или одновременное присвоение
- * значений нескольким переменным
- */
- public function assign($spec, $value = null);
- /**
- * Удаление всех переменных шаблона
- */
- public function clearVars();
- /**
- * Вывод шаблона с именем $name
- */
- public function render($name);
- ]]></programlisting>
- <para>
- Используя этот интерфейс, относительно легко сделать "обертку"
- для шаблонизаторов сторонних разработчиков. В примере показан
- вариант "обертки" для Smarty:
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_View_Smarty implements Zend_View_Interface
- {
- /**
- * Объект Smarty
- * @var Smarty
- */
- protected $_smarty;
- /**
- * Конструктор
- *
- * @param string $tmplPath
- * @param array $extraParams
- * @return void
- */
- public function __construct($tmplPath = null, $extraParams = array())
- {
- $this->_smarty = new Smarty;
- if (null !== $tmplPath) {
- $this->setScriptPath($tmplPath);
- }
- foreach ($extraParams as $key => $value) {
- $this->_smarty->$key = $value;
- }
- }
- /**
- * Возвращение объекта шаблонизатора
- *
- * @return Smarty
- */
- public function getEngine()
- {
- return $this->_smarty;
- }
- /**
- * Установка пути к шаблонам
- *
- * @param string $path Директория, устанавливаемая как путь к шаблонам
- * @return void
- */
- public function setScriptPath($path)
- {
- if (is_readable($path)) {
- $this->_smarty->template_dir = $path;
- return;
- }
- throw new Exception('Invalid path provided');
- }
- /**
- * Извлечение текущего пути к шаблонам
- *
- * @return string
- */
- public function getScriptPaths()
- {
- return array($this->_smarty->template_dir);
- }
- /**
- * Метод-"псевдоним" для setScriptPath
- *
- * @param string $path
- * @param string $prefix Не используется
- * @return void
- */
- public function setBasePath($path, $prefix = 'Zend_View')
- {
- return $this->setScriptPath($path);
- }
- /**
- * Метод-"псевдоним" для setScriptPath
- *
- * @param string $path
- * @param string $prefix Не используется
- * @return void
- */
- public function addBasePath($path, $prefix = 'Zend_View')
- {
- return $this->setScriptPath($path);
- }
- /**
- * Присвоение значения переменной шаблона
- *
- * @param string $key Имя переменной
- * @param mixed $val Значение переменной
- * @return void
- */
- public function __set($key, $val)
- {
- $this->_smarty->assign($key, $val);
- }
- /**
- * Получение значения переменной
- *
- * @param string $key Имя переменной
- * @return mixed Значение переменной
- */
- public function __get($key)
- {
- return $this->_smarty->get_template_vars($key);
- }
- /**
- * Позволяет проверять переменные через empty() и isset()
- *
- * @param string $key
- * @return boolean
- */
- public function __isset($key)
- {
- return (null !== $this->_smarty->get_template_vars($key));
- }
- /**
- * Позволяет удалять свойства объекта через unset()
- *
- * @param string $key
- * @return void
- */
- public function __unset($key)
- {
- $this->_smarty->clear_assign($key);
- }
- /**
- * Присвоение переменных шаблону
- *
- * Позволяет установить значение к определенному ключу или передать массив
- * пар ключ => значение
- *
- * @see __set()
- * @param string|array $spec Ключ или массив пар ключ => значение
- * @param mixed $value (необязательный) Если присваивается значение одной
- * переменной, то через него передается значение переменной
- * @return void
- */
- public function assign($spec, $value = null)
- {
- if (is_array($spec)) {
- $this->_smarty->assign($spec);
- return;
- }
- $this->_smarty->assign($spec, $value);
- }
- /**
- * Удаление всех переменных
- *
- * @return void
- */
- public function clearVars()
- {
- $this->_smarty->clear_all_assign();
- }
- /**
- * Обрабатывает шаблон и возвращает вывод
- *
- * @param string $name Шаблон для обработки
- * @return string Вывод
- */
- public function render($name)
- {
- return $this->_smarty->fetch($name);
- }
- }
- ]]></programlisting>
- <para>
- В этом примере вы можете инстанцировать класс
- <classname>Zend_View_Smarty</classname> вместо <classname>Zend_View</classname> и
- использовать его так же, как используется
- <classname>Zend_View</classname>.
- </para>
- <programlisting language="php"><![CDATA[
- //Пример 1. В initView() инициализатора
- $view = new Zend_View_Smarty('/path/to/templates');
- $viewRenderer =
- new Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
- $viewRenderer->setView($view)
- ->setViewBasePathSpec($view->_smarty->template_dir)
- ->setViewScriptPathSpec(':controller/:action.:suffix')
- ->setViewScriptPathNoControllerSpec(':action.:suffix')
- ->setViewSuffix('tpl');
- //Пример 2. Использование в контроллере действии остается тем же
- class FooController extends Zend_Controller_Action
- {
- public function barAction()
- {
- $this->view->book = 'Zend PHP 5 Certification Study Guide';
- $this->view->author = 'Davey Shafik and Ben Ramsey'
- }
- }
- //Пример 3. Инициализация вида в контроллере действий
- class FooController extends Zend_Controller_Action
- {
- public function init()
- {
- $this->view = new Zend_View_Smarty('/path/to/templates');
- $viewRenderer = $this->_helper->getHelper('viewRenderer');
- $viewRenderer->setView($this->view)
- ->setViewBasePathSpec($view->_smarty->template_dir)
- ->setViewScriptPathSpec(':controller/:action.:suffix')
- ->setViewScriptPathNoControllerSpec(':action.:suffix')
- ->setViewSuffix('tpl');
- }
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|