| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="learning.view.placeholders.basics">
- <title>Basic Placeholder Usage</title>
- <para>
- Zend Framework defines a generic <methodname>placeholder()</methodname> view helper that you
- may use for as many custom placeholders you need. It also provides a variety of specific
- placeholder implementations for often-needed functionality, such as specifying the
- <emphasis>DocType</emphasis> declaration, document title, and more.
- </para>
- <para>
- All placeholders operate in roughly the same way. They are containers, and thus allow you to
- operate on them as collections. With them you can:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Append</emphasis> or <emphasis>prepend</emphasis> items to the collection.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Replace</emphasis> the entire collection with a single value.
- </para>
- </listitem>
- <listitem>
- <para>
- Specify a string with which to <emphasis>prepend output</emphasis> of the collection
- when rendering.
- </para>
- </listitem>
- <listitem>
- <para>
- Specify a string with which to <emphasis>append output</emphasis> of the collection
- when rendering.
- </para>
- </listitem>
- <listitem>
- <para>
- Specify a string with which to <emphasis>separate items</emphasis> of the collection
- when rendering.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Capture content</emphasis> into the collection.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Render</emphasis> the aggregated content.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Typically, you will call the helper with no arguments, which will return a container on
- which you may operate. You will then either echo this container to render it, or call
- methods on it to configure or populate it. If the container is empty, rendering it will
- simply return an empty string; otherwise, the content will be aggregated according to the
- rules by which you configure it.
- </para>
- <para>
- As an example, let's create a sidebar that consists of a number of "blocks" of content.
- You'll likely know up-front the structure of each block; let's assume for this example that
- it might look like this:
- </para>
- <programlisting language="html"><![CDATA[
- <div class="sidebar">
- <div class="block">
- <p>
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
- consectetur aliquet odio ac consectetur. Nulla quis eleifend
- tortor. Pellentesque varius, odio quis bibendum consequat, diam
- lectus porttitor quam, et aliquet mauris orci eu augue.
- </p>
- </div>
- <div class="block">
- <ul>
- <li><a href="/some/target">Link</a></li>
- <li><a href="/some/target">Link</a></li>
- </ul>
- </div>
- </div>
- ]]></programlisting>
- <para>
- The content will vary based on the controller and action, but the structure will be the
- same. Let's first setup the sidebar in a resource method of our bootstrap:
- </para>
- <programlisting language="php"><![CDATA[
- class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
- {
- // ...
- protected function _initSidebar()
- {
- $this->bootstrap('View');
- $view = $this->getResource('View');
- $view->placeholder('sidebar')
- // "prefix" -> markup to emit once before all items in collection
- ->setPrefix("<div class=\"sidebar\">\n <div class=\"block\">\n")
- // "separator" -> markup to emit between items in a collection
- ->setSeparator("</div>\n <div class=\"block\">\n")
- // "postfix" -> markup to emit once after all items in a collection
- ->setPostfix("</div>\n</div>");
- }
- // ...
- }
- ]]></programlisting>
- <para>
- The above defines a placeholder, "sidebar", that has no items. It configures the basic
- markup structure of that placeholder, however, per our requirements.
- </para>
- <para>
- Now, let's assume for the "user" controller that for all actions we'll want a block at the
- top containing some information. We could accomplish this in two ways: (a) we could add the
- content to the placeholder directly in the controller's
- <methodname>preDispatch()</methodname> method, or (b) we could render a view script from
- within the <methodname>preDispatch()</methodname> method. We'll use (b), as it follows a
- more proper separation of concerns (leaving view-related logic and functionality within a
- view script).
- </para>
- <para>
- We'll name the view script "<filename>user/_sidebar.phtml</filename>", and populate it as
- follows:
- </para>
- <programlisting language="php"><![CDATA[
- <?php $this->placeholder('sidebar')->captureStart() ?>
- <h4>User Administration</h4>
- <ul>
- <li><a href="<?php $this->url(array('action' => 'list')) ?>">
- List</a></li>
- <li><a href="<?php $this->url(array('action' => 'create')) ?>">
- Create</a></a></li>
- </ul>
- <?php $this->placeholder('sidebar')->captureEnd() ?>
- ]]></programlisting>
- <para>
- The above example makes use of the content capturing feature of placeholders. By default,
- content is appended as a new item in the container, allowing us to aggregate content. This
- example makes use of view helpers and static <acronym>HTML</acronym> in order to generate
- markup, and the content is then captured and appended into the placeholder itself.
- </para>
- <para>
- To invoke the above view script, we would write the following in our
- <methodname>preDispatch()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- class UserController extends Zend_Controller_Action
- {
- // ...
- public function preDispatch()
- {
- // ...
- $this->view->render('user/_sidebar.phtml');
- // ...
- }
- // ...
- }
- ]]></programlisting>
- <para>
- Note that we're not capturing the rendered value; there's no need, as the entierty of that
- view is being captured into a placeholder.
- </para>
- <para>
- Now, let's assume our "view" action in that same controller needs to present some
- information. Within the "<filename>user/view.phtml</filename>" view script, we might have
- the following snippet of content:
- </para>
- <programlisting language="php"><![CDATA[
- $this->placeholder('sidebar')
- ->append('<p>User: ' . $this->escape($this->username) . '</p>');
- ]]></programlisting>
- <para>
- This example makes use of the <methodname>append()</methodname> method, and passes it some
- simple markup to aggregate.
- </para>
- <para>
- Finally, let's modify our layout view script, and have it render the placeholder.
- </para>
- <programlisting language="php"><![CDATA[
- <html>
- <head>
- <title>My Site</title>
- </head>
- <body>
- <div class="content">
- <?php echo $this->layout()->content ?>
- </div>
- <?php echo $this->placeholder('sidebar') ?>
- </body>
- </html>
- ]]></programlisting>
- <para>
- For controllers and actions that do not populate the "sidebar" placeholder, no content will
- be rendered; for those that do, however, echoing the placeholder will render the content
- according to the rules we created in our bootstrap, and the content we aggregated throughout
- the application. In the case of the "<filename>/user/view</filename>" action, and assuming a
- username of "matthew", we would get content for the sidebar as follows (formatted for
- readability):
- </para>
- <programlisting language="html"><![CDATA[
- <div class="sidebar">
- <div class="block">
- <h4>User Administration</h4>
- <ul>
- <li><a href="/user/list">List</a></li>
- <li><a href="/user/create">Create</a></a></li>
- </ul>
- </div>
- <div class="block">
- <p>User: matthew</p>
- </div>
- </div>
- ]]></programlisting>
- <para>
- There are a large number of things you can do by combining placeholders and layout scripts;
- experiment with them, and read the <link
- linkend="zend.view.helpers.initial.placeholder">relevant manual sections</link> for more
- information.
- </para>
- </sect1>
|