view-placeholders-basics.xml 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="learning.view.placeholders.basics">
  4. <title>Basic Placeholder Usage</title>
  5. <para>
  6. Zend Framework defines a generic <methodname>placeholder()</methodname> view helper that you
  7. may use for as many custom placeholders you need. It also provides a variety of specific
  8. placeholder implementations for often-needed functionality, such as specifying the
  9. <emphasis>DocType</emphasis> declaration, document title, and more.
  10. </para>
  11. <para>
  12. All placeholders operate in roughly the same way. They are containers, and thus allow you to
  13. operate on them as collections. With them you can:
  14. </para>
  15. <itemizedlist>
  16. <listitem>
  17. <para>
  18. <emphasis>Append</emphasis> or <emphasis>prepend</emphasis> items to the collection.
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>
  23. <emphasis>Replace</emphasis> the entire collection with a single value.
  24. </para>
  25. </listitem>
  26. <listitem>
  27. <para>
  28. Specify a string with which to <emphasis>prepend output</emphasis> of the collection
  29. when rendering.
  30. </para>
  31. </listitem>
  32. <listitem>
  33. <para>
  34. Specify a string with which to <emphasis>append output</emphasis> of the collection
  35. when rendering.
  36. </para>
  37. </listitem>
  38. <listitem>
  39. <para>
  40. Specify a string with which to <emphasis>separate items</emphasis> of the collection
  41. when rendering.
  42. </para>
  43. </listitem>
  44. <listitem>
  45. <para>
  46. <emphasis>Capture content</emphasis> into the collection.
  47. </para>
  48. </listitem>
  49. <listitem>
  50. <para>
  51. <emphasis>Render</emphasis> the aggregated content.
  52. </para>
  53. </listitem>
  54. </itemizedlist>
  55. <para>
  56. Typically, you will call the helper with no arguments, which will return a container on
  57. which you may operate. You will then either echo this container to render it, or call
  58. methods on it to configure or populate it. If the container is empty, rendering it will
  59. simply return an empty string; otherwise, the content will be aggregated according to the
  60. rules by which you configure it.
  61. </para>
  62. <para>
  63. As an example, let's create a sidebar that consists of a number of "blocks" of content.
  64. You'll likely know up-front the structure of each block; let's assume for this example that
  65. it might look like this:
  66. </para>
  67. <programlisting language="html"><![CDATA[
  68. <div class="sidebar">
  69. <div class="block">
  70. <p>
  71. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
  72. consectetur aliquet odio ac consectetur. Nulla quis eleifend
  73. tortor. Pellentesque varius, odio quis bibendum consequat, diam
  74. lectus porttitor quam, et aliquet mauris orci eu augue.
  75. </p>
  76. </div>
  77. <div class="block">
  78. <ul>
  79. <li><a href="/some/target">Link</a></li>
  80. <li><a href="/some/target">Link</a></li>
  81. </ul>
  82. </div>
  83. </div>
  84. ]]></programlisting>
  85. <para>
  86. The content will vary based on the controller and action, but the structure will be the
  87. same. Let's first setup the sidebar in a resource method of our bootstrap:
  88. </para>
  89. <programlisting language="php"><![CDATA[
  90. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  91. {
  92. // ...
  93. protected function _initSidebar()
  94. {
  95. $this->bootstrap('View');
  96. $view = $this->getResource('View');
  97. $view->placeholder('sidebar')
  98. // "prefix" -> markup to emit once before all items in collection
  99. ->setPrefix("<div class=\"sidebar\">\n <div class=\"block\">\n")
  100. // "separator" -> markup to emit between items in a collection
  101. ->setSeparator("</div>\n <div class=\"block\">\n")
  102. // "postfix" -> markup to emit once after all items in a collection
  103. ->setPostfix("</div>\n</div>");
  104. }
  105. // ...
  106. }
  107. ]]></programlisting>
  108. <para>
  109. The above defines a placeholder, "sidebar", that has no items. It configures the basic
  110. markup structure of that placeholder, however, per our requirements.
  111. </para>
  112. <para>
  113. Now, let's assume for the "user" controller that for all actions we'll want a block at the
  114. top containing some information. We could accomplish this in two ways: (a) we could add the
  115. content to the placeholder directly in the controller's
  116. <methodname>preDispatch()</methodname> method, or (b) we could render a view script from
  117. within the <methodname>preDispatch()</methodname> method. We'll use (b), as it follows a
  118. more proper separation of concerns (leaving view-related logic and functionality within a
  119. view script).
  120. </para>
  121. <para>
  122. We'll name the view script "<filename>user/_sidebar.phtml</filename>", and populate it as
  123. follows:
  124. </para>
  125. <programlisting language="php"><![CDATA[
  126. <?php $this->placeholder('sidebar')->captureStart() ?>
  127. <h4>User Administration</h4>
  128. <ul>
  129. <li><a href="<?php $this->url(array('action' => 'list')) ?>">
  130. List</a></li>
  131. <li><a href="<?php $this->url(array('action' => 'create')) ?>">
  132. Create</a></a></li>
  133. </ul>
  134. <?php $this->placeholder('sidebar')->captureEnd() ?>
  135. ]]></programlisting>
  136. <para>
  137. The above example makes use of the content capturing feature of placeholders. By default,
  138. content is appended as a new item in the container, allowing us to aggregate content. This
  139. example makes use of view helpers and static <acronym>HTML</acronym> in order to generate
  140. markup, and the content is then captured and appended into the placeholder itself.
  141. </para>
  142. <para>
  143. To invoke the above view script, we would write the following in our
  144. <methodname>preDispatch()</methodname> method:
  145. </para>
  146. <programlisting language="php"><![CDATA[
  147. class UserController extends Zend_Controller_Action
  148. {
  149. // ...
  150. public function preDispatch()
  151. {
  152. // ...
  153. $this->view->render('user/_sidebar.phtml');
  154. // ...
  155. }
  156. // ...
  157. }
  158. ]]></programlisting>
  159. <para>
  160. Note that we're not capturing the rendered value; there's no need, as the entierty of that
  161. view is being captured into a placeholder.
  162. </para>
  163. <para>
  164. Now, let's assume our "view" action in that same controller needs to present some
  165. information. Within the "<filename>user/view.phtml</filename>" view script, we might have
  166. the following snippet of content:
  167. </para>
  168. <programlisting language="php"><![CDATA[
  169. $this->placeholder('sidebar')
  170. ->append('<p>User: ' . $this->escape($this->username) . '</p>');
  171. ]]></programlisting>
  172. <para>
  173. This example makes use of the <methodname>append()</methodname> method, and passes it some
  174. simple markup to aggregate.
  175. </para>
  176. <para>
  177. Finally, let's modify our layout view script, and have it render the placeholder.
  178. </para>
  179. <programlisting language="php"><![CDATA[
  180. <html>
  181. <head>
  182. <title>My Site</title>
  183. </head>
  184. <body>
  185. <div class="content">
  186. <?php echo $this->layout()->content ?>
  187. </div>
  188. <?php echo $this->placeholder('sidebar') ?>
  189. </body>
  190. </html>
  191. ]]></programlisting>
  192. <para>
  193. For controllers and actions that do not populate the "sidebar" placeholder, no content will
  194. be rendered; for those that do, however, echoing the placeholder will render the content
  195. according to the rules we created in our bootstrap, and the content we aggregated throughout
  196. the application. In the case of the "<filename>/user/view</filename>" action, and assuming a
  197. username of "matthew", we would get content for the sidebar as follows (formatted for
  198. readability):
  199. </para>
  200. <programlisting language="html"><![CDATA[
  201. <div class="sidebar">
  202. <div class="block">
  203. <h4>User Administration</h4>
  204. <ul>
  205. <li><a href="/user/list">List</a></li>
  206. <li><a href="/user/create">Create</a></a></li>
  207. </ul>
  208. </div>
  209. <div class="block">
  210. <p>User: matthew</p>
  211. </div>
  212. </div>
  213. ]]></programlisting>
  214. <para>
  215. There are a large number of things you can do by combining placeholders and layout scripts;
  216. experiment with them, and read the <link
  217. linkend="zend.view.helpers.initial.placeholder">relevant manual sections</link> for more
  218. information.
  219. </para>
  220. </sect1>