Zend_Controller-ActionHelpers-ViewRenderer.xml 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. <sect3 id="zend.controller.actionhelpers.viewrenderer">
  2. <title>ViewRenderer</title>
  3. <sect4 id="zend.controller.actionhelper.viewrenderer.introduction">
  4. <title>Введение</title>
  5. <para>
  6. Помощник <code>ViewRenderer</code> предназначен для решения
  7. следующих задач:
  8. </para>
  9. <itemizedlist>
  10. <listitem>
  11. <para>
  12. Устранение необходимости инстанцирования объектов вида
  13. внутри контроллеров; объекты вида будут автоматически
  14. регистрироваться вместе с контроллером.
  15. </para>
  16. </listitem>
  17. <listitem>
  18. <para>
  19. Автоматическая установка путей к скриптам вида, помощникам
  20. и фильтрам, основанная на текущем модуле, и автоматическое
  21. присоединение имени текущего модуля в качестве префикса имен
  22. классов помощников и фильтров.
  23. </para>
  24. </listitem>
  25. <listitem>
  26. <para>
  27. Создание глобально доступного объекта вида для всех
  28. запускаемых контроллеров и действий.
  29. </para>
  30. </listitem>
  31. <listitem>
  32. <para>
  33. Возможность устанавливать используемые по
  34. умолчанию опции рендеринга для всех контроллеров.
  35. </para>
  36. </listitem>
  37. <listitem>
  38. <para>
  39. Возможность автоматического рендеринга скрипта
  40. вида, не требующего от разработчика каких-либо действий.
  41. </para>
  42. </listitem>
  43. <listitem>
  44. <para>
  45. Возможность создавать собственные спецификации базового пути
  46. вида и путей к скриптам видов.
  47. </para>
  48. </listitem>
  49. </itemizedlist>
  50. <note>
  51. <para>
  52. Если вы вручную производите <code>_forward()</code>,
  53. перенаправление или <code>render</code>, то авторендеринг не
  54. будет произведен, поскольку выполнение любых этих операций
  55. говорит помощнику <code>ViewRenderer</code>, что вы определили
  56. свой собственный вывод.
  57. </para>
  58. </note>
  59. <note>
  60. <para>
  61. <code>ViewRenderer</code> включен по умолчанию. Вы можете
  62. отключить его через параметр фронт-контроллера
  63. <code>noViewRenderer</code>
  64. (<code>$front->setParam('noViewRenderer', true)</code>) или
  65. посредством удаления помощника из стека брокера помощников
  66. (<code>Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')</code>).
  67. </para>
  68. <para>
  69. Если вы хотите изменить настройки <code>ViewRenderer</code> до
  70. начала диспетчеризации, то можете сделать это одним из двух
  71. способов:
  72. </para>
  73. <itemizedlist>
  74. <listitem>
  75. <para>
  76. Инстанцировать и зарегистрировать свой объект
  77. <code>ViewRenderer</code>, а затем передать его брокеру
  78. помощников:
  79. </para>
  80. <programlisting role="php"><![CDATA[
  81. $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
  82. $viewRenderer->setView($view)
  83. ->setViewSuffix('php');
  84. Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
  85. ]]>
  86. </programlisting>
  87. </listitem>
  88. <listitem>
  89. <para>
  90. Инициализировать и/или извлечь по запросу объект
  91. <code>ViewRenderer</code> через брокер помощников:
  92. </para>
  93. <programlisting role="php"><![CDATA[
  94. $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  95. $viewRenderer->setView($view)
  96. ->setViewSuffix('php');
  97. ]]>
  98. </programlisting>
  99. </listitem>
  100. </itemizedlist>
  101. </note>
  102. </sect4>
  103. <sect4 id="zend.controller.actionhelper.viewrenderer.api">
  104. <title>API</title>
  105. <para>
  106. В простейшем варианте использования вы просто инстанцируете
  107. <code>ViewRenderer</code> и передаете его брокеру помощников.
  108. Наиболее легким способом его инстанцирования и регистрации является
  109. использование метода <code>getStaticHelper()</code> брокера
  110. помощников:
  111. </para>
  112. <programlisting role="php"><![CDATA[
  113. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  114. ]]>
  115. </programlisting>
  116. <para>
  117. Во время инстанцирования контроллера действий производится вызов
  118. <code>ViewRenderer</code> для инстанцирования объекта вида. Каждый
  119. раз, когда инстанцируется контроллер, вызывается метод
  120. <code>init()</code> помощника <code>ViewRenderer</code>, что
  121. приводит к установке свойства <code>$view</code> данного контроллера
  122. действий и вызову метода <code>addScriptPath()</code> с путем
  123. относительно текущего модуля; он будет вызван с префиксом класса,
  124. соответствующим имени текущего модуля, что эффективно
  125. разделяет пространства имен всех классов помощников и фильтров,
  126. определенных для этого модуля.
  127. </para>
  128. <para>
  129. Каждый раз, когда вызывается <code>postDispatch()</code>, он будет
  130. вызывать <code>render()</code> для текущего действия.
  131. </para>
  132. <para>
  133. В качестве примера рассмотрим следующий класс:
  134. </para>
  135. <programlisting role="php"><![CDATA[
  136. // Класс контроллера, модуль foo:
  137. class Foo_BarController extends Zend_Controller_Action
  138. {
  139. // Рендеринг bar/index.phtml по умолчанию;
  140. // не требуется производить какие-либо операции
  141. public function indexAction()
  142. {
  143. }
  144. // Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
  145. // Поскольку объект вида определен в preDispatch(), то он всегда доступен.
  146. public function populateAction()
  147. {
  148. $this->view->foo = 'bar';
  149. }
  150. }
  151. ...
  152. // в одном из ваших скриптов вида:
  153. $this->foo(); // вызывает Foo_View_Helper_Foo::foo()
  154. ]]>
  155. </programlisting>
  156. <para>
  157. <code>ViewRenderer</code> также определяет несколько аксессоров для
  158. того, чтобы можно было устанавливать и извлекать опции видов:
  159. </para>
  160. <itemizedlist>
  161. <listitem>
  162. <para>
  163. <code>setView($view)</code> позволяет установить объект вида
  164. для <code>ViewRenderer</code>. Объект сохраняется в
  165. открытом свойстве <code>$view</code> класса.
  166. </para>
  167. </listitem>
  168. <listitem>
  169. <para>
  170. <code>setNeverRender($flag = true)</code> может
  171. использоваться для отключения или включения авторендеринга
  172. глобально, т.е. для всех контроллеров. Если установлен в
  173. <code>true</code>, то <code>postDispatch()</code> не будет
  174. автоматически вызывать <code>render()</code> в текущем
  175. контроллере. <code>getNeverRender()</code> возвращает
  176. текущее значение.
  177. </para>
  178. </listitem>
  179. <listitem>
  180. <para>
  181. <code>setNoRender($flag = true)</code> может использоваться
  182. для отключения или включения авторендеринга. Если установлен
  183. в <code>true</code>, то <code>postDispatch()</code> не будет
  184. автоматически вызывать <code>render()</code> в текущем
  185. контроллере. Эта установка сбрасывается каждый раз во время
  186. вызова <code>preDispatch()</code> (т.е. нужно устанавливать
  187. этот флаг для каждого контроллера, для которого вы не хотите
  188. производить авторендеринг). <code>getNoRender()</code>
  189. возвращает текущее значение.
  190. </para>
  191. </listitem>
  192. <listitem>
  193. <para>
  194. <code>setNoController($flag = true)</code> может
  195. использоваться для того, чтобы указать
  196. методу <code>render()</code>, чтобы он не искал скрипт вида
  197. в поддиректории с именем контроллера (что является
  198. поведением по умолчанию). <code>getNoController()</code>
  199. возвращает текущее значение.
  200. </para>
  201. </listitem>
  202. <listitem>
  203. <para>
  204. <code>setNeverController($flag = true)</code> является
  205. аналогом <code>setNoController()</code>, но работает на
  206. глобальном уровне - т.е. он не будет сбрасываться с каждым
  207. обработанным действием. <code>getNeverController()</code>
  208. возвращает текущее значение.
  209. </para>
  210. </listitem>
  211. <listitem>
  212. <para>
  213. <code>setScriptAction($name)</code> может использоваться для
  214. того, чтобы указать скрипт действия для рендеринга.
  215. <code>$name</code> должен быть именем скрипта без суффикса
  216. (и без поддиректории контроллера, за исключением того
  217. случая, когда включен <code>noController</code>). Если не
  218. задан, то ищется скрипт вида с именем, аналогичным имени
  219. действия в объекте запроса. <code>getScriptAction()</code>
  220. возвращает текущее значение.
  221. </para>
  222. </listitem>
  223. <listitem>
  224. <para>
  225. <code>setResponseSegment($name)</code> может использоваться
  226. для указания того, в какой именованный сегмент объекта
  227. ответа следует сохранить результат рендеринга. Если не
  228. указан, то выходные данные сохраняются в сегменте,
  229. используемом по умолчанию. <code>getResponseSegment()</code>
  230. возвращает текущее значение.
  231. </para>
  232. </listitem>
  233. <listitem>
  234. <para>
  235. <code>initView($path, $prefix, $options)</code> может
  236. вызываться для указания базового пути вида, префикса классов
  237. помощников и фильтров, опций помощника
  238. <code>ViewRenderer</code>. Вы можете передавать любые из
  239. следующих флагов:
  240. <code>neverRender</code>, <code>noRender</code>,
  241. <code>noController</code>, <code>scriptAction</code> и
  242. <code>responseSegment</code>.
  243. </para>
  244. </listitem>
  245. <listitem>
  246. <para>
  247. <code>setRender($action = null, $name = null, $noController
  248. = false)</code> позволяет установить
  249. <code>scriptAction</code>, <code>responseSegment</code>,
  250. или <code>noController</code> за один проход.
  251. <code>direct()</code> является псевдонимом для этого метода,
  252. что дает возможность легко вызывать этот метод из вашего
  253. контроллера.
  254. </para>
  255. <programlisting role="php"><![CDATA[
  256. // Рендеринг 'foo' вместо текущего скрипта вида
  257. $this->_helper->viewRenderer('foo');
  258. // Рендеринг form.phtml в сегмент ответа 'html' в обход
  259. // поддиректории:
  260. $this->_helper->viewRenderer('form', 'html', true);
  261. ]]>
  262. </programlisting>
  263. <note><para>
  264. <code>setRender()</code> и <code>direct()</code> в
  265. действительности не производят рендеринг скрипта вида, а
  266. устанавливают закрытые свойства помощника, которые
  267. <code>postDispatch()</code> и <code>render()</code>
  268. будут использовать при рендеринге скрипта вида.
  269. </para></note>
  270. </listitem>
  271. </itemizedlist>
  272. <para>
  273. Конструктор позволяет опционально передать объект вида и опции
  274. <code>ViewRenderer</code>. Он использует те же флаги, что и
  275. <code>initView()</code>:
  276. </para>
  277. <programlisting role="php"><![CDATA[
  278. $view = new Zend_View(array('encoding' => 'UTF-8'));
  279. $options = array('noController' => true, 'neverRender' => true);
  280. $viewRenderer =
  281. new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
  282. ]]>
  283. </programlisting>
  284. <para>
  285. <code>ViewRenderer</code> имеет несколько дополнительных методов для
  286. создания пользовательских спецификаций пути, используемых для
  287. определения базового пути вида, добавляемого в объект вида, и пути к
  288. определенному скрипту вида, используемого при автоматическом
  289. определении скрипта вида для рендеринга. Все эти методы принимают
  290. одну или более меток заполнения:
  291. </para>
  292. <itemizedlist>
  293. <listitem>
  294. <para>
  295. <code>:moduleDir</code> ссылается на текущую базовую
  296. директорию модуля (по соглашению это директория,
  297. родительская по отношению к директории контроллеров модуля).
  298. </para>
  299. </listitem>
  300. <listitem>
  301. <para>
  302. <code>:module</code> ссылается на имя текущего модуля.
  303. </para>
  304. </listitem>
  305. <listitem>
  306. <para>
  307. <code>:controller</code> ссылается на имя текущего
  308. контроллера.
  309. </para>
  310. </listitem>
  311. <listitem>
  312. <para>
  313. <code>:action</code> ссылается на имя текущего действия.
  314. </para>
  315. </listitem>
  316. <listitem>
  317. <para>
  318. <code>:suffix</code> ссылается на суффикс скрипта вида
  319. (который может быть установлен через
  320. <code>setViewSuffix()</code>).
  321. </para>
  322. </listitem>
  323. </itemizedlist>
  324. <para>
  325. Методы для управления спецификациями пути:
  326. </para>
  327. <itemizedlist>
  328. <listitem>
  329. <para>
  330. <code>setViewBasePathSpec($spec)</code> позволяет изменить
  331. спецификацию пути, используемую для определения базового
  332. пути, добавляемого в объект вида. По умолчанию используется
  333. спецификация <code>:moduleDir/views</code>. Вы можете в
  334. любое время получить текущую спецификацицию, используя метод
  335. <code>getViewBasePathSpec()</code>.
  336. </para>
  337. </listitem>
  338. <listitem>
  339. <para>
  340. <code>setViewScriptPathSpec($spec)</code> позволяет изменить
  341. спецификацию пути, используемую для определения пути к
  342. отдельному скрипту вида (без базового пути скрипта вида).
  343. По умолчанию используется спецификация
  344. <code>:controller/:action.:suffix</code>. Вы можете в любое
  345. время получить текущую спецификацию, используя метод
  346. <code>getViewScriptPathSpec()</code>.
  347. </para>
  348. </listitem>
  349. <listitem>
  350. <para>
  351. <code>setViewScriptPathNoControllerSpec($spec)</code>
  352. позволяет изменить спецификацию пути, используемую для
  353. определения пути к отдельному скрипту вида, когда действует
  354. <code>noController</code> (без базового пути скрипта вида).
  355. По умолчанию используется спецификация
  356. <code>:action.:suffix</code>. Вы можете в любое время
  357. получить текущую спецификацию, используя метод
  358. <code>getViewScriptPathNoControllerSpec()</code>.
  359. </para>
  360. </listitem>
  361. </itemizedlist>
  362. <para>
  363. Для более детального управления спецификациями путей вы можете
  364. использовать
  365. <link linkend="zend.filter.inflector">Zend_Filter_Inflector</link>.
  366. Внутри себя <code>ViewRenderer</code> уже использует инфлектор для
  367. поиска соответствий. Для взаимодействия с инфлектором - установки
  368. своего собственного инфлектора или изменения используемого по
  369. умолчанию - могут использоваться следующие методы:
  370. </para>
  371. <itemizedlist>
  372. <listitem>
  373. <para>
  374. <code>getInflector()</code> возвращает инфлектор. Если в
  375. <code>ViewRenderer</code> его нет, то метод создает его,
  376. используя правила по умолчанию.
  377. </para>
  378. <para>
  379. По умолчанию он использует ссылки на статические правила для
  380. суффикса и директории модуля, так же, как и статическую
  381. цель. Это дает различным свойствам <code>ViewRenderer</code>
  382. возможность динамически изменять инфлектор.
  383. </para>
  384. </listitem>
  385. <listitem>
  386. <para>
  387. <code>setInflector($inflector, $reference)</code> позволяет
  388. устанавливать свой инфлектор для использования с
  389. <code>ViewRenderer</code>. Если <code>$reference</code>
  390. равен true, то суффикс и директория модуля будут установлены
  391. как статические ссылки на свойства
  392. <code>ViewRenderer</code>, так же, как и цель.
  393. </para></listitem>
  394. </itemizedlist>
  395. <note>
  396. <title>Используемые по умолчанию соглашения по поиску</title>
  397. <para>
  398. <code>ViewRenderer</code> производит некоторую нормализацию пути
  399. для облегчения поиска скрипта вида. Используемые по умолчанию
  400. правила:
  401. </para>
  402. <itemizedlist>
  403. <listitem>
  404. <para>
  405. <code>:module</code>: СловаРазделенныеРегистром
  406. (CamelCase) разделяются тире и вся строка приводится к
  407. нижнему регистру. Например: "FooBarBaz" преобразуется в
  408. "foo-bar-baz".
  409. </para>
  410. <para>
  411. Внутри себя инфлектор использует фильтры
  412. <code>Zend_Filter_Word_CamelCaseToDash</code> и
  413. <code>Zend_Filter_StringToLower</code>.
  414. </para>
  415. </listitem>
  416. <listitem>
  417. <para>
  418. <code>:controller</code>:
  419. СловаРазделенныеРегистром (CamelCase) разделяются
  420. тире, знаки подчеркивания преобразуются в разделители
  421. директорий и вся строка приводится к нижнему регистру.
  422. Например: "FooBar" преобразуется в "foo-bar";
  423. "FooBar_Admin" преобразуется в "foo-bar/admin".
  424. </para>
  425. <para>
  426. Внутри себя инфлектор использует фильтры
  427. <code>Zend_Filter_Word_CamelCaseToDash</code>,
  428. <code>Zend_Filter_Word_UnderscoreToSeparator</code> и
  429. <code>Zend_Filter_StringToLower</code>.
  430. </para>
  431. </listitem>
  432. <listitem>
  433. <para>
  434. <code>:action</code>:
  435. СловаРазделенныеРегистром (CamelCase) разделяются
  436. тире, символы, не являющиеся буквенно-цифровыми,
  437. переводятся в тире и
  438. вся строка приводится к нижнему регистру.
  439. Например: "fooBar" преобразуется в "foo-bar";
  440. "foo-barBaz" преобразуется в "foo-bar-baz".
  441. </para>
  442. <para>
  443. Внутри себя инфлектор использует фильтры
  444. <code>Zend_Filter_Word_CamelCaseToDash</code>,
  445. <code>Zend_Filter_PregReplace</code> и
  446. <code>Zend_Filter_StringToLower</code>.
  447. </para>
  448. </listitem>
  449. </itemizedlist>
  450. </note>
  451. <para>
  452. Последними рассматриваемыми элементами в API <code>ViewRenderer</code>-а являются
  453. методы для собственно определения путей к скриптам вида и
  454. рендеринга видов. Эти методы включают в себя:
  455. </para>
  456. <itemizedlist>
  457. <listitem>
  458. <para>
  459. <code>renderScript($script, $name)</code> позволяет
  460. производить рендеринг скрипта по указанному пути,
  461. в опционально заданный именованный сегмент. Если
  462. используется этот метод, то <code>ViewRenderer</code> не
  463. производит автоматическое определение имени скрипта, вместо
  464. этого он напрямую передает аргумент <code>$script</code>
  465. методу <code>render()</code> объекта вида.
  466. </para>
  467. <note><para>
  468. После того, как был произведен рендеринг вида в объект
  469. ответа, устанавливается <code>noRender</code> для
  470. предотвращения случайного повторного рендеринга того же
  471. скрипта вида.
  472. </para></note>
  473. <note>
  474. <para>
  475. По умолчанию
  476. <code>Zend_Controller_Action::renderScript()</code>
  477. вызывает метод <code>renderScript()</code> помощника
  478. <code>ViewRenderer</code>.
  479. </para>
  480. </note>
  481. </listitem>
  482. <listitem>
  483. <para>
  484. <code>getViewScript($action, $vars)</code> создает путь к
  485. скрипту вида, основываясь на переданном действии $action
  486. и/или переменных, переданных в $vars. Этот массив может
  487. включать в себя ключи спецификаций пути ('moduleDir',
  488. 'module', 'controller', 'action' и 'suffix'). Если
  489. была передана переменная, то она будет использована, иначе
  490. будут использоваться значения из текущего запроса.
  491. </para>
  492. <para>
  493. <code>getViewScript()</code> будет использовать
  494. <code>viewScriptPathSpec</code>, либо
  495. <code>viewScriptPathNoControllerSpec</code>, в зависимости
  496. от значения флага <code>noController</code>.
  497. </para>
  498. <para>
  499. Разделители слов в именах модуля, контроллера или действия
  500. будут заменены на тире ('-'). Таким образом, если вы имеете
  501. контроллер с именем 'foo.bar' и действие 'baz:bat', то при
  502. использовании спецификации по умолчанию результатом
  503. будет путь 'foo-bar/baz-bat.phtml' к скрипту вида.
  504. </para>
  505. <note>
  506. <para>
  507. По умолчанию
  508. <code>Zend_Controller_Action::getViewScript()</code>
  509. вызывает метод <code>getViewScript()</code>
  510. <code>ViewRenderer</code>-а.
  511. </para>
  512. </note>
  513. </listitem>
  514. <listitem>
  515. <para>
  516. <code>render($action, $name, $noController)</code> сначала
  517. проверяет, были ли переданы параметры <code>$name</code> или
  518. <code>$noController</code>, и если были переданы, то
  519. устанавливает соответствующие флаги (responseSegment и
  520. noController соответственно) в ViewRenderer. Затем он
  521. передает параметр <code>$action</code> (если есть) методу
  522. <code>getViewScript()</code>. Наконец, он передает
  523. полученный путь к скрипту вида методу
  524. <code>renderScript()</code>.
  525. </para>
  526. <note>
  527. <para>
  528. Следует помнить о побочных эффектах использования
  529. render(): значения, передаваемые для имени сегмента
  530. ответа и флага noController, сохраняются в объекте.
  531. Кроме этого, по окончании рендеринга будет установлен
  532. noRender.
  533. </para>
  534. </note>
  535. <note>
  536. <para>
  537. По умолчанию
  538. <code>Zend_Controller_Action::render()</code> вызывает
  539. метод <code>render()</code> помощника
  540. <code>ViewRenderer</code>.
  541. </para>
  542. </note>
  543. </listitem>
  544. <listitem>
  545. <para>
  546. <code>renderBySpec($action, $vars, $name)</code> позволяет
  547. передавать переменные спецификации пути для определения
  548. создаваемого пути к скрипту вида. Он передает
  549. <code>$action</code> и <code>$vars</code> методу
  550. <code>getScriptPath()</code>, затем передает полученный путь
  551. и <code>$name</code> методу <code>renderScript()</code>.
  552. </para>
  553. </listitem>
  554. </itemizedlist>
  555. </sect4>
  556. <sect4 id="zend.controller.actionhelper.viewrenderer.basicusage">
  557. <title>Примеры базового использования</title>
  558. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-1">
  559. <title>Базовое использование</title>
  560. <para>
  561. В простейшем случае вы просто инициализируете и
  562. регистрируете помощник <code>ViewRenderer</code> через брокер
  563. помощников в своем файле загрузки и затем устанавливаете
  564. переменные в своих методах действий.
  565. </para>
  566. <programlisting role="php"><![CDATA[
  567. // В вашем файле загрузки:
  568. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  569. ...
  570. // Модуль 'foo', контроллер 'bar':
  571. class Foo_BarController extends Zend_Controller_Action
  572. {
  573. // По умолчанию производится рендеринг bar/index.phtml;
  574. // дополнительные действия не требуются
  575. public function indexAction()
  576. {
  577. }
  578. // Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
  579. // Поскольку объект вида был определен в preDispatch(), то он уже
  580. // доступен для использования.
  581. public function populateAction()
  582. {
  583. $this->view->foo = 'bar';
  584. }
  585. // Ничего не рендерится, т.к. производится переход на другое действие;
  586. // это другое действие может производить рендеринг
  587. public function bazAction()
  588. {
  589. $this->_forward('index');
  590. }
  591. // Ничего не рендерится, т.к. производится перенаправление по другому адресу
  592. public function batAction()
  593. {
  594. $this->_redirect('/index');
  595. }
  596. }
  597. ]]>
  598. </programlisting>
  599. </example>
  600. <note>
  601. <title>Соглашения по именованию: Разделители слов в именах контроллера и действия</title>
  602. <para>
  603. Если имена вашего контроллера и действия состоят из
  604. нескольких слов, то диспетчер требует, чтобы в URL они были
  605. разделены определенными символами-разделителями слов и
  606. путей. <code>ViewRenderer</code> при создании путей заменяет все
  607. найденные в имени контроллера разделители путей действующим
  608. разделителем путей ('/') и все разделители слов - чертой
  609. ('-'). Таким образом, вызов действия
  610. <code>/foo.bar/baz.bat</code> должен быть преобразован в
  611. вызов метода <code>FooBarController::bazBatAction()</code> в
  612. <code>FooBarController.php</code>, который в свою очередь
  613. произведет рендеринг скрипта вида <code>foo-bar/baz-bat.phtml</code>.
  614. Вызов действия <code>/bar_baz/baz-bat</code> должен быть
  615. преобразован в вызов
  616. <code>Bar_BazController::bazBatAction()</code> в
  617. <code>Bar/BazController.php</code> (обратите внимание на
  618. разделение путей), при этом производится рендеринг
  619. <code>bar/baz/baz-bat.phtml</code>.
  620. </para>
  621. <para>
  622. Во втором примере обратите внимание на то, что по-прежнему
  623. используется модуль по умолчанию, но из-за наличия
  624. разделителя путей получается имя контроллера
  625. <code>Bar_BazController</code> в файле
  626. <code>Bar/BazController.php</code>. <code>ViewRenderer</code>
  627. имитирует иерархию директорий контроллеров.
  628. </para>
  629. </note>
  630. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-2">
  631. <title>Отключение авторендеринга</title>
  632. <para>
  633. Может потребоваться отключить авторендеринг для некоторых
  634. действий или контроллеров - например, если вы хотите производить
  635. вывод другого типа (XML, JSON и т.д.), или просто не хотите
  636. ничего выводить. Есть два варианта - либо полностью
  637. отключить авторендеринг (<code>setNeverRender()</code>), либо
  638. отключить его для текущего действия
  639. (<code>setNoRender()</code>).
  640. </para>
  641. <programlisting role="php"><![CDATA[
  642. // Класс контроллера baz, модуль bar:
  643. class Bar_BazController extends Zend_Controller_Action
  644. {
  645. public function fooAction()
  646. {
  647. // Не производить авторендеринг в этом действии
  648. $this->_helper->viewRenderer->setNoRender();
  649. }
  650. }
  651. // Класс контроллера bat, модуль bar:
  652. class Bar_BatController extends Zend_Controller_Action
  653. {
  654. public function preDispatch()
  655. {
  656. // Не производить авторендеринг во всех действиях этого контроллера
  657. $this->_helper->viewRenderer->setNoRender();
  658. }
  659. }
  660. ]]>
  661. </programlisting>
  662. </example>
  663. <note>
  664. <para>
  665. В большинстве случаев не имеет смысла глобально отключать
  666. авторендеринг (через <code>setNeverRender()</code>), поскольку
  667. единственная выгода, которую вы получаете в этом случае от
  668. использования <code>ViewRenderer</code> - автоматическая
  669. установка объекта вида.
  670. </para>
  671. </note>
  672. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-3">
  673. <title>Выбор другого скрипта вида</title>
  674. <para>
  675. В некоторых случаях требуется, чтобы производился рендеринг
  676. скрипта с именем, отличным от имени действия. Например, если у
  677. вас есть контроллер, который имеет методы действий для
  678. добавления и редактирования, они оба могут отображать один и тот
  679. же вид 'форма', хоть и с разным набором значений. Вы легко
  680. можете изменить имя скрипта, используя методы
  681. <code>setScriptAction()</code> и <code>setRender()</code>, или
  682. вызывая помощника как метод брокера - этим будет произведен
  683. вызов метода <code>setRender()</code>.
  684. </para>
  685. <programlisting role="php"><![CDATA[
  686. // Класс контроллера bar, модуль foo:
  687. class Foo_BarController extends Zend_Controller_Action
  688. {
  689. public function addAction()
  690. {
  691. // Рендерить 'bar/form.phtml' вместо 'bar/add.phtml'
  692. $this->_helper->viewRenderer('form');
  693. }
  694. public function editAction()
  695. {
  696. // Рендерить 'bar/form.phtml' вместо 'bar/edit.phtml'
  697. $this->_helper->viewRenderer->setScriptAction('form');
  698. }
  699. public function processAction()
  700. {
  701. // произведение валидации...
  702. if (!$valid) {
  703. // Рендерить 'bar/form.phtml' вместо 'bar/process.phtml'
  704. $this->_helper->viewRenderer->setRender('form');
  705. return;
  706. }
  707. // иначе продолжение обработки...
  708. }
  709. }
  710. ]]>
  711. </programlisting>
  712. </example>
  713. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-4">
  714. <title>Изменение зарегистрированного объекта вида</title>
  715. <para>
  716. А что, если нужно модифицировать объект вида - например,
  717. изменить пути к помощникам или кодировку? Вы можете делать это
  718. как через модификацию объекта вида, установленного в вашем
  719. контроллере, так и через извлечение объекта вида из
  720. <code>ViewRenderer</code>, оба они являются ссылками на один и
  721. тот же объект.
  722. </para>
  723. <programlisting role="php"><![CDATA[
  724. // Класс контроллера bar, модуль foo:
  725. class Foo_BarController extends Zend_Controller_Action
  726. {
  727. public function preDispatch()
  728. {
  729. // Изменение кодировки вида
  730. $this->view->setEncoding('UTF-8');
  731. }
  732. public function bazAction()
  733. {
  734. // Получение объекта вида и указание 'htmlspecialchars'
  735. // в качестве функции для экранирования
  736. $view = $this->_helper->viewRenderer->view;
  737. $view->setEscape('htmlspecialchars');
  738. }
  739. }
  740. ]]>
  741. </programlisting>
  742. </example>
  743. </sect4>
  744. <sect4 id="zend.controller.actionhelper.viewrenderer.advancedusage">
  745. <title>Примеры продвинутого использования</title>
  746. <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-1">
  747. <title>Изменение спецификаций пути</title>
  748. <para>
  749. В некоторых случаях вы можете решить, что спецификации пути,
  750. используемые по умолчанию, не соответствуют требованиям вашего
  751. сайта. Например, вы можете захотеть иметь одно дерево шаблонов,
  752. к которому можно давать доступ дизайнерам (что, например,
  753. довольно типично в случае использованя
  754. <ulink url="http://smarty.php.net/">Smarty</ulink>).
  755. В таком случае вы можете захотеть задать жесткую
  756. спецификацию базового пути вида и создать альтернативную
  757. спецификацию для собственно путей к скриптам вида.
  758. </para>
  759. <para>
  760. В рамках данного примера предположим, что базовый путь к
  761. скриптам вида - '/opt/vendor/templates', и вы хотите, чтобы
  762. обращение к скриптам вида производилось по схеме
  763. ':moduleDir/:controller/:action.:suffix'. Также предположим, что
  764. если флаг noController установлен, то нужно, чтобы использовался
  765. верхний уровень вместо поддиректории (':action.:suffix'). И
  766. наконец, вы хотите использовать 'tpl' в качестве суффикса имени
  767. скрипта вида.
  768. </para>
  769. <programlisting role="php"><![CDATA[
  770. /**
  771. * В вашем файле загрузки:
  772. */
  773. // Другая реализация вида
  774. $view = new ZF_Smarty();
  775. $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
  776. $viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
  777. ->setViewScriptPathSpec(':module/:controller/:action.:suffix')
  778. ->setViewScriptPathNoControllerSpec(':action.:suffix')
  779. ->setViewSuffix('tpl');
  780. Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
  781. ]]>
  782. </programlisting>
  783. </example>
  784. <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-2">
  785. <title>Рендеринг нескольких скриптов вида из одного действия</title>
  786. <para>
  787. Иногда бывает нужно произвести рендеринг нескольких скриптов
  788. вида из одного действия. Решение довольно очевидное - просто
  789. сделайте несколько вызовов метода <code>render()</code>:
  790. </para>
  791. <programlisting role="php"><![CDATA[
  792. class SearchController extends Zend_Controller_Action
  793. {
  794. public function resultsAction()
  795. {
  796. // Предполагается, что $this->model - текущая модель
  797. $this->view->results =
  798. $this->model->find($this->_getParam('query', '');
  799. // render() по умолчанию использует ViewRenderer
  800. // Рендеринг формы поиска и затем результатов поиска
  801. $this->render('form');
  802. $this->render('results');
  803. }
  804. public function formAction()
  805. {
  806. // Ничего не делается. ViewRenderer автоматически производит
  807. // рендеринг скрипта вида
  808. }
  809. }
  810. ]]>
  811. </programlisting>
  812. </example>
  813. </sect4>
  814. </sect3>
  815. <!--
  816. vim:se ts=4 sw=4 et:
  817. -->