<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="learning.quickstart.create-layout">
    <title>Ein Layout erstellen</title>

    <para>
        Wie man festgestellen kann waren die View Skripte im vorhergehenden Kapitel
        <acronym>HTML</acronym> Fragmente- und keine kompletten Seiten. Das ist so gewünscht; wir
        wollen das unsere Aktionen nur den Inhalt zurückgeben der für die Aktion selbst relevant
        ist, und nicht die Anwendung als ganzes.
    </para>

    <para>
        Jetzt müssen wir den erstellten Inhalt zu einer kompletten <acronym>HTML</acronym> Seite
        zusammenfügen. Wir wollen auch ein konsistentes Aussehen und Feeling für die Anwendung
        haben. Wir wollen ein globales Sitelayout verwenden um beide Arbeiten zu ermöglichen.
    </para>

    <para>
        Es gibt zwei Design Pattern die Zend Framework verwendet um Layouts zu implementieren:
        <ulink url="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</ulink> und
        <ulink
            url="http://java.sun.com/blueprints/corej2eepatterns/Patterns/CompositeView.html">Composite
            View</ulink>. <emphasis>Two Step View</emphasis> wird normalerweise mit dem <ulink
            url="http://www.martinfowler.com/eaaCatalog/transformView.html">Transform View</ulink>
        Pattern assoziiert; die grundsätzliche Idee besteht darin das die View der Anwendung eine
        Repräsentation erstellt die dann in die Master View für letzte Transformationen injiziert
        wird. Das <emphasis>Composite View</emphasis> Pattern arbeitet mit einer View die aus ein
        oder mehreren atomischen Anwendungs Views gemacht ist.
    </para>

    <para>
        Im Zend Framework kombiniert <link linkend="zend.layout">Zend_Layout</link> die Ideen hinter
        diesen Pattern. Statt dass jedes Action View Skript Site-weite Artefakte einfügen muss,
        können Sie sich einfach auf Ihre eigenen Beantwortungen konzentrieren.
    </para>

    <para>
        Natürlich benötigt man trotzdem Anwendungs-spezifische Informationen im Site-weiten View
        Skript. Glücklicherweise bietet Zend Framework eine Anzahl von View
        <emphasis>Platzhaltern</emphasis> die es erlauben solche Informationen von den Action View
        Skripten zu bekommen.
    </para>

    <para>
        Um mit <classname>Zend_Layout</classname> zu beginnen müssen wir als erstes die Bootstrap
        informieren das Sie die <classname>Layout</classname> Ressource verwenden soll. Das kann
        getan werden indem der Befehl <command>zf enable layout</command> verwendet wird:
    </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>
        Wie vom Kommando notiert wird <filename>application/configs/application.ini</filename>
        aktualisiert und enthält jetzt das folgende im Abschnitt <constant>production</constant>:
    </para>

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

; Zum Abschnitt [production] hinzufügen:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
]]></programlisting>

    <para>
        Die endgültige <acronym>INI</acronym> Datei sollte wie folgt aussehen:
    </para>

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

[production]
; PHP Einstellungen die initialisiert werden sollen
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>
        Diese Direktive sagt der Anwendung das Sie nach Layout View Skripten unter
        <filename>application/layouts/scripts</filename> nachschauen soll. Wenn man den
        Verzeichnisbaum betrachtet sieht man das dieses Verzeichnis jetzt, zusammen mit der Datei
        <filename>layout.phtml</filename>, erstellt wurde.
    </para>

    <para>
        Wir wollen auch sicherstellen das wir eine XHTML DocType Deklaration für unsere Anwendung
        haben. Um das zu aktivieren mussen wir eine Ressource zu unserer Bootstrap hinzufügen.
    </para>

    <para>
        Der einfachste Weg um eine Bootstrap Ressource hinzuzufügen ist es einfach eine
        geschützte Methode zu erstellen die mit der Phrase <methodname>_init</methodname> beginnt.
        In diesem Fall wollen wir den Doctype initialisieren, also erstellen wir eine
        <methodname>_initDoctype()</methodname> Methode in unserer Bootstrap Klasse:
    </para>

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

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

    <para>
        In dieser Methode müssen wir der View sagen das Sie den richtigen DocType verwenden soll.
        Aber wo kommt das View Objekt her? Die einfachste Lösung ist die Initialisierung der
        <classname>View</classname> Ressource; sobald wir Sie haben können wir das View Objekt
        aus der Bootstrap holen und verwenden.
    </para>

    <para>
        Um die View Ressource zu initialisieren ist die folgende Zeile in der Sektion
        <constant>production</constant> der Datei
        <filename>application/configs/application.ini</filename> hinzuzufügen:
    </para>

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

; Zum Abschnitt [production] hinzufügen:
resources.view[] =
]]></programlisting>

    <para>
        Das sagt uns das die View ohne Optionen initialisiert werden soll ('[]' zeigt das der "view"
        Schlüssel ein Array ist, und wir Ihm nichts übergeben).
    </para>

    <para>
        Jetzt da wir die View haben, sehen wir uns die <methodname>_initDoctype()</methodname>
        Methode an. In Ihr stellen wir zuerst sicher das die <classname>View</classname> Ressource
        läuft, holen das View Objekt und konfigurieren es anschließend:
    </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>
        Jetzt da wir <classname>Zend_Layout</classname> initialisiert und den DocType gesetzt haben
        erstellen wir unser Site-weites 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 Schnellstart Anwendung</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 Schnellstart Anwendung</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>
        Wir holen den Inhalt der Anwendung indem der <methodname>layout()</methodname> View Helfer
        verwendet, und auf den "content" Schlüssel zugegriffen wird. Man kann andere Antwort
        Segmente darstellen wenn man das möchte, aber in den meisten Fällen ist das alles was
        notwendig ist.
    </para>

    <para>
        Es ist zu beachten das wir auch den <methodname>headLink()</methodname> Platzhalter
        verwenden. Das ist ein einfacher Weg um das <acronym>HTML</acronym> für das &lt;link&gt;
        Element zu erstellen, sowie um es durch die Anwendung hindurch zu verfolgen. Wenn man
        zusätzliche CSS Blätter zur Unterstützung einer einzelnen Aktion benötigt, kann das getan
        werden indem man sicherstellt das Sie in der endgültig dargestellten Seite vorhanden sind.
    </para>

    <note>
        <title>Checkpoint</title>

        <para>
            Jetzt gehen wir zu "http://localhost" und prüfen die Quelle. Man sieht den XHTML Header,
            Kopf, Titel und Body Abschnitte.
        </para>
    </note>
</sect1>
