[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / en / tutorials / view-placeholders-standard.xml
blobf80d6be0fe16b647c5c27b8b59dddb6906274632
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="learning.view.placeholders.standard">
4     <title>Standard Placeholders</title>
6     <para>
7         In the <link linkend="learning.view.placeholders.basics">previous section</link>, we learned
8         about the <methodname>placeholder()</methodname> view helper, and how it can be used to
9         aggregate custom content. In this section, we'll look at some of the concrete placeholders
10         shipped with Zend Framework, and how you can use them to your advantage when creating
11         complex composite layouts.
12     </para>
14     <para>
15         Most of the shipped placeholders are for generating content for the
16         <emphasis>&lt;head&gt;</emphasis> section of your layout content -- an area you typically
17         cannot manipulate directly via your application view scripts, but one you may want to
18         influence. As examples: you may want your title to contain certain content on every page,
19         but specific content based on the controller and/or action; you may want to specify
20         <acronym>CSS</acronym> files to load based on what section of the application you're in; you
21         may need specific JavaScript scripts loaded at different times; or you may want to set the
22         <acronym>DocType</acronym> declaration.
23     </para>
25     <para>
26         Zend Framework ships with placeholder implementations for each of these situations, and
27         several more.
28     </para>
30     <sect2 id="learning.view.placeholders.standard.doctype">
31         <title>Setting the DocType</title>
33         <para>
34             <acronym>DocType</acronym> declarations are troublesome to memorize, and often essential
35             to include in your document to ensure the browser properly renders your content. The
36             <methodname>doctype()</methodname> view helper allows you to use simple string mnemonics
37             to specify the desired <acronym>DocType</acronym>; additionally, other helpers will
38             query the <methodname>doctype()</methodname> helper to ensure the output generated
39             conforms with the requested <acronym>DocType</acronym>.
40         </para>
42         <para>
43             As an example, if you want to use the <acronym>XHTML1</acronym> Strict
44             <acronym>DTD</acronym>, you can simply specify:
45         </para>
47         <programlisting language="php"><![CDATA[
48 $this->doctype('XHTML1_STRICT');
49 ]]></programlisting>
51         <para>
52             Among the other available mnemonics, you'll find these common types:
53         </para>
55         <variablelist>
56             <varlistentry>
57                 <term>XHTML1_STRICT</term>
59                 <listitem>
60                     <para>
61                         <acronym>XHTML</acronym> 1.0 Strict
62                     </para>
63                 </listitem>
64             </varlistentry>
66             <varlistentry>
67                 <term>XHTML1_TRANSITIONAL</term>
69                 <listitem>
70                     <para>
71                         <acronym>XHTML</acronym> 1.0 Transitional
72                     </para>
73                 </listitem>
74             </varlistentry>
76             <varlistentry>
77                 <term>HTML4_STRICT</term>
79                 <listitem>
80                     <para>
81                         <acronym>HTML</acronym> 4.01 Strict
82                     </para>
83                 </listitem>
84             </varlistentry>
86             <varlistentry>
87                 <term>HTML4_Loose</term>
89                 <listitem>
90                     <para>
91                         <acronym>HTML</acronym> 4.01 Loose
92                     </para>
93                 </listitem>
94             </varlistentry>
96             <varlistentry>
97                 <term>HTML5</term>
99                 <listitem>
100                     <para>
101                         <acronym>HTML</acronym> 5
102                     </para>
103                 </listitem>
104             </varlistentry>
105         </variablelist>
107         <para>
108             You can assign the type and render the declaration in a single call:
109         </para>
111         <programlisting language="php"><![CDATA[
112 echo $this->doctype('XHTML1_STRICT');
113 ]]></programlisting>
115         <para>
116             However, the better approach is to assign the type in your bootstrap, and then render it
117             in your layout. Try adding the following to your bootstrap class:
118         </para>
120         <programlisting language="php"><![CDATA[
121 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
123     protected function _initDocType()
124     {
125         $this->bootstrap('View');
126         $view = $this->getResource('View');
127         $view->doctype('XHTML1_STRICT');
128     }
130 ]]></programlisting>
132         <para>
133             Then, in your layout script, simply <function>echo</function> the helper at the
134             top of the file:
135         </para>
137         <programlisting language="php"><![CDATA[
138 <?php echo $this->doctype() ?>
139 <html>
140     <!-- ... -->
141 ]]></programlisting>
143         <para>
144             This will ensure that your DocType-aware view helpers render the appropriate markup,
145             ensure that the type is set well before the layout is rendered, and provide a single
146             location to change the DocType.
147         </para>
148     </sect2>
150     <sect2 id="learning.view.placeholders.standard.head-title">
151         <title>Specifying the Page Title</title>
153         <para>
154             Often, a site will include the site or business name as part of the page title, and
155             then add additional information based on the location within the site. As an example,
156             the zend.com website includes the string "Zend.com" on all pages, and the prepends
157             information based on the page: "Zend Server - Zend.com". Within Zend Framework, the
158             <methodname>headTitle()</methodname> view helper can help simplify this task.
159         </para>
161         <para>
162             At its simplest, the <methodname>headTitle()</methodname> helper allows you to aggregate
163             content for the <emphasis>&lt;title&gt;</emphasis> tag; when you echo it, it then
164             assembles it based on the order in which segments are added. You can control the order
165             using <methodname>prepend()</methodname> and <methodname>append()</methodname>, and
166             provide a separator to use between segments using the
167             <methodname>setSeparator()</methodname> method.
168         </para>
170         <para>
171             Typically, you should specify any segments common to all pages in your bootstrap,
172             similar to how we define the doctype. In this case, we'll define a
173             <methodname>_initPlaceholders()</methodname> method for operating on all the various
174             placeholders, and specify an initial title as well as a separator.
175         </para>
177         <programlisting language="php"><![CDATA[
178 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
180     // ...
182     protected function _initPlaceholders()
183     {
184         $this->bootstrap('View');
185         $view = $this->getResource('View');
186         $view->doctype('XHTML1_STRICT');
188         // Set the initial title and separator:
189         $view->headTitle('My Site')
190              ->setSeparator(' :: ');
191     }
193     // ...
195 ]]></programlisting>
197         <para>
198             Within a view script, we might want to add another segment:
199         </para>
201         <programlisting language="php"><![CDATA[
202 <?php $this->headTitle()->append('Some Page'); // place after other segments ?>
203 <?php $this->headTitle()->prepend('Some Page'); // place before ?>
204 ]]></programlisting>
206         <para>
207             In our layout, we will simply echo the <methodname>headTitle()</methodname> helper:
208         </para>
210         <programlisting language="php"><![CDATA[
211 <?php echo $this->doctype() ?>
212 <html>
213     <?php echo $this->headTitle() ?>
214     <!-- ... -->
215 ]]></programlisting>
217         <para>
218             This will generate the following output:
219         </para>
221         <programlisting language="html"><![CDATA[
222 <!-- If append() was used: -->
223 <title>My Site :: Some Page</title>
225 <!-- If prepend() was used: -->
226 <title>Some Page :: My Site</title>
227 ]]></programlisting>
228     </sect2>
230     <sect2 id="learning.view.placeholders.standard.head-link">
231         <title>Specifying Stylesheets with HeadLink</title>
233         <para>
234             Good <acronym>CSS</acronym> developers will often create a general stylesheet for
235             sitewide styles, and individual stylesheets for specific sections or pages of the
236             website, and load these latter conditionally so as to decrease the amount of data
237             needing to be transferred on each request. The <methodname>headLink()</methodname>
238             placeholder makes such conditional aggregation of stylesheets trivial within your
239             application.
240         </para>
242         <para>
243             To accomplish this, <methodname>headLink()</methodname> defines a number of "virtual"
244             methods (via overloading) to make the process trivial. The ones we will be concerned
245             with are <methodname>appendStylesheet()</methodname> and
246             <methodname>prependStylesheet()</methodname>. Each takes up to four arguments,
247             <varname>$href</varname> (the relative path to the stylesheet),
248             <varname>$media</varname> (the <acronym>MIME</acronym> type, which defaults to
249             "text/css"), <varname>$conditionalStylesheet</varname> (which can be used to specify a
250             "condition" under which the stylesheet will be evaluated), and
251             <varname>$extras</varname> (an associative array of key and value pairs, commonly used
252             to specify a key for "media"). In most cases, you will only need to specify the first
253             argument, the relative path to the stylesheet.
254         </para>
256         <para>
257             In our example, we'll assume that all pages need to load the stylesheet located in
258             "<filename>/styles/site.css</filename>" (relative to the document root); we'll specify
259             this in our <methodname>_initPlaceholders()</methodname> bootstrap method.
260         </para>
262         <programlisting language="php"><![CDATA[
263 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
265     // ...
267     protected function _initPlaceholders()
268     {
269         $this->bootstrap('View');
270         $view = $this->getResource('View');
271         $view->doctype('XHTML1_STRICT');
273         // Set the initial title and separator:
274         $view->headTitle('My Site')
275              ->setSeparator(' :: ');
277         // Set the initial stylesheet:
278         $view->headLink()->prependStylesheet('/styles/site.css');
279     }
281     // ...
283 ]]></programlisting>
285         <para>
286             Later, in a controller or action-specific view script, we can add more stylesheets:
287         </para>
289         <programlisting language="php"><![CDATA[
290 <?php $this->headLink()->appendStylesheet('/styles/user-list.css') ?>
291 ]]></programlisting>
293         <para>
294             Within our layout view script, once again, we simply echo the placeholder:
295         </para>
297         <programlisting language="php"><![CDATA[
298 <?php echo $this->doctype() ?>
299 <html>
300     <?php echo $this->headTitle() ?>
301     <?php echo $this->headLink() ?>
302     <!-- ... -->
303 ]]></programlisting>
305         <para>
306             This will generate the following output:
307         </para>
309         <programlisting language="html"><![CDATA[
310 <link rel="stylesheet" type="text/css" href="/styles/site.css" />
311 <link rel="stylesheet" type="text/css" href="/styles/user-list.css" />
312 ]]></programlisting>
313     </sect2>
315     <sect2 id="learning.view.placeholders.standard.head-script">
316         <title>Aggregating Scripts Using HeadScript</title>
318         <para>
319             Another common tactic to prevent long page load times is to only load JavaScript when
320             necessary. That said, you may need several layers of scripts: perhaps one for
321             progressively enhancing menus on the site, and another for page-specific content. In
322             these situations, the <methodname>headScript()</methodname> helper presents a solution.
323         </para>
325         <para>
326             Similar to the <methodname>headLink()</methodname> helper,
327             <methodname>headScript()</methodname> provides the ability to append or prepend scripts
328             to the collection, and then echo the entire set. It provides the flexibility to specify
329             either script files themselves to load, or explicit JavaScript. You also have the option
330             of capturing JavaScript via
331             <methodname>captureStart()</methodname>/<methodname>captureEnd()</methodname>, which
332             allows you to simply inline the JavaScript instead of requiring an additional call to
333             your server.
334         </para>
336         <para>
337             Also like <methodname>headLink()</methodname>, <methodname>headScript()</methodname>
338             provides "virtual" methods via overloading as a convenience when specifying items to
339             aggregate; common methods include <methodname>prependFile()</methodname>,
340             <methodname>appendFile()</methodname>, <methodname>prependScript()</methodname>, and
341             <methodname>appendScript()</methodname>. The first two allow you to specify files that
342             will be referenced in a <emphasis>&lt;script&gt;</emphasis> tag's
343             <varname>$src</varname> attribute; the latter two will take the content provided and
344             render it as literal JavaScript within a <emphasis>&lt;script&gt;</emphasis> tag.
345         </para>
347         <para>
348             In this example, we'll specify that a script, "<filename>/js/site.js</filename>" needs
349             to be loaded on every page; we'll update our
350             <methodname>_initPlaceholders()</methodname> bootstrap method to do this.
351         </para>
353         <programlisting language="php"><![CDATA[
354 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
356     // ...
358     protected function _initPlaceholders()
359     {
360         $this->bootstrap('View');
361         $view = $this->getResource('View');
362         $view->doctype('XHTML1_STRICT');
364         // Set the initial title and separator:
365         $view->headTitle('My Site')
366              ->setSeparator(' :: ');
368         // Set the initial stylesheet:
369         $view->headLink()->prependStylesheet('/styles/site.css');
371         // Set the initial JS to load:
372         $view->headScript()->prependFile('/js/site.js');
373     }
375     // ...
377 ]]></programlisting>
379         <para>
380             Within a view script, we might then add an extra script file to source, or capture some
381             JavaScript to include in our document.
382         </para>
384         <programlisting language="php"><![CDATA[
385 <?php $this->headScript()->appendFile('/js/user-list.js') ?>
386 <?php $this->headScript()->captureStart() ?>
387 site = {
388     baseUrl: "<?php echo $this->baseUrl() ?>"
390 <?php $this->headScript()->captureEnd() ?>
391 ]]></programlisting>
393         <para>
394             Within our layout script, we then simply echo the placeholder, just as we have all the
395             others:
396         </para>
398         <programlisting language="php"><![CDATA[
399 <?php echo $this->doctype() ?>
400 <html>
401     <?php echo $this->headTitle() ?>
402     <?php echo $this->headLink() ?>
403     <?php echo $this->headScript() ?>
404     <!-- ... -->
405 ]]></programlisting>
407         <para>
408             This will generate the following output:
409         </para>
411         <programlisting language="html"><![CDATA[
412 <script type="text/javascript" src="/js/site.js"></script>
413 <script type="text/javascript" src="/js/user-list.js"></script>
414 <script type="text/javascript">
415 site = {
416     baseUrl: "<?php echo $this->baseUrl() ?>"
418 </script>
419 ]]></programlisting>
421         <note>
422             <title>InlineScript Variant</title>
424             <para>
425                 Many browsers will often block display of a page until all scripts and stylesheets
426                 referenced in the <emphasis>&lt;head&gt;</emphasis> section have loaded. If you have
427                 a number of such directives, this can impact how soon somebody can start actually
428                 viewing the page.
429             </para>
431             <para>
432                 One way around this is to emit your <emphasis>&lt;script&gt;</emphasis> tags just
433                 prior to closing the <emphasis>&lt;body&gt;</emphasis> of your document. (This is a
434                 practice specifically recommend by the <ulink
435                     url="http://developer.yahoo.com/yslow/">Y! Slow project</ulink>.)
436             </para>
438             <para>
439                 Zend Framework supports this in two different ways:
440             </para>
442             <itemizedlist>
443                 <listitem>
444                     <para>
445                         You can render your <methodname>headScript()</methodname> tag whereever you
446                         like in your layout script; just because the title references "head" does
447                         not mean it needs to be rendered in that location.
448                     </para>
449                 </listitem>
451                 <listitem>
452                     <para>
453                         Alternately, you may use the <methodname>inlineScript()</methodname> helper,
454                         which is simply a variant on <methodname>headScript()</methodname>, and
455                         retains the same behavior, but uses a separate registry.
456                     </para>
457                 </listitem>
458             </itemizedlist>
459         </note>
460     </sect2>
461 </sect1>