<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="learning.quickstart.create-layout">
    <title>Create A Layout</title>

    <para>
        You may have noticed that the view scripts in the previous sections were
        <acronym>HTML</acronym> fragments- not complete pages. This is by design; we want our
        actions to return content only related to the action itself, not the application as a whole.
    </para>

    <para>
        Now we must compose that generated content into a full <acronym>HTML</acronym> page. We'd
        also like to have a consistent look and feel for the application. We will use a global site
        layout to accomplish both of these tasks.
    </para>

    <para>
        There are two design patterns that Zend Framework uses to implement layouts: <ulink
            url="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</ulink> and
        <ulink
            url="http://java.sun.com/blueprints/corej2eepatterns/Patterns/CompositeView.html">Composite
            View</ulink>. <emphasis>Two Step View</emphasis> is usually associated with the <ulink
            url="http://www.martinfowler.com/eaaCatalog/transformView.html">Transform View</ulink>
        pattern; the basic idea is that your application view creates a representation that is then
        injected into the master view for final transformation. The <emphasis>Composite
            View</emphasis> pattern deals with a view made of one or more atomic, application views.
    </para>

    <para>
        In Zend Framework, <link linkend="zend.layout">Zend_Layout</link> combines the ideas behind
        these patterns. Instead of each action view script needing to include site-wide artifacts,
        they can simply focus on their own responsibilities.
    </para>

    <para>
        Occasionally, however, you may need application-specific information in your site-wide view
        script. Fortunately, Zend Framework provides a variety of view
        <emphasis>placeholders</emphasis> to allow you to provide such information from your action
        view scripts.
    </para>

    <para>
        To get started using <classname>Zend_Layout</classname>, first we need to inform our
        bootstrap to use the <classname>Layout</classname> resource. This can be done using the
        <command>zf enable layout</command> command:
    </para>

    <programlisting language="shell"><![CDATA[
% zf enable layout
Layouts have been enabled, and a default layout created at
application/layouts/scripts/layout.phtml
A layout entry has been added to the application config file.
]]></programlisting>

    <para>
        As noted by the command,
        <filename>application/configs/application.ini</filename> is updated, and
        now contains the following within the <constant>production</constant>
        section:
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

; Add to [production] section:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
]]></programlisting>

    <para>
        The final <acronym>INI</acronym> file should look as follows:
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

[production]
; PHP settings we want to initialize
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
]]></programlisting>

    <para>
        This directive tells your application to look for layout view scripts in
        <filename>application/layouts/scripts</filename>. If you examine your directory tree, you'll
        see that this directory has been created for you now, with the file
        <filename>layout.phtml</filename>.
    </para>

    <para>
        We also want to ensure we have an XHTML DocType declaration for our application. To enable
        this, we need to add a resource to our bootstrap.
    </para>

    <para>
        The simplest way to add a bootstrap resource is to simply create a protected method
        beginning with the phrase <methodname>_init</methodname>. In this case, we want to
        initialize the doctype, so we'll create an <methodname>_initDoctype()</methodname> method
        within our bootstrap class:
    </para>

    <programlisting language="php"><![CDATA[
// application/Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initDoctype()
    {
    }
}
]]></programlisting>

    <para>
        Within that method, we need to hint to the view to use the appropriate doctype. But where
        will the view object come from? The easy solution is to initialize the
        <classname>View</classname> resource; once we have, we can pull the view object from the
        bootstrap and use it.
    </para>

    <para>
        To initialize the view resource, add the following line to your
        <filename>application/configs/application.ini</filename> file, in the section marked
        <constant>production</constant>:
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

; Add to [production] section:
resources.view[] =
]]></programlisting>

    <para>
        This tells us to initialize the view with no options (the '[]' indicates that the "view" key
        is an array, and we pass nothing to it).
    </para>

    <para>
        Now that we have a view, let's flesh out our <methodname>_initDoctype()</methodname> method.
        In it, we will first ensure the <classname>View</classname> resource has run, fetch the view
        object, and then configure it:
    </para>

    <programlisting language="php"><![CDATA[
// application/Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initDoctype()
    {
        $this->bootstrap('view');
        $view = $this->getResource('view');
        $view->doctype('XHTML1_STRICT');
    }
}
]]></programlisting>

    <para>
        Now that we've initialized <classname>Zend_Layout</classname> and set the Doctype, let's
        create our site-wide layout:
    </para>

    <programlisting language="php"><![CDATA[
<!-- application/layouts/scripts/layout.phtml -->
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Zend Framework Quickstart Application</title>
  <?php echo $this->headLink()->appendStylesheet('/css/global.css') ?>
</head>
<body>
<div id="header" style="background-color: #EEEEEE; height: 30px;">
    <div id="header-logo" style="float: left">
        <b>ZF Quickstart Application</b>
    </div>
    <div id="header-navigation" style="float: right">
        <a href="<?php echo $this->url(
            array('controller'=>'guestbook'),
            'default',
            true) ?>">Guestbook</a>
    </div>
</div>

<?php echo $this->layout()->content ?>

</body>
</html>
]]></programlisting>

    <para>
        We grab our application content using the <methodname>layout()</methodname> view helper, and
        accessing the "content" key. You may render to other response segments if you wish to, but
        in most cases, this is all that's necessary.
    </para>

    <para>
        Note also the use of the <methodname>headLink()</methodname> placeholder. This is an easy
        way to generate the <acronym>HTML</acronym> for &lt;link&gt; elements, as well as to keep
        track of them throughout your application. If you need to add additional CSS sheets to
        support a single action, you can do so, and be assured it will be present in the final
        rendered page.
    </para>

    <note>
        <title>Checkpoint</title>

        <para>
            Now go to "http://localhost" and check out the source. You should see your XHTML header,
            head, title, and body sections.
        </para>
    </note>
</sect1>
