Zend_Controller-ActionHelpers-ViewRenderer.xml 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect3 id="zend.controller.actionhelpers.viewrenderer">
  4. <title>ViewRenderer</title>
  5. <sect4 id="zend.controller.actionhelper.viewrenderer.introduction">
  6. <title>Introduction</title>
  7. <para>
  8. The <emphasis>ViewRenderer</emphasis> helper is designed to satisfy the
  9. following goals:
  10. </para>
  11. <itemizedlist>
  12. <listitem>
  13. <para>
  14. Eliminate the need to instantiate view objects within
  15. controllers; view objects will be automatically registered
  16. with the controller.
  17. </para>
  18. </listitem>
  19. <listitem>
  20. <para>
  21. Automatically set view script, helper, and filter paths
  22. based on the current module, and automatically associate
  23. the current module name as a class prefix for helper and
  24. filter classes.
  25. </para>
  26. </listitem>
  27. <listitem>
  28. <para>
  29. Create a globally available view object for all dispatched
  30. controllers and actions.
  31. </para>
  32. </listitem>
  33. <listitem>
  34. <para>
  35. Allow the developer to set default view rendering options
  36. for all controllers.
  37. </para>
  38. </listitem>
  39. <listitem>
  40. <para>
  41. Add the ability to automatically render a view script with
  42. no intervention.
  43. </para>
  44. </listitem>
  45. <listitem>
  46. <para>
  47. Allow the developer to create her own specifications for
  48. the view base path and for view script paths.
  49. </para>
  50. </listitem>
  51. </itemizedlist>
  52. <note>
  53. <para>
  54. If you perform a <methodname>_forward()</methodname>,
  55. <methodname>redirect()</methodname>, or
  56. <methodname>render()</methodname> manually, autorendering will not occur, as
  57. by performing any of these actions you are telling the
  58. <emphasis>ViewRenderer</emphasis> that you are determining your own
  59. output.
  60. </para>
  61. </note>
  62. <note>
  63. <para>
  64. The <emphasis>ViewRenderer</emphasis> is enabled by default. You may
  65. disable it via the front controller <emphasis>noViewRenderer</emphasis>
  66. param (<command>$front->setParam('noViewRenderer', true);</command>) or
  67. removing the helper from the helper broker stack
  68. (<methodname>Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')</methodname>).
  69. </para>
  70. <para>
  71. If you wish to modify settings of the <emphasis>ViewRenderer</emphasis>
  72. prior to dispatching the front controller, you may do so in one
  73. of two ways:
  74. </para>
  75. <itemizedlist>
  76. <listitem>
  77. <para>
  78. Instantiate and register your own
  79. <emphasis>ViewRenderer</emphasis> object and pass it to the
  80. helper broker:
  81. </para>
  82. <programlisting language="php"><![CDATA[
  83. $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
  84. $viewRenderer->setView($view)
  85. ->setViewSuffix('php');
  86. Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
  87. ]]></programlisting>
  88. </listitem>
  89. <listitem>
  90. <para>
  91. Initialize and/or retrieve a <emphasis>ViewRenderer</emphasis>
  92. object on demand via the helper broker:
  93. </para>
  94. <programlisting language="php"><![CDATA[
  95. $viewRenderer =
  96. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  97. $viewRenderer->setView($view)
  98. ->setViewSuffix('php');
  99. ]]></programlisting>
  100. </listitem>
  101. </itemizedlist>
  102. </note>
  103. </sect4>
  104. <sect4 id="zend.controller.actionhelper.viewrenderer.api">
  105. <title>API</title>
  106. <para>
  107. At its most basic usage, you simply instantiate the
  108. <emphasis>ViewRenderer</emphasis> and pass it to the action helper broker.
  109. The easiest way to instantiate it and register in one go is to use
  110. the helper broker's <methodname>getStaticHelper()</methodname> method:
  111. </para>
  112. <programlisting language="php"><![CDATA[
  113. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  114. ]]></programlisting>
  115. <para>
  116. The first time an action controller is instantiated, it will trigger
  117. the <emphasis>ViewRenderer</emphasis> to instantiate a view object. Each
  118. time a controller is instantiated, the <emphasis>ViewRenderer</emphasis>'s
  119. <methodname>init()</methodname> method is called, which will cause it to set the
  120. view property of the action controller, and call
  121. <methodname>addScriptPath()</methodname> with a path relative to the current
  122. module; this will be called with a class prefix named after the
  123. current module, effectively namespacing all helper and filter
  124. classes you define for the module.
  125. </para>
  126. <para>
  127. Each time <methodname>postDispatch()</methodname> is called, it will call
  128. <methodname>render()</methodname> for the current action.
  129. </para>
  130. <para>
  131. As an example, consider the following class:
  132. </para>
  133. <programlisting language="php"><![CDATA[
  134. // A controller class, foo module:
  135. class Foo_BarController extends Zend_Controller_Action
  136. {
  137. // Render bar/index.phtml by default; no action required
  138. public function indexAction()
  139. {
  140. }
  141. // Render bar/populate.phtml with variable 'foo' set to 'bar'.
  142. // Since view object defined at preDispatch(), it's already available.
  143. public function populateAction()
  144. {
  145. $this->view->foo = 'bar';
  146. }
  147. }
  148. ...
  149. // in one of your view scripts:
  150. $this->foo(); // call Foo_View_Helper_Foo::foo()
  151. ]]></programlisting>
  152. <para>
  153. The <emphasis>ViewRenderer</emphasis> also defines a number of accessors to
  154. allow setting and retrieving view options:
  155. </para>
  156. <itemizedlist>
  157. <listitem>
  158. <para>
  159. <methodname>setView($view)</methodname> allows you to set the view
  160. object for the <emphasis>ViewRenderer</emphasis>. It gets set as
  161. the public class property <varname>$view</varname>.
  162. </para>
  163. </listitem>
  164. <listitem>
  165. <para>
  166. <methodname>setNeverRender($flag = true)</methodname> can be used to
  167. disable or enable autorendering globally, i.e., for all
  168. controllers. If set to <constant>TRUE</constant>,
  169. <methodname>postDispatch()</methodname>
  170. will not automatically call <methodname>render()</methodname> in the
  171. current controller. <methodname>getNeverRender()</methodname> retrieves
  172. the current value.
  173. </para>
  174. </listitem>
  175. <listitem>
  176. <para>
  177. <methodname>setNoRender($flag = true)</methodname> can be used to
  178. disable or enable autorendering. If set to <constant>TRUE</constant>,
  179. <methodname>postDispatch()</methodname> will not automatically call
  180. <methodname>render()</methodname> in the current controller. This
  181. setting is reset each time <methodname>preDispatch()</methodname> is
  182. called (i.e., you need to set this flag for each controller
  183. for which you don't want autorenderering to occur).
  184. <methodname>getNoRender()</methodname> retrieves the current value.
  185. </para>
  186. </listitem>
  187. <listitem>
  188. <para>
  189. <methodname>setNoController($flag = true)</methodname> can be used to
  190. tell <methodname>render()</methodname> not to look for the action script
  191. in a subdirectory named after the controller (which is the
  192. default behaviour). <methodname>getNoController()</methodname> retrieves
  193. the current value.
  194. </para>
  195. </listitem>
  196. <listitem>
  197. <para>
  198. <methodname>setNeverController($flag = true)</methodname> is analogous
  199. to <methodname>setNoController()</methodname>, but works on a global
  200. level -- i.e., it will not be reset for each dispatched
  201. action. <methodname>getNeverController()</methodname> retrieves
  202. the current value.
  203. </para>
  204. </listitem>
  205. <listitem>
  206. <para>
  207. <methodname>setScriptAction($name)</methodname> can be used to
  208. specify the action script to render. <varname>$name</varname>
  209. should be the name of the script minus the file suffix (and
  210. without the controller subdirectory, unless
  211. <emphasis>noController</emphasis> has been turned on). If not
  212. specified, it looks for a view script named after the action
  213. in the request object. <methodname>getScriptAction()</methodname>
  214. retrieves the current value.
  215. </para>
  216. </listitem>
  217. <listitem>
  218. <para>
  219. <methodname>setResponseSegment($name)</methodname> can be used to
  220. specify which response object named segment to render into.
  221. If not specified, it renders into the default segment.
  222. <methodname>getResponseSegment()</methodname> retrieves the current
  223. value.
  224. </para>
  225. </listitem>
  226. <listitem>
  227. <para>
  228. <methodname>initView($path, $prefix, $options)</methodname> may be called
  229. to specify the base view path, class prefix for helper and
  230. filter scripts, and <emphasis>ViewRenderer</emphasis> options. You
  231. may pass any of the following flags:
  232. <emphasis>neverRender</emphasis>, <emphasis>noRender</emphasis>,
  233. <emphasis>noController</emphasis>, <emphasis>scriptAction</emphasis>, and
  234. <emphasis>responseSegment</emphasis>.
  235. </para>
  236. </listitem>
  237. <listitem>
  238. <para>
  239. <methodname>setRender($action = null, $name = null, $noController
  240. = false)</methodname> allows you to set any of
  241. <emphasis>scriptAction</emphasis>, <emphasis>responseSegment</emphasis>, and
  242. <emphasis>noController</emphasis> in one pass. <methodname>direct()</methodname>
  243. is an alias to this method, allowing you to call this method
  244. easily from your controller:
  245. </para>
  246. <programlisting language="php"><![CDATA[
  247. // Render 'foo' instead of current action script
  248. $this->_helper->viewRenderer('foo');
  249. // render form.phtml to the 'html' response segment, without using a
  250. // controller view script subdirectory:
  251. $this->_helper->viewRenderer('form', 'html', true);
  252. ]]></programlisting>
  253. <note>
  254. <para>
  255. <methodname>setRender()</methodname> and <methodname>direct()</methodname>
  256. don't actually render the view script, but instead set hints
  257. that <methodname>postDispatch()</methodname> and
  258. <methodname>render()</methodname> will use to render the view.
  259. </para>
  260. </note>
  261. </listitem>
  262. </itemizedlist>
  263. <para>
  264. The constructor allows you to optionally pass the view object and
  265. <emphasis>ViewRenderer</emphasis> options; it accepts the same flags as
  266. <methodname>initView()</methodname>:
  267. </para>
  268. <programlisting language="php"><![CDATA[
  269. $view = new Zend_View(array('encoding' => 'UTF-8'));
  270. $options = array('noController' => true, 'neverRender' => true);
  271. $viewRenderer =
  272. new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
  273. ]]></programlisting>
  274. <para>
  275. There are several additional methods for customizing path
  276. specifications used for determining the view base path to add to the
  277. view object, and the view script path to use when autodetermining
  278. the view script to render. These methods each take one or more of
  279. the following placeholders:
  280. </para>
  281. <itemizedlist>
  282. <listitem>
  283. <para>
  284. <emphasis>:moduleDir</emphasis> refers to the current module's base
  285. directory (by convention, the parent directory of the
  286. module's controller directory).
  287. </para>
  288. </listitem>
  289. <listitem>
  290. <para>
  291. <emphasis>:module</emphasis> refers to the current module name.
  292. </para>
  293. </listitem>
  294. <listitem>
  295. <para>
  296. <emphasis>:controller</emphasis> refers to the current controller name.
  297. </para>
  298. </listitem>
  299. <listitem>
  300. <para>
  301. <emphasis>:action</emphasis> refers to the current action name.
  302. </para>
  303. </listitem>
  304. <listitem>
  305. <para>
  306. <emphasis>:suffix</emphasis> refers to the view script suffix (which
  307. may be set via <methodname>setViewSuffix()</methodname>).
  308. </para>
  309. </listitem>
  310. </itemizedlist>
  311. <para>
  312. The methods for controlling path specifications are:
  313. </para>
  314. <itemizedlist>
  315. <listitem>
  316. <para>
  317. <methodname>setViewBasePathSpec($spec)</methodname> allows you to change
  318. the path specification used to determine the base path to
  319. add to the view object. The default specification is
  320. <filename>:moduleDir/views</filename>. You may retrieve the current
  321. specification at any time using
  322. <methodname>getViewBasePathSpec()</methodname>.
  323. </para>
  324. </listitem>
  325. <listitem>
  326. <para>
  327. <methodname>setViewScriptPathSpec($spec)</methodname> allows you to
  328. change the path specification used to determine the path to
  329. an individual view script (minus the base view script path).
  330. The default specification is
  331. <filename>:controller/:action.:suffix</filename>. You may retrieve
  332. the current specification at any time using
  333. <methodname>getViewScriptPathSpec()</methodname>.
  334. </para>
  335. </listitem>
  336. <listitem>
  337. <para>
  338. <methodname>setViewScriptPathNoControllerSpec($spec)</methodname> allows
  339. you to change the path specification used to determine the
  340. path to an individual view script when
  341. <emphasis>noController</emphasis> is in effect (minus the base view
  342. script path). The default specification is
  343. <filename>:action.:suffix</filename>. You may retrieve the current
  344. specification at any time using
  345. <methodname>getViewScriptPathNoControllerSpec()</methodname>.
  346. </para>
  347. </listitem>
  348. </itemizedlist>
  349. <para>
  350. For fine-grained control over path specifications, you may use
  351. <link linkend="zend.filter.inflector">Zend_Filter_Inflector</link>.
  352. Under the hood, the <emphasis>ViewRenderer</emphasis> uses an inflector to
  353. perform path mappings already. To interact with the inflector --
  354. either to set your own for use, or to modify the default inflector,
  355. the following methods may be used:
  356. </para>
  357. <itemizedlist>
  358. <listitem>
  359. <para>
  360. <methodname>getInflector()</methodname> will retrieve the inflector. If
  361. none exists yet in the <emphasis>ViewRenderer</emphasis>, it creates
  362. one using the default rules.
  363. </para>
  364. <para>
  365. By default, it uses static rule references for the suffix
  366. and module directory, as well as a static target; this
  367. allows various <emphasis>ViewRenderer</emphasis> properties the
  368. ability to dynamically modify the inflector.
  369. </para>
  370. </listitem>
  371. <listitem>
  372. <para>
  373. <methodname>setInflector($inflector, $reference)</methodname> allows you
  374. to set a custom inflector for use with the
  375. <emphasis>ViewRenderer</emphasis>. If <varname>$reference</varname> is
  376. <constant>TRUE</constant>, it will set the suffix and module directory as static
  377. references to <emphasis>ViewRenderer</emphasis> properties, as well
  378. as the target.
  379. </para>
  380. </listitem>
  381. </itemizedlist>
  382. <note>
  383. <title>Default Lookup Conventions</title>
  384. <para>
  385. The <emphasis>ViewRenderer</emphasis> does some path normalization to
  386. make view script lookups easier. The default rules are as
  387. follows:
  388. </para>
  389. <itemizedlist>
  390. <listitem>
  391. <para>
  392. <emphasis>:module</emphasis>: MixedCase and camelCasedWords are separated by
  393. dashes, and the entire string cast to lowercase. E.g.:
  394. "FooBarBaz" becomes "foo-bar-baz".
  395. </para>
  396. <para>
  397. Internally, the inflector uses the filters
  398. <classname>Zend_Filter_Word_CamelCaseToDash</classname> and
  399. <classname>Zend_Filter_StringToLower</classname>.
  400. </para>
  401. </listitem>
  402. <listitem>
  403. <para>
  404. <emphasis>:controller</emphasis>: MixedCase and camelCasedWords are
  405. separated by dashes; underscores are converted to directory
  406. separators, and the entire string cast to lower case.
  407. Examples: "<classname>FooBar</classname>" becomes "foo-bar";
  408. "<classname>FooBar_Admin</classname>" becomes
  409. "<filename>foo-bar/admin</filename>".
  410. </para>
  411. <para>
  412. Internally, the inflector uses the filters
  413. <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
  414. <classname>Zend_Filter_Word_UnderscoreToSeparator</classname>, and
  415. <classname>Zend_Filter_StringToLower</classname>.
  416. </para>
  417. </listitem>
  418. <listitem>
  419. <para>
  420. <emphasis>:action</emphasis>: MixedCase and camelCasedWords are separated
  421. by dashes; non-alphanumeric characters are translated to
  422. dashes, and the entire string cast to lower case.
  423. Examples: "fooBar" becomes "foo-bar"; "foo-barBaz"
  424. becomes "foo-bar-baz".
  425. </para>
  426. <para>
  427. Internally, the inflector uses the filters
  428. <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
  429. <classname>Zend_Filter_PregReplace</classname>, and
  430. <classname>Zend_Filter_StringToLower</classname>.
  431. </para>
  432. </listitem>
  433. </itemizedlist>
  434. </note>
  435. <para>
  436. The final items in the <emphasis>ViewRenderer</emphasis> <acronym>API</acronym> are the
  437. methods for actually determining view script paths and rendering views.
  438. These include:
  439. </para>
  440. <itemizedlist>
  441. <listitem>
  442. <para>
  443. <methodname>renderScript($script, $name)</methodname> allows you to
  444. render a script with a path you specify, optionally to a
  445. named path segment. When using this method, the
  446. <emphasis>ViewRenderer</emphasis> does no autodetermination of the
  447. script name, but instead directly passes the
  448. <varname>$script</varname> argument directly to the view object's
  449. <methodname>render()</methodname> method.
  450. </para>
  451. <note>
  452. <para>
  453. Once the view has been rendered to the response object, it
  454. sets the <emphasis>noRender</emphasis> to prevent accidentally
  455. rendering the same view script multiple times.
  456. </para>
  457. </note>
  458. <note>
  459. <para>
  460. By default,
  461. <methodname>Zend_Controller_Action::renderScript()</methodname>
  462. proxies to the <emphasis>ViewRenderer</emphasis>'s
  463. <methodname>renderScript()</methodname> method.
  464. </para>
  465. </note>
  466. </listitem>
  467. <listitem>
  468. <para>
  469. <methodname>getViewScript($action, $vars)</methodname> creates the path
  470. to a view script based on the action passed and/or any
  471. variables passed in <varname>$vars</varname>. Keys for this array
  472. may include any of the path specification keys ('moduleDir',
  473. 'module', 'controller', 'action', and 'suffix'). Any
  474. variables passed will be used; otherwise, values based on
  475. the current request will be utlized.
  476. </para>
  477. <para>
  478. <methodname>getViewScript()</methodname> will use either the
  479. <emphasis>viewScriptPathSpec</emphasis> or
  480. <emphasis>viewScriptPathNoControllerSpec</emphasis> based on the
  481. setting of the <emphasis>noController</emphasis> flag.
  482. </para>
  483. <para>
  484. Word delimiters occurring in module, controller, or action names will be
  485. replaced with dashes ('-'). Thus, if you have the controller name
  486. '<command>foo.bar</command>' and the action '<command>baz:bat</command>', using
  487. the default path specification will result in a view script path of
  488. '<filename>foo-bar/baz-bat.phtml</filename>'.
  489. </para>
  490. <note>
  491. <para>
  492. By default,
  493. <methodname>Zend_Controller_Action::getViewScript()</methodname>
  494. proxies to the <emphasis>ViewRenderer</emphasis>'s
  495. <methodname>getViewScript()</methodname> method.
  496. </para>
  497. </note>
  498. </listitem>
  499. <listitem>
  500. <para>
  501. <methodname>render($action, $name, $noController)</methodname> checks
  502. first to see if either <varname>$name</varname> or
  503. <varname>$noController</varname> have been passed, and if so, sets
  504. the appropriate flags (responseSegment and noController,
  505. respectively) in the ViewRenderer. It then passes the
  506. <varname>$action</varname> argument, if any, on to
  507. <methodname>getViewScript()</methodname>. Finally, it passes the
  508. calculated view script path to <methodname>renderScript()</methodname>.
  509. </para>
  510. <note>
  511. <para>
  512. Be aware of the side-effects of using <methodname>render()</methodname>: the
  513. values you pass for the response segment name and for
  514. the noController flag will persist in the object.
  515. Additionally, noRender will be set after rendering is
  516. completed.
  517. </para>
  518. </note>
  519. <note>
  520. <para>
  521. By default,
  522. <methodname>Zend_Controller_Action::render()</methodname> proxies to
  523. the <emphasis>ViewRenderer</emphasis>'s <methodname>render()</methodname>
  524. method.
  525. </para>
  526. </note>
  527. </listitem>
  528. <listitem>
  529. <para>
  530. <methodname>renderBySpec($action, $vars, $name)</methodname> allows you
  531. to pass path specification variables in order to determine
  532. the view script path to create. It passes
  533. <varname>$action</varname> and <varname>$vars</varname> to
  534. <methodname>getScriptPath()</methodname>, and then passes the resulting
  535. script path and <varname>$name</varname> on to
  536. <methodname>renderScript()</methodname>.
  537. </para>
  538. </listitem>
  539. </itemizedlist>
  540. </sect4>
  541. <sect4 id="zend.controller.actionhelper.viewrenderer.basicusage">
  542. <title>Basic Usage Examples</title>
  543. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-1">
  544. <title>Basic Usage</title>
  545. <para>
  546. At its most basic, you simply initialize and register the
  547. <emphasis>ViewRenderer</emphasis> helper with the helper broker in your
  548. bootstrap, and then set variables in your action methods.
  549. </para>
  550. <programlisting language="php"><![CDATA[
  551. // In your bootstrap:
  552. Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  553. ...
  554. // 'foo' module, 'bar' controller:
  555. class Foo_BarController extends Zend_Controller_Action
  556. {
  557. // Render bar/index.phtml by default; no action required
  558. public function indexAction()
  559. {
  560. }
  561. // Render bar/populate.phtml with variable 'foo' set to 'bar'.
  562. // Since view object defined at preDispatch(), it's already available.
  563. public function populateAction()
  564. {
  565. $this->view->foo = 'bar';
  566. }
  567. // Renders nothing as it forwards to another action; the new action
  568. // will perform any rendering
  569. public function bazAction()
  570. {
  571. $this->_forward('index');
  572. }
  573. // Renders nothing as it redirects to another location
  574. public function batAction()
  575. {
  576. $this->_redirect('/index');
  577. }
  578. }
  579. ]]></programlisting>
  580. </example>
  581. <note>
  582. <title>Naming Conventions: Word Delimiters in Controller and Action Names</title>
  583. <para>
  584. If your controller or action name is composed of several
  585. words, the dispatcher requires that these are separated on
  586. the <acronym>URL</acronym> by specific path and word delimiter characters. The
  587. <emphasis>ViewRenderer</emphasis> replaces any path delimiter found
  588. in the controller name with an actual path delimiter ('/'),
  589. and any word delimiter found with a dash ('-') when creating
  590. paths. Thus, a call to the action
  591. <filename>/foo.bar/baz.bat</filename> would dispatch to
  592. <methodname>FooBarController::bazBatAction()</methodname> in
  593. <filename>FooBarController.php</filename>, which would render
  594. <filename>foo-bar/baz-bat.phtml</filename>; a call to the action
  595. <filename>/bar_baz/baz-bat</filename> would dispatch to
  596. <methodname>Bar_BazController::bazBatAction()</methodname> in
  597. <filename>Bar/BazController.php</filename> (note the path
  598. separation) and render <filename>bar/baz/baz-bat.phtml</filename>.
  599. </para>
  600. <para>
  601. Note that the in the second example, the module is still the
  602. default module, but that, because of the existence of a path
  603. separator, the controller receives the name
  604. <classname>Bar_BazController</classname>, in
  605. <filename>Bar/BazController.php</filename>. The ViewRenderer mimics
  606. the controller directory hierarchy.
  607. </para>
  608. </note>
  609. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-2">
  610. <title>Disabling Autorender</title>
  611. <para>
  612. For some actions or controllers, you may want to turn off the
  613. autorendering -- for instance, if you're wanting to emit a
  614. different type of output (<acronym>XML</acronym>, <acronym>JSON</acronym>, etc),
  615. or if you simply want
  616. to emit nothing. You have two options: turn off all cases of
  617. autorendering (<methodname>setNeverRender()</methodname>), or simply turn it
  618. off for the current action (<methodname>setNoRender()</methodname>).
  619. </para>
  620. <programlisting language="php"><![CDATA[
  621. // Baz controller class, bar module:
  622. class Bar_BazController extends Zend_Controller_Action
  623. {
  624. public function fooAction()
  625. {
  626. // Don't auto render this action
  627. $this->_helper->viewRenderer->setNoRender();
  628. }
  629. }
  630. // Bat controller class, bar module:
  631. class Bar_BatController extends Zend_Controller_Action
  632. {
  633. public function preDispatch()
  634. {
  635. // Never auto render this controller's actions
  636. $this->_helper->viewRenderer->setNoRender();
  637. }
  638. }
  639. ]]></programlisting>
  640. </example>
  641. <note>
  642. <para>
  643. In most cases, it makes no sense to turn off autorendering
  644. globally (ala <methodname>setNeverRender()</methodname>), as the only thing
  645. you then gain from <emphasis>ViewRenderer</emphasis> is the autosetup of
  646. the view object.
  647. </para>
  648. </note>
  649. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-3">
  650. <title>Choosing a Different View Script</title>
  651. <para>
  652. Some situations require that you render a different script than
  653. one named after the action. For instance, if you have a
  654. controller that has both add and edit actions, they may both
  655. display the same 'form' view, albeit with different values set.
  656. You can easily change the script name used with either
  657. <methodname>setScriptAction()</methodname>, <methodname>setRender()</methodname>,
  658. or calling the helper as a method, which will invoke
  659. <methodname>setRender()</methodname>.
  660. </para>
  661. <programlisting language="php"><![CDATA[
  662. // Bar controller class, foo module:
  663. class Foo_BarController extends Zend_Controller_Action
  664. {
  665. public function addAction()
  666. {
  667. // Render 'bar/form.phtml' instead of 'bar/add.phtml'
  668. $this->_helper->viewRenderer('form');
  669. }
  670. public function editAction()
  671. {
  672. // Render 'bar/form.phtml' instead of 'bar/edit.phtml'
  673. $this->_helper->viewRenderer->setScriptAction('form');
  674. }
  675. public function processAction()
  676. {
  677. // do some validation...
  678. if (!$valid) {
  679. // Render 'bar/form.phtml' instead of 'bar/process.phtml'
  680. $this->_helper->viewRenderer->setRender('form');
  681. return;
  682. }
  683. // otherwise continue processing...
  684. }
  685. }
  686. ]]></programlisting>
  687. </example>
  688. <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-4">
  689. <title>Modifying the Registered View</title>
  690. <para>
  691. What if you need to modify the view object -- for instance,
  692. change the helper paths, or the encoding? You can do so either
  693. by modifying the view object set in your controller, or by
  694. grabbing the view object out of the <emphasis>ViewRenderer</emphasis>;
  695. both are references to the same object.
  696. </para>
  697. <programlisting language="php"><![CDATA[
  698. // Bar controller class, foo module:
  699. class Foo_BarController extends Zend_Controller_Action
  700. {
  701. public function preDispatch()
  702. {
  703. // change view encoding
  704. $this->view->setEncoding('UTF-8');
  705. }
  706. public function bazAction()
  707. {
  708. // Get view object and set escape callback to 'htmlspecialchars'
  709. $view = $this->_helper->viewRenderer->view;
  710. $view->setEscape('htmlspecialchars');
  711. }
  712. }
  713. ]]></programlisting>
  714. </example>
  715. </sect4>
  716. <sect4 id="zend.controller.actionhelper.viewrenderer.advancedusage">
  717. <title>Advanced Usage Examples</title>
  718. <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-1">
  719. <title>Changing the Path Specifications</title>
  720. <para>
  721. In some circumstances, you may decide that the default path
  722. specifications do not fit your site's needs. For instance, you
  723. may want to have a single template tree to which you may then
  724. give access to your designers (this is very typical when using
  725. <ulink url="http://smarty.php.net/">Smarty</ulink>, for
  726. instance). In such a case, you may want to hardcode the view
  727. base path specification, and create an alternate specification
  728. for the action view script paths themselves.
  729. </para>
  730. <para>
  731. For purposes of this example, let's assume that the base path to
  732. views should be '<filename>/opt/vendor/templates</filename>', and that you wish for
  733. view scripts to be referenced by
  734. '<filename>:moduleDir/:controller/:action.:suffix</filename>'; if the
  735. <emphasis>noController</emphasis>
  736. flag has been set, you want to render out of the top level
  737. instead of in a subdirectory ('<filename>:action.:suffix</filename>'). Finally, you
  738. want to use 'tpl' as the view script filename suffix.
  739. </para>
  740. <programlisting language="php"><![CDATA[
  741. /**
  742. * In your bootstrap:
  743. */
  744. // Different view implementation
  745. $view = new ZF_Smarty();
  746. $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
  747. $viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
  748. ->setViewScriptPathSpec(':module/:controller/:action.:suffix')
  749. ->setViewScriptPathNoControllerSpec(':action.:suffix')
  750. ->setViewSuffix('tpl');
  751. Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
  752. ]]></programlisting>
  753. </example>
  754. <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-2">
  755. <title>Rendering Multiple View Scripts from a Single Action</title>
  756. <para>
  757. At times, you may need to render multiple view scripts from a
  758. single action. This is very straightforward -- simply make
  759. multiple calls to <methodname>render()</methodname>:
  760. </para>
  761. <programlisting language="php"><![CDATA[
  762. class SearchController extends Zend_Controller_Action
  763. {
  764. public function resultsAction()
  765. {
  766. // Assume $this->model is the current model
  767. $this->view->results =
  768. $this->model->find($this->_getParam('query', '');
  769. // render() by default proxies to the ViewRenderer
  770. // Render first the search form and then the results
  771. $this->render('form');
  772. $this->render('results');
  773. }
  774. public function formAction()
  775. {
  776. // do nothing; ViewRenderer autorenders the view script
  777. }
  778. }
  779. ]]></programlisting>
  780. </example>
  781. </sect4>
  782. </sect3>
  783. <!--
  784. vim:se ts=4 sw=4 et:
  785. -->