Browse Source

[MANUAL] German:

- sync to r19776

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19924 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 years ago
parent
commit
76829bf871
55 changed files with 8248 additions and 264 deletions
  1. BIN
      documentation/manual/de/figures/learning.quickstart.create-form.png
  2. BIN
      documentation/manual/de/figures/learning.quickstart.create-model.png
  3. BIN
      documentation/manual/de/figures/learning.quickstart.intro.mvc.png
  4. 6 2
      documentation/manual/de/module_specs/Zend_Dojo-BuildLayers.xml
  5. 207 184
      documentation/manual/de/module_specs/Zend_Feed_Writer.xml
  6. 116 0
      documentation/manual/de/module_specs/Zend_Service_WindowsAzure.xml
  7. 360 0
      documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Blob.xml
  8. 172 0
      documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Queue.xml
  9. 739 0
      documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Table.xml
  10. 1 1
      documentation/manual/de/module_specs/Zend_Tool-Extending.xml
  11. 71 75
      documentation/manual/de/module_specs/Zend_Tool-Usage-CLI.xml
  12. 11 1
      documentation/manual/de/module_specs/Zend_View-Helpers-Doctype.xml
  13. 16 1
      documentation/manual/de/module_specs/Zend_View-Helpers-HeadMeta.xml
  14. 21 0
      documentation/manual/de/tutorials/autoloading-conclusion.xml
  15. 108 0
      documentation/manual/de/tutorials/autoloading-design.xml
  16. 35 0
      documentation/manual/de/tutorials/autoloading-intro.xml
  17. 109 0
      documentation/manual/de/tutorials/autoloading-resources.xml
  18. 160 0
      documentation/manual/de/tutorials/autoloading-usage.xml
  19. 385 0
      documentation/manual/de/tutorials/form-decorators-composite.xml
  20. 13 0
      documentation/manual/de/tutorials/form-decorators-conclusion.xml
  21. 284 0
      documentation/manual/de/tutorials/form-decorators-individual.xml
  22. 24 0
      documentation/manual/de/tutorials/form-decorators-intro.xml
  23. 363 0
      documentation/manual/de/tutorials/form-decorators-layering.xml
  24. 245 0
      documentation/manual/de/tutorials/form-decorators-simplest.xml
  25. 21 0
      documentation/manual/de/tutorials/layout-conclusions.xml
  26. 57 0
      documentation/manual/de/tutorials/layout-intro.xml
  27. 255 0
      documentation/manual/de/tutorials/layout-usage.xml
  28. 28 0
      documentation/manual/de/tutorials/lucene-index-opening.xml
  29. 118 0
      documentation/manual/de/tutorials/lucene-index-structure.xml
  30. 95 0
      documentation/manual/de/tutorials/lucene-indexing.xml
  31. 103 0
      documentation/manual/de/tutorials/lucene-intro.xml
  32. 49 0
      documentation/manual/de/tutorials/lucene-pagination.xml
  33. 229 0
      documentation/manual/de/tutorials/lucene-queries.xml
  34. 99 0
      documentation/manual/de/tutorials/lucene-searching.xml
  35. 184 0
      documentation/manual/de/tutorials/multiuser-authentication.xml
  36. 246 0
      documentation/manual/de/tutorials/multiuser-authorization.xml
  37. 76 0
      documentation/manual/de/tutorials/multiuser-intro.xml
  38. 134 0
      documentation/manual/de/tutorials/multiuser-sessions.xml
  39. 107 0
      documentation/manual/de/tutorials/paginator-control.xml
  40. 38 0
      documentation/manual/de/tutorials/paginator-intro.xml
  41. 125 0
      documentation/manual/de/tutorials/paginator-simple.xml
  42. 75 0
      documentation/manual/de/tutorials/paginator-together.xml
  43. 63 0
      documentation/manual/de/tutorials/plugins-conclusion.xml
  44. 58 0
      documentation/manual/de/tutorials/plugins-intro.xml
  45. 157 0
      documentation/manual/de/tutorials/plugins-usage.xml
  46. 17 0
      documentation/manual/de/tutorials/quickstart-conclusion.xml
  47. 172 0
      documentation/manual/de/tutorials/quickstart-create-form.xml
  48. 214 0
      documentation/manual/de/tutorials/quickstart-create-layout.xml
  49. 761 0
      documentation/manual/de/tutorials/quickstart-create-model.xml
  50. 430 0
      documentation/manual/de/tutorials/quickstart-create-project.xml
  51. 115 0
      documentation/manual/de/tutorials/quickstart-intro-mvc.xml
  52. 255 0
      documentation/manual/de/tutorials/view-placeholders-basics.xml
  53. 17 0
      documentation/manual/de/tutorials/view-placeholders-conclusion.xml
  54. 44 0
      documentation/manual/de/tutorials/view-placeholders-intro.xml
  55. 460 0
      documentation/manual/de/tutorials/view-placeholders-standard.xml

BIN
documentation/manual/de/figures/learning.quickstart.create-form.png


BIN
documentation/manual/de/figures/learning.quickstart.create-model.png


BIN
documentation/manual/de/figures/learning.quickstart.intro.mvc.png


+ 6 - 2
documentation/manual/de/module_specs/Zend_Dojo-BuildLayers.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 16720 -->
+<!-- EN-Revision: 19768 -->
 <!-- Reviewed: no -->
 <sect1 id="zend.dojo.build-layers">
     <title>Support für den Build Layer von Zend_Dojo</title>
@@ -131,9 +131,13 @@ class App_Plugin_DojoLayer extends Zend_Controller_Plugin_Abstract
 
     public function getBuild()
     {
+        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
+            'ViewRenderer'
+        );
+        $viewRenderer->initView();
         if (null === $this->_build) {
             $this->_build = new Zend_Dojo_BuildLayer(array(
-                'view'      => $view,
+                'view'      => $viewRenderer->view,
                 'layerName' => 'custom.main',
             ));
         }

+ 207 - 184
documentation/manual/de/module_specs/Zend_Feed_Writer.xml

@@ -55,48 +55,52 @@
         </para>
 
         <para>
-            The containers include the <classname>Zend_Feed_Writer_Feed</classname> and
-            <classname>Zend_Feed_Writer_Entry</classname> classes. The Entry classes can be attached
-            to any Feed class. The sole purpose of these containers is to collect data about the
-            feed to generate using a simple interface of setter methods. These methods perform some
-            data validity testing. For example, it will validate any passed URIs, dates, etc. These
-            checks are not tied to any of the feed standards. The container objects also contain
-            methods to allow for fast rendering and export of the final feed, and these can be
-            reused at will.
+            Der Container enthält die Klassen <classname>Zend_Feed_Writer_Feed</classname> und
+            <classname>Zend_Feed_Writer_Entry</classname>. Die Einstiegsklassen können bei jeder
+            Feed Klasse angehängt werden. Der einzige Zweck dieses Containers ist es Daten über den
+            zu erstellenden Feed zu sammelnindem ein einfaches Interface von Setter Methoden
+            verwendet wird. Diese Methode führen einige Test zur Datenprüfung durch. Zum Beispiel
+            prüft er übergebene URIs, Datum, usw. Diese Checks sind nicht an einen der Feed
+            Standards gebunden. Das Container Objekt enthält auch Methoden welche die schnelle
+            Darstellung und den Export des endgültigen Feeds erlauben, und Sie können auf Wunsch
+            wiederverwendet werden.
         </para>
 
         <para>
-            While there are two data containers, there are four renderers - two matching container
-            renderers per support feed type. The renderer accept a container, and based on its
-            content attempt to generate a valid feed. If the renderer is unable to generate a valid
-            feed, perhaps due to the container missing an obligatory data point, it will report this
-            by throwing an <classname>Exception</classname>. While it is possible to ignore
-            <classname>Exception</classname>s, this removes the default safeguard of ensuring you
-            have sufficient data set to render a wholly valid feed.
+            Wärend es zwei Daten Container gibt, gibt es vier Renderer - zwei passende Container
+            Renderer pro unterstütztem Feed Typ. Der Renderer akzeptiert einen Container, und
+            basierend auf seinem Container versucht er einen gültigen Feed zu erstellen. Wenn der
+            Renderer nicht in der Lage ist einen gültigen Feed zu erstellen, möglicherweise weil dem
+            Container ein obligatorischer Datenpunkt fehlt, dann wird er dies melden indem eine
+            <classname>Exception</classname> geworfen wird. Wärend es möglich ist
+            <classname>Exception</classname>s zu ignorieren, würde das diese alle standardmäßigen
+            Sicherheiten entfernen welche sicherstellen das gültige Daten gesetzt wurden um einen
+            komplett gültigen Feed darzustellen.
         </para>
 
         <para>
-            Due to the system being divided between data containers and renderers, it can make
-            Extensions somewhat interesting. A typical Extension offering namespaced feed and entry
-            level elements, must itself reflect the exact same architecture, i.e. offer feed and
-            entry level data containers, and matching renderers. There is, fortunately, no complex
-            integration work required since all Extension classes are simply registered and
-            automatically used by the core classes. We'll meet Extensions in more detail at the end
-            of this section.
+            Da das System in Datencontainer und Renderer geteilt ist, kann es Erweiterungen
+            interessant machen. Eine typische Erweiterung welche namespaced Feeds und Entry Level
+            Elemente bietet, muss selbst exakt die gleiche Atchitektur reflektieren, z.B. anbieten
+            von Feed und Entry Level Daten Containern, und passenden Renderern. Das ist,
+            glücklicherweise, keine komplexe Integrationsarbeit da alle Erweiterungsklassen einfach
+            registriert und automatisch von den Kern Klassen verwendet werden. Wir kommen später in
+            diesem Kapitel im Detail zu den Erweiterungen.
         </para>
     </sect2>
 
     <sect2 id="zend.feed.writer.getting.started">
-        <title>Getting Started</title>
+        <title>Beginnen</title>
 
         <para>
-            Using <classname>Zend_Feed_Reader</classname> is as simple as setting data and
-            triggering the renderer. Here is an example to generate a minimal Atom 1.0 feed.
+            Die Verwendung von <classname>Zend_Feed_Reader</classname> ist so einfach wie das Setzen
+            von Daten und dem Ausführen des Renderers. Hier ist ein Beispiel um einen minimalen Atom
+            1.0 Feed zu erstellen.
         </para>
 
         <programlisting language="php"><![CDATA[
 /**
- * Create the parent feed
+ * Den Eltern Feed erstellen
  */
 $feed = new Zend_Feed_Writer_Feed;
 $feed->setTitle('Paddy\'s Blog');
@@ -111,8 +115,8 @@ $feed->setDateModified(time());
 $feed->addHub('http://pubsubhubbub.appspot.com/');
 
 /**
- * Add one or more entries. Note that entries must
- * be manually added once created.
+ * Einen oder mehrere Einträge hinzufügen. Beachten das Einträge
+ * manuell hinzugefügt werden müssen sobald Sie erstellt wurden
  */
 $entry = $feed->createEntry();
 $entry->setTitle('All Your Base Are Belong To Us');
@@ -124,19 +128,22 @@ $entry->addAuthor(array(
 ));
 $entry->setDateModified(time());
 $entry->setDateCreated(time());
-$entry->setDescription('Exposing the difficultly of porting games to English.');
-$entry->setContent('I am not writing the article. The example is long enough as is ;).');
+$entry->setDescription(
+    'Die Schwierigkeiten erklären Spiele ins englische zu portieren.'
+);
+$entry->setContent(
+    'Ich schreibe diesen Artikel nicht. Das Beispiel ist lang genug ;).');
 $feed->addEntry($entry);
 
 /**
- * Render the resulting feed to Atom 1.0 and assign to $out.
- * You can substitute "atom" with "rss" to generate an RSS 2.0 feed.
+ * Den ergebenden Feed in Atom 1.0 darstellen und $out zuordnen. Man kann
+ * "atom" mit "rss" ersetzen um einen RSS 2.0 feed zu erstellen
  */
 $out = $feed->export('atom');
 ]]></programlisting>
 
         <para>
-            The output rendered should be as follows:
+            Die dargestellt Ausgabe sollte folgende sein:
         </para>
 
         <programlisting language="xml">
@@ -160,7 +167,7 @@ $out = $feed->export('atom');
     &#60;entry&#62;
         &#60;title type="html"&#62;&#60;![CDATA[All Your Base Are Belong To Us]]&#62;&#60;/title&#62;
         &#60;summary type="html"&#62;
-            &#60;![CDATA[Exposing the difficultly of porting games to English.]]&#62;
+            &#60;![CDATA[Die Schwierigkeiten erklären Spiele ins englische zu portieren.]]&#62;
         &#60;/summary&#62;
         &#60;published&#62;2009-12-14T20:28:18+00:00&#60;/published&#62;
         &#60;updated&#62;2009-12-14T20:28:18+00:00&#60;/updated&#62;
@@ -172,91 +179,93 @@ $out = $feed->export('atom');
         &#60;uri&#62;http://www.example.com&#60;/uri&#62;
         &#60;/author&#62;
         &#60;content type="html"&#62;
-            &#60;![CDATA[I am not writing the article. The example is long enough as is ;).]]&#62;
+            &#60;![CDATA[Ich schreibe diesen Artikel nicht. Das Beispiel ist lang genug ;).]]&#62;
         &#60;/content&#62;
     &#60;/entry&#62;
 &#60;/feed&#62;
 </programlisting>
 
         <para>
-            This is a perfectly valid Atom 1.0 example. It should be noted that omitting an obligatory point
-            of data, such as a title, will trigger an <classname>Exception</classname> when
-            rendering as Atom 1.0. This will differ for RSS 2.0 since a title may be omitted so long
-            as a description is present. This gives rise to Exceptions that differ between the two
-            standards depending on the renderer in use. By design,
-            <classname>Zend_Feed_Writer</classname> will not render an invalid feed for either
-            standard unless the end-user deliberately elects to ignore all Exceptions.
+            Das ist ein perfekt gültiges Beispiel für Atom 1.0. Es sollte erwähnt sein das die
+            Unterdrückung von obligatorischen Datenpunkten, wie dem Titel, eine
+            <classname>Exception</classname> werfen wenn diese als Atom 1.0 dargestellt werden.
+            Das unterscheidet sich für RSS 2.0 wo ein Titel unterdrückt werden kann solange eine
+            Beschreibung vorhanden ist. Dadurch werden Exceptions geworfen die sich zwischen beiden
+            Standards unterscheiden abhängig vom Renderer der Verwendet wird. Vom Design her wird
+            <classname>Zend_Feed_Writer</classname> einen ungültigen Feed für keinen Standard
+            darstellen solange der End-Benutzer nicht definiert das alle Exceptions ignoriert werden
+            sollen.
         </para>
     </sect2>
 
     <sect2 id="zend.feed.writer.setting.feed.data.points">
-        <title>Setting Feed Data Points</title>
+        <title>Die Datenpunkte eines Feeds setzen</title>
 
         <para>
-            Before you can render a feed, you must first setup the data necessary for
-            the feed being rendered. This utilises a simple setter style API which doubles
-            as an initial method for validating the data being set. By design, the API
-            closely matches that for <classname>Zend_Feed_Reader</classname> to avoid
-            undue confusion and uncertainty.
+            Bevor ein Feed dargestellt werden kann, müssen zuerst die notwendigen Daten, für den
+            Feed der dargestellt werden soll, gesetzt werden. Hierbei wird eine einfache Setter
+            artige API verwendet welche auch als initiale Methode für die Prüfung von Daten herhält
+            wenn diese gesetzt werden. Vom Design her entspricht die API stark der von
+            <classname>Zend_Feed_Reader</classname> um Unklarheiten und Unsicherheiten zu vermeiden.
         </para>
 
         <para>
-            <classname>Zend_Feed_Writer</classname> offers this API via its data container
-            classes <classname>Zend_Feed_Writer_Feed</classname> and
-            <classname>Zend_Feed_Writer_Entry</classname>. These classes merely store
-            all feed data in type-agnostic manner, meaning you may reuse any data
-            container with any renderer without requiring additional work. Both classes
-            are also amenable to Extensions, meaning that an Extension may define its own
-            container classes which are registered to the base container classes as extensions, and
-            are checked when any method call triggers the base container's
-            <methodname>__call()</methodname> method.
+            <classname>Zend_Feed_Writer</classname> bietet diese API über seine Datencontainer
+            Klassen <classname>Zend_Feed_Writer_Feed</classname> und
+            <classname>Zend_Feed_Writer_Entry</classname> an. Diese Klassen speichern nahezu alle
+            Feed Daten in einer vom Typ unabhängigen Art, was bedeutet das man jeden Datencontainer
+            mit jedem Renderer wiederverwenden kann ohne das zusätzliche Arbeit notwendig ist. Beide
+            Klassen sind auch offen für Erweiterungen, was bedeutet das eine Erweiterung seine
+            eigenen Containerklassen definieren kann welche bei den Basis Containerklassen als
+            Erweiterung registriert sind, und geprüft werden sobald irgendein Methodenaufruf die
+            <methodname>__call()</methodname> Methode des Basiscontainers auslöst.
         </para>
 
         <para>
-            Here's a summary of the Core <acronym>API</acronym> for Feeds. You should note it
-            comprises not only the basic <acronym>RSS</acronym> and Atom standards, but also
-            accounts for a number of included Extensions bundled with
-            <classname>Zend_Feed_Writer</classname>. The naming of these
-            Extension sourced methods remain fairly generic - all Extension
-            methods operate at the same level as the Core <acronym>API</acronym> though we do allow
-            you to retrieve any specific Extension object separately if required.
+            Hier ist eine Zusammenfassung der Kern <acronym>API</acronym> für Feeds. Man sollte
+            beachten das Sie nicht nur die Standards für <acronym>RSS</acronym> und Atom umfasst,
+            sondern auch eine Anzahl von Erweiterungen welche in
+            <classname>Zend_Feed_Writer</classname> enthalten sind. Die Benamung dieser Erweiterungs
+            Methoden ist recht generisch - alle Erweiterungs Methoden arbeiten auf dem gleichen
+            Level wie die Kern <acronym>API</acronym> da wir es erlauben jedes Erweiterungs Objekt
+            seperat zu empfangen wenn das notwendig ist.
         </para>
 
         <table>
-            <title>Feed Level API Methods</title>
+            <title>API Methoden auf Feed Level</title>
 
             <tgroup cols="2">
                 <tbody>
                     <row>
                         <entry><methodname>setId()</methodname></entry>
 
-                        <entry>Set a unique ID associated with this feed. For Atom 1.0
-                        this is an atom:id element, whereas for RSS 2.0 it is added
-                        as a guid element. These are optional so long as a link is
-                        added, i.e. the link is set as the ID.</entry>
+                        <entry>
+                            Setzt eine eindeutige ID die mit diesem Feed assoziiert ist. Für Atom
+                            1.0 ist das ein atom:id Element, und für RSS 2.0 wird es als guid
+                            Element hinzugefügt. Diese sind optional solange ein Link hinzugefügt
+                            wird, wenn z.B. der Link als ID gesetzt ist.
+                        </entry>
                     </row>
 
                     <row>
                         <entry><methodname>setTitle()</methodname></entry>
-
-                        <entry>Set the title of the feed.</entry>
+                        <entry>Setzt den Titel des Feeds.</entry>
                     </row>
 
                     <row>
                         <entry><methodname>setDescription()</methodname></entry>
-
-                        <entry>Set the text description of the feed.</entry>
+                        <entry>Setzt die textuelle Beschreibung des Feeds.</entry>
                     </row>
 
                     <row>
                         <entry><methodname>setLink()</methodname></entry>
 
                         <entry>
-                            Set a <acronym>URI</acronym> to the <acronym>HTML</acronym> website
-                            containing the same or
-                            similar information as this feed (i.e. if the feed is from a blog,
-                            it should provide the blog's <acronym>URI</acronym> where the
-                            <acronym>HTML</acronym> version of the entries can be read).
+                            Setzt eine <acronym>URI</acronym> zur <acronym>HTML</acronym> Website
+                            welche die gleichen oder ähnliche Informationen wie dieser Feed
+                            enthält (z.B. wenn der Feed von einem Blog ist, sollte er die
+                            <acronym>URI</acronym> des Blogs anbieten unter welche die
+                            <acronym>HTML</acronym> Version der Einträge gelesen werden können).
                         </entry>
                     </row>
 
@@ -264,15 +273,16 @@ $out = $feed->export('atom');
                         <entry><methodname>setFeedLinks()</methodname></entry>
 
                         <entry>
-                            Add a link to an XML feed, whether the feed being generated or
-                            an alternate URI pointing to the same feed but in a different
-                            format. At a minimum, it is recommended to include a link to
-                            the feed being generated so it has an identifiable final
-                            URI allowing a client to track its location changes without
-                            necessitating constant redirects. The parameter is an array of
-                            arrays, where each sub-array contains the keys "type" and "uri".
-                            The type should be one of "atom", "rss", or "rdf". If a type is
-                            omitted, it defaults to the type used when rendering the feed.
+                            Fügt einen Link zu einem XML Feed hinzu, entweder der erzeugte Feed oder
+                            eine alternative URI zeigen auf den gleichen Feed, aber in einem
+                            anderen Format. Es ist mindestens notwendig einen Link zum erstellten
+                            Feed zu inkludieren damit dieser eine identifizierbare endgültige URI
+                            hat, welche es dem Client erlaubt Änderungen des Orts mitzubekommen ohne
+                            das dauernde Umleitungen notwendig sind. Dieser Parameter ist ein Array
+                            von Arrays, wobei jedes Unter-Array die Schlüssel "type" und "uri"
+                            enthält. Der Type sollte "atom", "rss" oder "rdf" sein. Wenn ein Typ
+                            unterdrückt wird, ist er standardmäßig mit dem Typ identisch mit dem
+                            der Feed dargestellt wird.
                         </entry>
                     </row>
 
@@ -280,13 +290,13 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthors()</methodname></entry>
 
                         <entry>
-                            Sets the data for authors. The parameter is an array of arrays
-                            where each sub-array may contain the keys "name", "email" and
-                            "uri". The "uri" value is only applicable for Atom feeds since
-                            RSS contains no facility to show it. For RSS 2.0, rendering will
-                            create two elements - an author element containing the email
-                            reference with the name in brackets, and a Dublin Core creator
-                            element only containing the name.
+                            Setzt die Daten für Autoren. Der Parameter ist ein Array von Arrays
+                            wobei jedes Unter-Array die Schlüssel "name", "email" und "uri"
+                            enthalten kann. Der Wert "uri ist nur für Atom Feeds anwendbar da RSS
+                            keine möglichkeit enthält Ihn anzuzeigen. Für RSS 2.0 werden bei der
+                            Darstellung zwei Elemente erzeugt - ein Autor Element welches die
+                            Referenz zur Email enthält und dem Namen in Klammern, und ein Dublin
+                            Core Creator Element welches nur den Namen enthält.
                         </entry>
                     </row>
 
@@ -294,8 +304,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthor()</methodname></entry>
 
                         <entry>
-                            Sets the data for a single author following the same
-                            format as described above for a single sub-array.
+                            Setzt die Daten für einen einzelnen Autor und folgt dem selben Format
+                            wie vorher für ein einzelnes Unter-Array beschrieben.
                         </entry>
                     </row>
 
@@ -303,10 +313,11 @@ $out = $feed->export('atom');
                         <entry><methodname>setDateCreated()</methodname></entry>
 
                         <entry>
-                            Sets the date on which this feed was created. Generally
-                            only applicable to Atom where it represents the date the resource
-                            described by an Atom 1.0 document was created. The expected parameter
-                            may be a UNIX timestamp or a <classname>Zend_Date</classname> object.
+                            Setzt das Datum an dem dieser Feed erstellt wurde. Generell nur
+                            für Atom anwendbar wo es das Datum beschreibt zu der die Ressource,
+                            die von dem Atom 1.0 Dokument beschrieben wird, erstellt wurde. Der
+                            erwartete Parameter muss ein UNIX Timestamp oder ein
+                            <classname>Zend_Date</classname> Objekt sein.
                         </entry>
                     </row>
 
@@ -314,8 +325,9 @@ $out = $feed->export('atom');
                         <entry><methodname>getDateModified()</methodname></entry>
 
                         <entry>
-                            Sets the date on which this feed was last modified. The expected parameter
-                            may be a UNIX timestamp or a <classname>Zend_Date</classname> object.
+                            Setzt das Datum zu dem dieser Feed das letzte Mal geändert wurde. Der
+                            erwartete Parameter muss ein UNIX Timestamp oder ein
+                            <classname>Zend_Date</classname> Objekt sein.
                         </entry>
                     </row>
 
@@ -323,7 +335,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setLanguage()</methodname></entry>
 
                         <entry>
-                            Sets the language of the feed. This will be omitted unless set.
+                            Setzt die Sprache des Feeds. Diese wird unterdrückt solange Sie nicht
+                            gesetzt ist.
                         </entry>
                     </row>
 
@@ -331,11 +344,11 @@ $out = $feed->export('atom');
                         <entry><methodname>getGenerator()</methodname></entry>
 
                         <entry>
-                            Allows the setting of a generator. The parameter should be an
-                            array containing the keys "name", "version" and "uri". If omitted
-                            a default generator will be added referencing
-                            <classname>Zend_Feed_Writer</classname>, the current Zend Framework
-                            version and the Framework's URI.
+                            Erlaubt es einen Generator zu setzen. Der Parameter sollte ein Array
+                            sein welche die Schlüssel "name", "version" und "uri" enthält. Wenn er
+                            unterdrückt wird, wird ein standardmäßiger Generator hinzugefügt welcher
+                            auf <classname>Zend_Feed_Writer</classname>, die aktuelle Version vom
+                            Zend Framework und die URI des Frameworks verweist.
                         </entry>
                     </row>
 
@@ -343,7 +356,7 @@ $out = $feed->export('atom');
                         <entry><methodname>setCopyright()</methodname></entry>
 
                         <entry>
-                            Sets a copyright notice associated with the feed.
+                            Setzt eine Copyright Notiz die mit dem Feed assoziiert ist.
                         </entry>
                     </row>
 
@@ -351,11 +364,12 @@ $out = $feed->export('atom');
                         <entry><methodname>setHubs()</methodname></entry>
 
                         <entry>
-                            Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in
-                            the feed as Atom links so that PuSH Subscribers may subscribe to
-                            your feed. Note that you must implement a Pubsubhubbub Publisher in
-                            order for real-time updates to be enabled. A Publisher may be implemented
-                            using <classname>Zend_Feed_Pubsubhubbub_Publisher</classname>.
+                            Akzeptiert ein Array von Pubsubhubbub Hub Endpunkten die im Feed als
+                            Atom Links dargestellt werden damit PuSH Abonnenten den eigenen Feed
+                            abbonieren können. Es ist zu beachten das man einen Pubsubhubbub
+                            Herausgeber implementieren muss damit Real-Time Updates ermöglicht
+                            werden. Ein Herausgeber kann implementiert werden indem
+                            <classname>Zend_Feed_Pubsubhubbub_Publisher</classname> verwendet wird.
                         </entry>
                     </row>
 
@@ -363,12 +377,14 @@ $out = $feed->export('atom');
                         <entry><methodname>setCategories()</methodname></entry>
 
                         <entry>
-                            Accepts an array of categories for rendering, where each element is itself
-                            an array whose possible keys include "term", "label" and "scheme". The "term"
-                            is a typically a category name suitable for inclusion in a URI. The "label"
-                            may be a human readable category name supporting special characters (it is encoded
-                            during rendering) and is a required key. The "scheme" (called the domain in RSS)
-                            is optional but must be a valid URI.
+                            Akzepziert ein Array an Kategorien für die Darstellung, wobei jedes
+                            Element selbst ein Array ist dessen möglich Schlüssel "term", "label"
+                            und "scheme" enthalten. "term" ist typischerweise der Name einer
+                            Kategorie welche für die Aufnahme in einer URI passen. "label" kann
+                            ein menschlich lesbarer Name einer Kategorie sein der spezielle Zeichen
+                            unterstützt (er wird wärend der Darstellung kodiert) und ist ein
+                            benötigter Schlüssel. "scheme" (im RSS auch die Domain genannt) ist
+                            optional muss aber eine gültige URI sein.
                         </entry>
                     </row>
                 </tbody>
@@ -377,53 +393,53 @@ $out = $feed->export('atom');
     </sect2>
 
     <sect2 id="zend.feed.writer.setting.entry.data.points">
-        <title>Setting Entry Data Points</title>
+        <title>Setzen der Datenpunkt für Einträge</title>
 
         <para>
-            Here's a summary of the Core <acronym>API</acronym> for Entries/Items. You should note it
-            comprises not only the basic <acronym>RSS</acronym> and Atom standards, but also
-            accounts for a number of included Extensions bundled with
-            <classname>Zend_Feed_Writer</classname>. The naming of these
-            Extension sourced methods remain fairly generic - all Extension
-            methods operate at the same level as the Core <acronym>API</acronym> though we do allow
-            you to retrieve any specific Extension object separately if required.
+            Hier ist eine Zusammenfassung der Kern <acronym>API</acronym> für Einträge/Elemente.
+            Man sollte beachten das Sie nicht nur die Standards für <acronym>RSS</acronym> und Atom
+            umfasst, sondern auch eine Anzahl von Erweiterungen welche in
+            <classname>Zend_Feed_Writer</classname> enthalten sind. Die Benamung dieser Erweiterungs
+            Methoden ist recht generisch - alle Erweiterungs Methoden arbeiten auf dem gleichen
+            Level wie die Kern <acronym>API</acronym> da wir es erlauben jedes Erweiterungs Objekt
+            seperat zu empfangen wenn das notwendig ist.
         </para>
 
         <table>
-            <title>Entry Level API Methods</title>
+            <title>API Methoden auf Eintrags Level</title>
 
             <tgroup cols="2">
                 <tbody>
                     <row>
                         <entry><methodname>setId()</methodname></entry>
 
-                        <entry>Set a unique ID associated with this feed. For Atom 1.0
-                        this is an atom:id element, whereas for RSS 2.0 it is added
-                        as a guid element. These are optional so long as a link is
-                        added, i.e. the link is set as the ID.</entry>
+                        <entry>
+                            Setzt eine eindeutige ID die mit diesem Feed assoziiert ist. Für Atom
+                            1.0 ist das ein atom:id Element, und für RSS 2.0 wird es als guid
+                            Element hinzugefügt. Diese sind optional solange ein Link hinzugefügt
+                            wird, wenn z.B. der Link als ID gesetzt ist.
+                        </entry>
                     </row>
 
                     <row>
                         <entry><methodname>setTitle()</methodname></entry>
-
-                        <entry>Set the title of the feed.</entry>
+                        <entry>Setzt den Titel des Feeds.</entry>
                     </row>
 
                     <row>
                         <entry><methodname>setDescription()</methodname></entry>
-
-                        <entry>Set the text description of the feed.</entry>
+                        <entry>Setzt die textuelle Beschreibung des Feeds.</entry>
                     </row>
 
                     <row>
                         <entry><methodname>setLink()</methodname></entry>
 
                         <entry>
-                            Set a <acronym>URI</acronym> to the <acronym>HTML</acronym> website
-                            containing the same or
-                            similar information as this feed (i.e. if the feed is from a blog,
-                            it should provide the blog's <acronym>URI</acronym> where the
-                            <acronym>HTML</acronym> version of the entries can be read).
+                            Setzt eine <acronym>URI</acronym> zur <acronym>HTML</acronym> Website
+                            welche die gleichen oder ähnliche Informationen wie dieser Feed
+                            enthält (z.B. wenn der Feed von einem Blog ist, sollte er die
+                            <acronym>URI</acronym> des Blogs anbieten unter welche die
+                            <acronym>HTML</acronym> Version der Einträge gelesen werden können).
                         </entry>
                     </row>
 
@@ -431,15 +447,16 @@ $out = $feed->export('atom');
                         <entry><methodname>setFeedLinks()</methodname></entry>
 
                         <entry>
-                            Add a link to an XML feed, whether the feed being generated or
-                            an alternate URI pointing to the same feed but in a different
-                            format. At a minimum, it is recommended to include a link to
-                            the feed being generated so it has an identifiable final
-                            URI allowing a client to track its location changes without
-                            necessitating constant redirects. The parameter is an array of
-                            arrays, where each sub-array contains the keys "type" and "uri".
-                            The type should be one of "atom", "rss", or "rdf". If a type is
-                            omitted, it defaults to the type used when rendering the feed.
+                            Fügt einen Link zu einem XML Feed hinzu, entweder der erzeugte Feed oder
+                            eine alternative URI zeigen auf den gleichen Feed, aber in einem
+                            anderen Format. Es ist mindestens notwendig einen Link zum erstellten
+                            Feed zu inkludieren damit dieser eine identifizierbare endgültige URI
+                            hat, welche es dem Client erlaubt Änderungen des Orts mitzubekommen ohne
+                            das dauernde Umleitungen notwendig sind. Dieser Parameter ist ein Array
+                            von Arrays, wobei jedes Unter-Array die Schlüssel "type" und "uri"
+                            enthält. Der Type sollte "atom", "rss" oder "rdf" sein. Wenn ein Typ
+                            unterdrückt wird, ist er standardmäßig mit dem Typ identisch mit dem
+                            der Feed dargestellt wird.
                         </entry>
                     </row>
 
@@ -447,13 +464,13 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthors()</methodname></entry>
 
                         <entry>
-                            Sets the data for authors. The parameter is an array of arrays
-                            where each sub-array may contain the keys "name", "email" and
-                            "uri". The "uri" value is only applicable for Atom feeds since
-                            RSS contains no facility to show it. For RSS 2.0, rendering will
-                            create two elements - an author element containing the email
-                            reference with the name in brackets, and a Dublin Core creator
-                            element only containing the name.
+                            Setzt die Daten für Autoren. Der Parameter ist ein Array von Arrays
+                            wobei jedes Unter-Array die Schlüssel "name", "email" und "uri"
+                            enthalten kann. Der Wert "uri ist nur für Atom Feeds anwendbar da RSS
+                            keine möglichkeit enthält Ihn anzuzeigen. Für RSS 2.0 werden bei der
+                            Darstellung zwei Elemente erzeugt - ein Autor Element welches die
+                            Referenz zur Email enthält und dem Namen in Klammern, und ein Dublin
+                            Core Creator Element welches nur den Namen enthält.
                         </entry>
                     </row>
 
@@ -461,8 +478,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthor()</methodname></entry>
 
                         <entry>
-                            Sets the data for a single author following the same
-                            format as described above for a single sub-array.
+                            Setzt die Daten für einen einzelnen Autor und folgt dem selben Format
+                            wie vorher für ein einzelnes Unter-Array beschrieben.
                         </entry>
                     </row>
 
@@ -470,10 +487,11 @@ $out = $feed->export('atom');
                         <entry><methodname>setDateCreated()</methodname></entry>
 
                         <entry>
-                            Sets the date on which this feed was created. Generally
-                            only applicable to Atom where it represents the date the resource
-                            described by an Atom 1.0 document was created. The expected parameter
-                            may be a UNIX timestamp or a <classname>Zend_Date</classname> object.
+                            Setzt das Datum an dem dieser Feed erstellt wurde. Generell nur
+                            für Atom anwendbar wo es das Datum beschreibt zu der die Ressource,
+                            die von dem Atom 1.0 Dokument beschrieben wird, erstellt wurde. Der
+                            erwartete Parameter muss ein UNIX Timestamp oder ein
+                            <classname>Zend_Date</classname> Objekt sein.
                         </entry>
                     </row>
 
@@ -481,8 +499,9 @@ $out = $feed->export('atom');
                         <entry><methodname>getDateModified()</methodname></entry>
 
                         <entry>
-                            Sets the date on which this feed was last modified. The expected parameter
-                            may be a UNIX timestamp or a <classname>Zend_Date</classname> object.
+                            Setzt das Datum zu dem dieser Feed das letzte Mal geändert wurde. Der
+                            erwartete Parameter muss ein UNIX Timestamp oder ein
+                            <classname>Zend_Date</classname> Objekt sein.
                         </entry>
                     </row>
 
@@ -490,7 +509,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setLanguage()</methodname></entry>
 
                         <entry>
-                            Sets the language of the feed. This will be omitted unless set.
+                            Setzt die Sprache des Feeds. Diese wird unterdrückt solange Sie nicht
+                            gesetzt ist.
                         </entry>
                     </row>
 
@@ -498,11 +518,11 @@ $out = $feed->export('atom');
                         <entry><methodname>getGenerator()</methodname></entry>
 
                         <entry>
-                            Allows the setting of a generator. The parameter should be an
-                            array containing the keys "name", "version" and "uri". If omitted
-                            a default generator will be added referencing
-                            <classname>Zend_Feed_Writer</classname>, the current Zend Framework
-                            version and the Framework's URI.
+                            Erlaubt es einen Generator zu setzen. Der Parameter sollte ein Array
+                            sein welche die Schlüssel "name", "version" und "uri" enthält. Wenn er
+                            unterdrückt wird, wird ein standardmäßiger Generator hinzugefügt welcher
+                            auf <classname>Zend_Feed_Writer</classname>, die aktuelle Version vom
+                            Zend Framework und die URI des Frameworks verweist.
                         </entry>
                     </row>
 
@@ -510,7 +530,7 @@ $out = $feed->export('atom');
                         <entry><methodname>setCopyright()</methodname></entry>
 
                         <entry>
-                            Sets a copyright notice associated with the feed.
+                            Setzt eine Copyright Notiz die mit dem Feed assoziiert ist.
                         </entry>
                     </row>
 
@@ -518,11 +538,12 @@ $out = $feed->export('atom');
                         <entry><methodname>setHubs()</methodname></entry>
 
                         <entry>
-                            Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in
-                            the feed as Atom links so that PuSH Subscribers may subscribe to
-                            your feed. Note that you must implement a Pubsubhubbub Publisher in
-                            order for real-time updates to be enabled. A Publisher may be implemented
-                            using <classname>Zend_Feed_Pubsubhubbub_Publisher</classname>.
+                            Akzeptiert ein Array von Pubsubhubbub Hub Endpunkten die im Feed als
+                            Atom Links dargestellt werden damit PuSH Abonnenten den eigenen Feed
+                            abbonieren können. Es ist zu beachten das man einen Pubsubhubbub
+                            Herausgeber implementieren muss damit Real-Time Updates ermöglicht
+                            werden. Ein Herausgeber kann implementiert werden indem
+                            <classname>Zend_Feed_Pubsubhubbub_Publisher</classname> verwendet wird.
                         </entry>
                     </row>
 
@@ -530,12 +551,14 @@ $out = $feed->export('atom');
                         <entry><methodname>setCategories()</methodname></entry>
 
                         <entry>
-                            Accepts an array of categories for rendering, where each element is itself
-                            an array whose possible keys include "term", "label" and "scheme". The "term"
-                            is a typically a category name suitable for inclusion in a URI. The "label"
-                            may be a human readable category name supporting special characters (it is encoded
-                            during rendering) and is a required key. The "scheme" (called the domain in RSS)
-                            is optional but must be a valid URI.
+                            Akzepziert ein Array an Kategorien für die Darstellung, wobei jedes
+                            Element selbst ein Array ist dessen möglich Schlüssel "term", "label"
+                            und "scheme" enthalten. "term" ist typischerweise der Name einer
+                            Kategorie welche für die Aufnahme in einer URI passen. "label" kann
+                            ein menschlich lesbarer Name einer Kategorie sein der spezielle Zeichen
+                            unterstützt (er wird wärend der Darstellung kodiert) und ist ein
+                            benötigter Schlüssel. "scheme" (im RSS auch die Domain genannt) ist
+                            optional muss aber eine gültige URI sein.
                         </entry>
                     </row>
                 </tbody>

+ 116 - 0
documentation/manual/de/module_specs/Zend_Service_WindowsAzure.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="zend.service.windowsazure">
+    <title>Zend_Service_WindowsAzure</title>
+
+    <sect2 id="zend.service.windowsazure.introduction">
+        <title>Introduction</title>
+
+        <para>
+          Windows Azure is the name for Microsoft’s Software + Services platform, an operating
+          system in the cloud providing services for hosting, management, scalable storage with
+          support for simple blobs, tables, and queues, as well as a management infrastructure for
+          provisioning and geo-distribution of cloud-based services, and a development platform for
+          the Azure Services layer.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.sdk">
+        <title>Installing the Windows Azure SDK</title>
+
+        <para>
+            There are two development scenario's when working with Windows Azure.
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    You can develop your application using
+                    <classname>Zend_Service_WindowsAzure</classname> and the Windows Azure SDK,
+                    which provides a local developent environment of the services provided by
+                    Windows Azure's cloud infrastructure.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    You can develop your application using
+                    <classname>Zend_Service_WindowsAzure</classname>, working directly with the
+                    Windows Azure cloud infrastructure.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            The first case requires you to install the <ulink
+                url="http://www.microsoft.com/downloads/details.aspx?familyid=11B451C4-7A7B-4537-A769-E1D157BAD8C6&amp;displaylang=en">Windows
+                Azure SDK</ulink> on your development machine.  It is currently only available for
+            Windows environments; progress is being made on a Java-based version of the SDK which
+            can run on any platform.
+        </para>
+
+        <para>
+            The latter case requires you to have an account at <ulink
+                url="http://www.azure.com">Azure.com</ulink>.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.apiDocumentation">
+        <title>API Documentation</title>
+
+        <para>
+            The <classname>Zend_Service_WindowsAzure</classname> class provides the PHP wrapper to
+            the Windows Azure <acronym>REST</acronym> interface. Please consult the <ulink
+                url="http://msdn.microsoft.com/en-us/library/dd179355.aspx">REST
+                documentation</ulink> for detailed description of the service. You will need to be
+            familiar with basic concepts in order to use this service.
+        </para>
+
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.features">
+        <title>Features</title>
+
+        <para>
+            <classname>Zend_Service_WindowsAzure</classname> provides the following functionality:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    PHP classes for Windows Azure Blobs, Tables and Queues (for
+                    <acronym>CRUD</acronym> operations)
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Helper Classes for HTTP transport, AuthN/AuthZ, REST and Error Management
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Manageability, Instrumentation and Logging support
+                </para>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.architecture">
+        <title>Architecture</title>
+
+        <para>
+            <classname>Zend_Service_WindowsAzure</classname> provides access to Windows Azure's
+            storage, computation and management interfaces by abstracting the REST/XML interface
+            Windows Azure provides into a simple PHP API.
+        </para>
+
+        <para>
+            An application built using <classname>Zend_Service_WindowsAzure</classname> can access
+            Windows Azure's features, no matter if it is hosted on the Windows Azure platform or on
+            an in-premise web server.
+        </para>
+  </sect2>
+</sect1>

+ 360 - 0
documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Blob.xml

@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="zend.service.windowsazure.storage.blob">
+    <title>Zend_Service_WindowsAzure_Storage_Blob</title>
+
+    <para>
+        Blob Storage stores sets of binary data. Blob storage offers the following three
+        resources: the storage account, containers, and blobs.  Within your storage account,
+        containers provide a way to organize sets of blobs within your storage account.
+    </para>
+
+    <para>
+        Blob Storage is offered by Windows Azure as a <acronym>REST</acronym> API which is
+        wrapped by the <classname>Zend_Service_WindowsAzure_Storage_Blob</classname> class in
+        order to provide a native PHP interface to the storage account.
+    </para>
+
+    <sect2 id="zend.service.windowsazure.storage.blob.api">
+        <title>API Examples</title>
+
+        <para>
+            This topic lists some examples of using the
+            <classname>Zend_Service_WindowsAzure_Storage_Blob</classname> class.  Other features are
+            available in the download package, as well as a detailed API documentation of those
+            features.
+        </para>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.create-container">
+            <title>Creating a storage container</title>
+
+            <para>
+                Using the following code, a blob storage container can be created on development
+                storage.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.create-container">
+                <title>Creating a storage container</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+$result = $storageClient->createContainer('testcontainer');
+
+echo 'Container name is: ' . $result->Name;
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.delete-container">
+            <title>Deleting a storage container</title>
+
+            <para>
+                Using the following code, a blob storage container can be removed from development
+                storage.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.delete-container">
+                <title>Deleting a storage container</title>
+
+                <programlisting role="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+$storageClient->deleteContainer('testcontainer');
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.storing-blob">
+            <title>Storing a blob</title>
+
+            <para>
+                Using the following code, a blob can be uploaded to a blob storage container on
+                development storage. Note that the container has already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.storing-blob">
+                <title>Storing a blob</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+
+// upload /home/maarten/example.txt to Azure
+$result = $storageClient->putBlob(
+    'testcontainer', 'example.txt', '/home/maarten/example.txt'
+);
+
+echo 'Blob name is: ' . $result->Name;
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.copy-blob">
+            <title>Copying a blob</title>
+
+            <para>
+                Using the following code, a blob can be copied from inside the storage account.  The
+                advantage of using this method is that the copy operation occurs in the Azure cloud
+                and does not involve downloading the blob. Note that the container has already been
+                created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.copy-blob">
+                <title>Copying a blob</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+
+// copy example.txt to example2.txt
+$result = $storageClient->copyBlob(
+    'testcontainer', 'example.txt', 'testcontainer', 'example2.txt'
+);
+
+echo 'Copied blob name is: ' . $result->Name;
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.download-blob">
+            <title>Downloading a blob</title>
+
+            <para>
+                Using the following code, a blob can be downloaded from a blob storage container on
+                development storage. Note that the container has already been created before and a
+                blob has been uploaded.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.download-blob">
+                <title>Downloading a blob</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+
+// download file to /home/maarten/example.txt
+$storageClient->getBlob(
+    'testcontainer', 'example.txt', '/home/maarten/example.txt'
+);
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.api.public-blob">
+            <title>Making a blob publicly available</title>
+
+            <para>
+                By default, blob storage containers on Windows Azure are protected from public
+                viewing. If any user on the Internet should have access to a blob container, its ACL
+                can be set to public. Note that this applies to a complete container and not to a
+                single blob!
+            </para>
+
+            <para>
+                Using the following code, blob storage container ACL can be set on development
+                storage. Note that the container has already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.api.public-blob">
+                <title>Making a blob publicly available</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+
+// make container publicly available
+$storageClient->setContainerAcl('testcontainer', Zend_Service_WindowsAzure_Storage_Blob::ACL_PUBLIC);
+]]></programlisting>
+            </example>
+        </sect3>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.storage.blob.root">
+        <title>Root container</title>
+
+        <para>
+            Windows Azure Blob Storage provides support to work with a "root container".
+            This means that a blob can be stored in the root of your storage account,
+            i.e. <code>http://myaccount.blob.core.windows.net/somefile.txt</code>.
+        </para>
+
+        <para>
+            In order to work with the root container, it should first be created using the
+            <methodname>createContainer()</methodname> method, naming the container
+            <varname>$root</varname>.  All other operations on the root container should be issued
+            with the container name set to <varname>$root</varname>.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.storage.blob.wrapper">
+        <title>Blob storage stream wrapper</title>
+
+        <para>
+            The Windows Azure SDK for PHP provides support for registering a blob storage
+            client as a PHP file stream wrapper. The blob storage stream wrapper provides
+            support for using regular file operations on Windows Azure Blob Storage.
+            For example, one can open a file from Windows Azure Blob Storage with
+            the <functionname>fopen()</functionname> function:
+        </para>
+
+        <example id="zend.service.windowsazure.storage.blob.wrapper.sample">
+            <title>Example usage of blob storage stream wrapper</title>
+
+            <programlisting language="php"><![CDATA[
+$fileHandle = fopen('azure://mycontainer/myfile.txt', 'r');
+
+// ...
+
+fclose($fileHandle);
+]]></programlisting>
+        </example>
+
+        <para>
+            In order to do this, the Windows Azure SDK for PHP blob storage client
+            must be registered as a stream wrapper. This can be done by calling the
+            <methodname>registerStreamWrapper()</methodname> method:
+        </para>
+
+        <example id="zend.service.windowsazure.storage.blob.wrapper.register">
+            <title>Registering the blob storage stream wrapper</title>
+
+            <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
+$storageClient->registerStreamWrapper(); // registers azure:// on this storage client
+
+// or:
+
+$storageClient->registerStreamWrapper('blob://'); // regiters blob:// on this storage client
+]]></programlisting>
+        </example>
+
+        <para>
+            To unregister the stream wrapper, the <methodname>unregisterStreamWrapper()</methodname>
+            method can be used.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.storage.blob.sharedaccesssig">
+        <title>Shared Access Signature</title>
+
+        <para>
+            Windows Azure Bob Storage provides a feature called "Shared Access Signatures". By
+            default, there is only one level of authorization possible in Windows Azure Blob
+            Storage: either a container is private or it is public. Shared Access Signatures provide
+            a more granular method of authorization: read, write, delete and list permissions can be
+            assigned on a container or a blob and given to a specific client using an URL-based
+            model.
+        </para>
+
+        <para>
+            An example would be the following signature:
+        </para>
+
+        <literallayout>
+http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&amp;se=2009-08-17T09%3A56%3A17Z&amp;sr=c&amp;sp=w&amp;sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D
+        </literallayout>
+
+        <para>
+            The above signature gives write access to the "phpazuretestshared1"
+            container of the "phpstorage" account.
+        </para>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.sharedaccesssig.generate">
+            <title>Generating a Shared Access Signature</title>
+
+            <para>
+                When you are the owner of a Windows Azure Bob Storage account, you can create and
+                distribute a shared access key for any type of resource in your account. To do this,
+                the <methodname>generateSharedAccessUrl()</methodname> method of the
+                <classname>Zend_Service_WindowsAzure_Storage_Blob</classname> storage client can be
+                used.
+            </para>
+
+            <para>
+                The following example code will generate a Shared Access Signature for write access
+                in a container named "container1", within a timeframe of 3000 seconds.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.sharedaccesssig.generate-2">
+                <title>Generating a Shared Access Signature for a container</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient   = new Zend_Service_WindowsAzure_Storage_Blob();
+$sharedAccessUrl = storageClient->generateSharedAccessUrl(
+    'container1',
+    '',
+    'c',
+    'w',
+    $storageClient ->isoDate(time() - 500),
+    $storageClient ->isoDate(time() + 3000)
+);
+]]></programlisting>
+            </example>
+
+            <para>
+                The following example code will generate a Shared Access Signature for read access
+                in a blob named <filename>test.txt</filename> in a container named "container1"
+                within a time frame of 3000 seconds.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.sharedaccesssig-generate-3">
+                <title>Generating a Shared Access Signature for a blob</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient   = new Zend_Service_WindowsAzure_Storage_Blob();
+$sharedAccessUrl = storageClient->generateSharedAccessUrl(
+    'container1',
+    'test.txt',
+    'b',
+    'r',
+    $storageClient ->isoDate(time() - 500),
+    $storageClient ->isoDate(time() + 3000)
+);
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.blob.sharedaccesssig.consume">
+            <title>Working with Shared Access Signatures from others</title>
+
+            <para>
+                When you receive a Shared Access Signature from someone else, you can use the
+                Windows Azure SDK for PHP to work with the addressed resource.  For example, the
+                following signature can be retrieved from the owner of a storage account:
+            </para>
+
+            <literallayout>
+http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&amp;se=2009-08-17T09%3A56%3A17Z&amp;sr=c&amp;sp=w&amp;sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D
+            </literallayout>
+
+            <para>
+                The above signature gives write access to the "phpazuretestshared1" "container" of
+                the phpstorage account. Since the shared key for the account is not known, the
+                Shared Access Signature can be used to work with the authorized resource.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.blob.sharedaccesssig.consuming">
+                <title>Consuming a Shared Access Signature for a container</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Blob(
+    'blob.core.windows.net', 'phpstorage', ''
+);
+$storageClient->setCredentials(
+    new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature()
+);
+$storageClient->getCredentials()->setPermissionSet(array(
+    'http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&se=2009-08-17T09%3A56%3A17Z&sr=c&sp=w&sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D'
+));
+$storageClient->putBlob(
+    'phpazuretestshared1', 'NewBlob.txt', 'C:\Files\dataforazure.txt'
+);
+]]></programlisting>
+            </example>
+
+            <para>
+                Note that there was no explicit permission to write to a specific blob. Instead, the
+                Windows Azure SDK for PHP determined that a permission was required to either write
+                to that specific blob, or to write to its container. Since only a signature was
+                available for the latter, the Windows Azure SDK for PHP chose those credentials to
+                perform the request on Windows Azure blob storage.
+            </para>
+        </sect3>
+    </sect2>
+</sect1>

+ 172 - 0
documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Queue.xml

@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="zend.service.windowsazure.storage.queue">
+    <title>Zend_Service_WindowsAzure_Storage_Queue</title>
+
+    <para>
+        The Queue service stores messages that may be read by any client who has access to the
+        storage account.
+    </para>
+
+    <para>
+        A queue can contain an unlimited number of messages, each of which can be up to 8 KB in
+        size. Messages are generally added to the end of the queue and retrieved from the front of
+        the queue, although first in/first out (<acronym>FIFO</acronym>) behavior is not guaranteed.
+        If you need to store messages larger than 8 KB, you can store message data as a queue or in
+        a table and then store a reference to the data as a message in a queue.
+    </para>
+
+    <para>
+        Queue Storage is offered by Windows Azure as a <acronym>REST</acronym> API which is wrapped
+        by the <classname>Zend_Service_WindowsAzure_Storage_Queue</classname> class in order to
+        provide a native PHP interface to the storage account.
+    </para>
+
+    <sect2 id="zend.service.windowsazure.storage.queue.api">
+        <title>API Examples</title>
+
+        <para>
+            This topic lists some examples of using the
+            <classname>Zend_Service_WindowsAzure_Storage_Queue</classname> class.  Other features
+            are available in the download package, as well as a detailed API documentation of those
+            features.
+        </para>
+
+        <sect3 id="zend.service.windowsazure.storage.queue.api.create-queue">
+            <title>Creating a queue</title>
+
+            <para>
+                Using the following code, a queue can be created on development storage.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.create-queue.example">
+                <title>Creating a queue</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+$result = $storageClient->createQueue('testqueue');
+
+echo 'Queue name is: ' . $result->Name;
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.queue.api.delete-queue">
+            <title>Deleting a queue</title>
+
+            <para>
+                Using the following code, a queue can be removed from development storage.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.delete-queue.example">
+                <title>Deleting a queue</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+$storageClient->deleteQueue('testqueue');
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.queue.api.storing-queue">
+            <title>Adding a message to a queue</title>
+
+            <para>
+                Using the following code, a message can be added to a queue on development storage.
+                Note that the queue has already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.storing-queue.example">
+                <title>Adding a message to a queue</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+
+// 3600 = time-to-live of the message, if omitted defaults to 7 days
+$storageClient->putMessage('testqueue', 'This is a test message', 3600);
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.queue.api.read-queue">
+            <title>Reading a message from a queue</title>
+
+            <para>
+                Using the following code, a message can be read from a queue on development storage.
+                Note that the queue and message have already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.read-queue.example">
+                <title>Reading a message from a queue</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+
+// retrieve 10 messages at once
+$messages = $storageClient->getMessages('testqueue', 10);
+
+foreach ($messages as $message) {
+    echo $message->MessageText . "\r\n";
+}
+]]></programlisting>
+            </example>
+
+            <para>
+                The messages that are read using <methodname>getMessages()</methodname> will be
+                invisible in the queue for 30 seconds, after which the messages will re-appear in
+                the queue.  To mark a message as processed and remove it from the queue, use the
+                <methodname>deleteMessage()</methodname> method.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.read-queue.processexample">
+                <title>Marking a message as processed</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+
+// retrieve 10 messages at once
+$messages = $storageClient->getMessages('testqueue', 10);
+
+foreach ($messages as $message) {
+    echo $message . "\r\n";
+
+    // Mark the message as processed
+    $storageClient->deleteMessage('testqueue', $message);
+}
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.queue.api.peek-queue">
+            <title>Check if there are messages in a queue</title>
+
+            <para>
+                Using the following code, a queue can be checked for new messages.  Note that the
+                queue and message have already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.queue.api.peek-queue.example">
+                <title>Check if there are messages in a queue</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
+
+// retrieve 10 messages at once
+$messages = $storageClient->peekMessages('testqueue', 10);
+
+foreach ($messages as $message) {
+    echo $message->MessageText . "\r\n";
+}
+]]></programlisting>
+            </example>
+
+            <para>
+                Note that messages that are read using <methodname>peekMessages()</methodname> will
+                not become invisible in the queue, nor can they be marked as processed using the
+                <methodname>deleteMessage()</methodname> method.  To do this, use
+                <methodname>getMessages()</methodname> instead.
+            </para>
+        </sect3>
+    </sect2>
+</sect1>

+ 739 - 0
documentation/manual/de/module_specs/Zend_Service_WindowsAzure_Table.xml

@@ -0,0 +1,739 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="zend.service.windowsazure.storage.table">
+    <title>Zend_Service_WindowsAzure_Storage_Table</title>
+
+    <para>
+        The Table service offers structured storage in the form of tables.
+    </para>
+
+    <para>
+        Table Storage is offered by Windows Azure as a REST API which is wrapped by the
+        <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class in order to provide a
+        native PHP interface to the storage account.
+    </para>
+
+    <para>
+        This topic lists some examples of using the
+        <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class.  Other features are
+        available in the download package, as well as a detailed API documentation of those
+        features.
+    </para>
+
+    <para>
+        Note that development table storage (in the Windows Azure SDK) does not support all features
+        provided by the API. Therefore, the examples listed on this page are to be used on Windows
+        Azure production table storage.
+    </para>
+
+    <sect2 id="zend.service.windowsazure.storage.table.api">
+        <title>Operations on tables</title>
+
+        <para>
+            This topic lists some samples of operations that can be executed on tables.
+        </para>
+
+        <sect3 id="zend.service.windowsazure.storage.table.api.create">
+            <title>Creating a table</title>
+
+            <para>
+                Using the following code, a table can be created on Windows Azure production table
+                storage.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.api.create.example">
+                <title>Creating a table</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$result = $storageClient->createTable('testtable');
+
+echo 'New table name is: ' . $result->Name;
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.table.api.list">
+            <title>Listing all tables</title>
+
+            <para>
+                Using the following code, a list of all tables in Windows Azure production table
+                storage can be queried.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.api.list.example">
+                <title>Listing all tables</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$result = $storageClient->listTables();
+foreach ($result as $table) {
+    echo 'Table name is: ' . $table->Name . "\r\n";
+}
+]]></programlisting>
+            </example>
+        </sect3>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.storage.table.entities">
+        <title>Operations on entities</title>
+
+        <para>
+            Tables store data as collections of entities. Entities are similar to rows.  An entity
+            has a primary key and a set of properties. A property is a named, typed-value pair,
+            similar to a column.
+        </para>
+
+        <para>
+            The Table service does not enforce any schema for tables, so two entities in the same
+            table may have different sets of properties. Developers may choose to enforce a schema
+            on the client side. A table may contain any number of entities.
+        </para>
+
+        <para>
+            <classname>Zend_Service_WindowsAzure_Storage_Table</classname> provides 2 ways of
+            working with entities:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    Enforced schema
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    No enforced schema
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            All examples will make use of the following enforced schema class.
+        </para>
+
+        <example id="zend.service.windowsazure.storage.table.entities.schema">
+            <title>Enforced schema used in samples</title>
+
+            <programlisting language="php"><![CDATA[
+class SampleEntity extends Zend_Service_WindowsAzure_Storage_TableEntity
+{
+    /**
+    * @azure Name
+    */
+    public $Name;
+
+    /**
+    * @azure Age Edm.Int64
+    */
+    public $Age;
+
+    /**
+    * @azure Visible Edm.Boolean
+    */
+    public $Visible = false;
+}
+]]></programlisting>
+        </example>
+
+        <para>
+            Note that if no schema class is passed into table storage methods,
+            <classname>Zend_Service_WindowsAzure_Storage_Table</classname> automatically works with
+            <classname>Zend_Service_WindowsAzure_Storage_DynamicTableEntity</classname>.
+        </para>
+
+        <sect3 id="zend.service.windowsazure.storage.table.entities.enforced">
+            <title>Enforced schema entities</title>
+
+            <para>
+                To enforce a schema on the client side using the
+                <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class, you can create
+                a class which inherits
+                <classname>Zend_Service_WindowsAzure_Storage_TableEntity</classname>.  This class
+                provides some basic functionality for the
+                <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class to work with a
+                client-side schema.
+            </para>
+
+            <para>
+                Base properties provided by
+                <classname>Zend_Service_WindowsAzure_Storage_TableEntity</classname> are:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        PartitionKey (exposed through <methodname>getPartitionKey()</methodname> and
+                        <methodname>setPartitionKey()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        RowKey (exposed through <methodname>getRowKey()</methodname> and
+                        <methodname>setRowKey()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Timestamp (exposed through <methodname>getTimestamp()</methodname> and
+                        <methodname>setTimestamp()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Etag value (exposed through <methodname>getEtag()</methodname> and
+                        <methodname>setEtag()</methodname>)
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Here's a sample class inheriting
+                <classname>Zend_Service_WindowsAzure_Storage_TableEntity</classname>:
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.enforced.schema">
+                <title>Sample enforced schema class</title>
+
+                <programlisting language="php"><![CDATA[
+class SampleEntity extends Zend_Service_WindowsAzure_Storage_TableEntity
+{
+    /**
+     * @azure Name
+     */
+    public $Name;
+
+    /**
+     * @azure Age Edm.Int64
+     */
+    public $Age;
+
+    /**
+     * @azure Visible Edm.Boolean
+     */
+    public $Visible = false;
+}
+]]></programlisting>
+            </example>
+
+            <para>
+                The <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class will map
+                any class inherited from
+                <classname>Zend_Service_WindowsAzure_Storage_TableEntity</classname> to Windows
+                Azure table storage entities with the correct data type and property name. All there
+                is to storing a property in Windows Azure is adding a docblock comment to a public
+                property or public getter/setter, in the following format:
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.enforced.schema-property">
+                <title>Enforced property</title>
+
+                <programlisting language="php"><![CDATA[
+/**
+ * @azure <property name in Windows Azure> <optional property type>
+ */
+public $<property name in PHP>;
+]]></programlisting>
+            </example>
+
+            <para>
+                Let's see how to define a propety "Age" as an integer on Windows Azure table
+                storage:
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.enforced.schema-property-sample">
+                <title>Sample enforced property</title>
+
+                <programlisting language="php"><![CDATA[
+/**
+ * @azure Age Edm.Int64
+ */
+public $Age;
+]]></programlisting>
+            </example>
+
+            <para>
+                Note that a property does not necessarily have to be named the same on Windows Azure
+                table storage. The Windows Azure table storage property name can be defined as well
+                as the type.
+            </para>
+
+            <para>
+                The following data types are supported:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <constant>Edm.Binary</constant> - An array of bytes up to 64 KB in size.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.Boolean</constant> - A boolean value.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.DateTime</constant> - A 64-bit value expressed as Coordinated
+                        Universal Time (UTC). The supported DateTime range begins from 12:00
+                        midnight, January 1, 1601 A.D. (C.E.), Coordinated Universal Time (UTC). The
+                        range ends at December 31st, 9999.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.Double</constant> - A 64-bit floating point value.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.Guid</constant> - A 128-bit globally unique identifier.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.Int32</constant> - A 32-bit integer.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.Int64</constant> - A 64-bit integer.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <constant>Edm.String</constant> - A UTF-16-encoded value. String values may
+                        be up to 64 KB in size.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.table.entities.dynamic">
+            <title>No enforced schema entities (a.k.a. DynamicEntity)</title>
+
+            <para>
+                To use the <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class
+                without defining a schema, you can make use of the
+                <classname>Zend_Service_WindowsAzure_Storage_DynamicTableEntity</classname> class.
+                This class inherits <classname>Zend_Service_WindowsAzure_Storage_TableEntity</code>
+                like an enforced schema class does, but contains additional logic to make it dynamic
+                and not bound to a schema.
+            </para>
+
+            <para>
+                Base properties provided by
+                <classname>Zend_Service_WindowsAzure_Storage_DynamicTableEntity</classname> are:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        PartitionKey (exposed through <methodname>getPartitionKey()</methodname> and
+                        <methodname>setPartitionKey()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        RowKey (exposed through <methodname>getRowKey()</methodname> and
+                        <methodname>setRowKey()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Timestamp (exposed through <methodname>getTimestamp()</methodname> and
+                        <methodname>setTimestamp()</methodname>)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Etag value (exposed through <methodname>getEtag()</methodname> and
+                        <methodname>setEtag()</methodname>)
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Other properties can be added on the fly. Their Windows Azure table storage type
+                will be determined on-the-fly:
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.dynamic.schema">
+                <title>Dynamicaly adding properties to Zend_Service_WindowsAzure_Storage_DynamicTableEntity</title>
+
+                <programlisting language="php"><![CDATA[
+$target = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity(
+    'partition1', '000001'
+);
+$target->Name = 'Name'; // Will add property "Name" of type "Edm.String"
+$target->Age  = 25;     // Will add property "Age" of type "Edm.Int32"
+]]></programlisting>
+            </example>
+
+            <para>
+                Optionally, a property type can be enforced:
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.dynamic.schema-forcedproperties">
+                <title>Forcing property types on Zend_Service_WindowsAzure_Storage_DynamicTableEntity</title>
+
+                <programlisting language="php"><![CDATA[
+$target = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity(
+    'partition1', '000001'
+);
+$target->Name = 'Name'; // Will add property "Name" of type "Edm.String"
+$target->Age  = 25;     // Will add property "Age" of type "Edm.Int32"
+
+// Change type of property "Age" to "Edm.Int32":
+$target->setAzurePropertyType('Age', 'Edm.Int64');
+]]></programlisting>
+            </example>
+
+            <para>
+                The <classname>Zend_Service_WindowsAzure_Storage_Table</classname> class
+                automatically works with
+                <classname>Zend_Service_WindowsAzure_Storage_TableEntity</classname> if no specific
+                class is passed into Table Storage methods.
+            </para>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.table.entities.api">
+            <title>Entities API examples</title>
+
+            <sect4 id="zend.service.windowsazure.storage.table.entities.api.insert">
+                <title>Inserting an entity</title>
+
+                <para>
+                    Using the following code, an entity can be inserted into a table named
+                    "testtable".  Note that the table has already been created before.
+                </para>
+
+                <example id="zend.service.windowsazure.storage.table.api.entities.insert.example">
+                    <title>Inserting an entity</title>
+
+                    <programlisting language="php"><![CDATA[
+$entity = new SampleEntity ('partition1', 'row1');
+$entity->FullName = "Maarten";
+$entity->Age = 25;
+$entity->Visible = true;
+
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$result = $storageClient->insertEntity('testtable', $entity);
+
+// Check the timestamp and etag of the newly inserted entity
+echo 'Timestamp: ' . $result->getTimestamp() . "\n";
+echo 'Etag: ' . $result->getEtag() . "\n";
+]]></programlisting>
+                </example>
+            </sect4>
+
+            <sect4 id="zend.service.windowsazure.storage.table.entities.api.retrieve-by-id">
+                <title>Retrieving an entity by partition key and row key</title>
+
+                <para>
+                    Using the following code, an entity can be retrieved by partition key and row
+                    key.  Note that the table and entity have already been created before.
+                </para>
+
+                <example id="zend.service.windowsazure.storage.table.entities.api.retrieve-by-id.example">
+                    <title>Retrieving an entity by partition key and row key</title>
+
+                    <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entity= $storageClient->retrieveEntityById(
+    'testtable', 'partition1', 'row1', 'SampleEntity'
+);
+]]></programlisting>
+                </example>
+            </sect4>
+
+            <sect4 id="zend.service.windowsazure.storage.table.entities.api.updating">
+                <title>Updating an entity</title>
+
+                <para>
+                    Using the following code, an entity can be updated. Note that the table and
+                    entity have already been created before.
+                </para>
+
+                <example id="zend.service.windowsazure.storage.table.api.entities.updating.example">
+                    <title>Updating an entity</title>
+
+                    <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entity = $storageClient->retrieveEntityById(
+    'testtable', 'partition1', 'row1', 'SampleEntity'
+);
+
+$entity->Name = 'New name';
+$result = $storageClient->updateEntity('testtable', $entity);
+]]></programlisting>
+                </example>
+
+                <para>
+                    If you want to make sure the entity has not been updated before, you can make
+                    sure the <acronym>Etag</acronym> of the entity is checked. If the entity already
+                    has had an update, the update will fail to make sure you do not overwrite any
+                    newer data.
+                </para>
+
+                <example id="zend.service.windowsazure.storage.table.entities.api.updating.example-etag">
+                    <title>Updating an entity (with Etag check)</title>
+
+                    <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entity = $storageClient->retrieveEntityById(
+    'testtable', 'partition1', 'row1', 'SampleEntity'
+);
+
+$entity->Name = 'New name';
+
+// last parameter instructs the Etag check:
+$result = $storageClient->updateEntity('testtable', $entity, true);
+]]></programlisting>
+                </example>
+            </sect4>
+
+            <sect4 id="zend.service.windowsazure.storage.table.entities.api.delete">
+                <title>Deleting an entity</title>
+
+                <para>
+                    Using the following code, an entity can be deleted.  Note that the table and
+                    entity have already been created before.
+                </para>
+
+                <example id="zend.service.windowsazure.storage.table.entities.api.delete.example">
+                    <title>Deleting an entity</title>
+
+                    <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entity = $storageClient->retrieveEntityById(
+    'testtable', 'partition1', 'row1', 'SampleEntity'
+);
+$result = $storageClient->deleteEntity('testtable', $entity);
+]]></programlisting>
+                </example>
+            </sect4>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.table.entities.querying">
+            <title>Performing queries</title>
+
+            <para>
+                Queries in <classname>Zend_Service_WindowsAzure_Storage_Table</classname> table
+                storage can be performed in two ways:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        By manually creating a filter condition (involving learning a new query
+                        language)
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        By using the fluent interface provided by the
+                        <classname>Zend_Service_WindowsAzure_Storage_Table</classname>
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Using the following code, a table can be queried using a filter condition.  Note
+                that the table and entities have already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.entities.querying.query-filter">
+                <title>Performing queries using a filter condition</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entities = $storageClient->storageClient->retrieveEntities(
+    'testtable',
+    'Name eq \'Maarten\' and PartitionKey eq \'partition1\'',
+    'SampleEntity'
+);
+
+foreach ($entities as $entity) {
+    echo 'Name: ' . $entity->Name . "\n";
+}
+]]></programlisting>
+            </example>
+
+            <para>
+                Using the following code, a table can be queried using a fluent interface.  Note
+                that the table and entities have already been created before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.api.entities.query-fluent">
+                <title>Performing queries using a fluent interface</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+$entities = $storageClient->storageClient->retrieveEntities(
+    'testtable',
+    $storageClient->select()
+                  ->from($tableName)
+                  ->where('Name eq ?', 'Maarten')
+                  ->andWhere('PartitionKey eq ?', 'partition1'),
+    'SampleEntity'
+);
+
+foreach ($entities as $entity) {
+    echo 'Name: ' . $entity->Name . "\n";
+}
+]]></programlisting>
+            </example>
+        </sect3>
+
+        <sect3 id="zend.service.windowsazure.storage.table.entities.batch">
+            <title>Batch operations</title>
+
+            <para>
+                This topic demonstrates how to use the table entity group transaction features
+                provided by Windows Azure table storage. Windows Azure table storage supports batch
+                transactions on entities that are in the same table and belong to the same partition
+                group. A transaction can include at most 100 entities.
+            </para>
+
+            <para>
+                The following example uses a batch operation (transaction) to insert a set of
+                entities into the "testtable" table. Note that the table has already been created
+                before.
+            </para>
+
+            <example id="zend.service.windowsazure.storage.table.api.batch">
+                <title>Executing a batch operation</title>
+
+                <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+
+// Start batch
+$batch = $storageClient->startBatch();
+
+// Insert entities in batch
+$entities = generateEntities();
+foreach ($entities as $entity) {
+    $storageClient->insertEntity($tableName, $entity);
+}
+
+// Commit
+$batch->commit();
+]]></programlisting>
+            </example>
+        </sect3>
+    </sect2>
+
+    <sect2 id="zend.service.windowsazure.storage.table.sessionhandler">
+        <title>Table storage session handler</title>
+
+        <para>
+            When running a PHP application on the Windows Azure platform in a load-balanced mode
+            (running 2 Web Role instances or more), it is important that PHP session data can be
+            shared between multiple Web Role instances. The Windows Azure SDK for PHP provides the
+            <classname>Zend_Service_WindowsAzure_SessionHandler</classname> class, which uses
+            Windows Azure Table Storage as a session handler for PHP applications.
+        </para>
+
+        <para>
+            To use the <classname>Zend_Service_WindowsAzure_SessionHandler</classname> session
+            handler, it should be registered as the default session handler for your PHP
+            application:
+        </para>
+
+        <example id="zend.service.windowsazure.storage.table.api.sessionhandler-register">
+            <title>Registering table storage session handler</title>
+
+            <programlisting language="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+
+$sessionHandler = new Zend_Service_WindowsAzure_SessionHandler(
+    $storageClient , 'sessionstable'
+);
+$sessionHandler->register();
+]]></programlisting>
+        </example>
+
+        <para>
+            The above classname registers the
+            <classname>Zend_Service_WindowsAzure_SessionHandler</classname> session handler and will
+            store sessions in a table called "sessionstable".
+        </para>
+
+        <para>
+            After registration of the
+            <classname>Zend_Service_WindowsAzure_SessionHandler</classname> session handler,
+            sessions can be started and used in the same way as a normal PHP session:
+        </para>
+
+        <example id="zend.service.windowsazure.storage.table.api.sessionhandler-usage">
+            <title>Using table storage session handler</title>
+
+            <programlisting role="php"><![CDATA[
+$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
+    'table.core.windows.net', 'myaccount', 'myauthkey'
+);
+
+$sessionHandler = new Zend_Service_WindowsAzure_SessionHandler(
+    $storageClient , 'sessionstable'
+);
+$sessionHandler->register();
+
+session_start();
+
+if (!isset($_SESSION['firstVisit'])) {
+    $_SESSION['firstVisit'] = time();
+}
+
+// ...
+]]></programlisting>
+        </example>
+
+        <warning>
+            <para>
+                The <classname>Zend_Service_WindowsAzure_SessionHandler</classname> session handler
+                should be registered before a call to <functionname>session_start()</functionname>
+                is made!
+            </para>
+        </warning>
+    </sect2>
+</sect1>

+ 1 - 1
documentation/manual/de/module_specs/Zend_Tool-Extending.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19738 -->
+<!-- EN-Revision: 19778 -->
 <!-- Reviewed: no -->
 <sect1 id="zend.tool.extending">
     <title>Extending Zend_Tool</title>

+ 71 - 75
documentation/manual/de/module_specs/Zend_Tool-Usage-CLI.xml

@@ -1,21 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19748 -->
+<!-- EN-Revision: 19777 -->
 <!-- Reviewed: no -->
 <sect1 id="zend.tool.usage.cli">
-    <title>Using Zend_Tool On The Command Line</title>
+    <title>Verwendung von Zend_Tool auf der Kommandozeile</title>
 
     <para>
-        The <acronym>CLI</acronym>, or command line tool (internally known as the console tool),
-        is currently the primary interface for dispatching <classname>Zend_Tool</classname>
-        requests. With the <acronym>CLI</acronym> tool, developers can issue tooling requests
-        inside the "command line window", also commonly known as a "terminal" window. This
-        environment is predominant in the *nix environment, but also has a common implementation
-        in windows with the <filename>cmd.exe</filename>, console2 and also with the Cygwin project.
+        Das <acronym>CLI</acronym>, oder Kommandozeilentool (intern bekannt als Konsolen Tool),
+        ist aktuell das primäre Interface für die Bearbeitung von <classname>Zend_Tool</classname>
+        Anfragen. Mit dem <acronym>CLI</acronym> Tool können Entwickler Tooling Anfragen im
+        "Kommandozeilen Fenster", auch bekannt als "Terminal" Fenster, auslösen. Diese Umgebung ist
+        vorherrschend bei *nix Umgebungen, es gibt aber auch übliche Implementationen unter Windows
+        mit <filename>cmd.exe</filename>, Console2 und auch im Cygwin Projekt.
     </para>
 
     <!--
     <sect2 id="zend.tool.usage.cli.introduction">
-        <title>Introduction</title>
+        <title>Einführung</title>
     </sect2>
     -->
 
@@ -23,31 +23,29 @@
         <title>Installation</title>
 
         <sect3 id="zend.tool.usage.cli.installation.download-and-go">
-            <title>Download And Go</title>
+            <title>Herunterladen und anfangen</title>
 
             <para>
-                First download Zend Framework.  This can be done by going to framework.zend.com
-                and downloading the latest release.  After you've downloaded the package and placed
-                it on your system.  The next step is to make the zf command available to your system.
-                The easiest way to do this, is to copy the proper files from the bin/ directory
-                of the download, and place these files within the <emphasis>same</emphasis> directory
-                as the location of the php cli binary.
+                Zuerst muss Zend Framework heruntergeladen werden. Das kann man tun, indem man auf
+                framework.zend.com geht und das letzte Release herunterlädt. Nachdem man das
+                Paket heruntergeladen und auf dem System plaziert hat ist der nächste Schritt das
+                zf Kommendo auf dem System zu erstellen. Der einfachste Weg das zu tun ist die
+                richtigen Dateien vom bin/ Verzeichnis des Downloads zu kopieren, und diese Dateien
+                im <emphasis>gleichen</emphasis> Verzeichnis zu platzieren wie der Ort an dem die
+                PHP CLI Binardatei ist.
             </para>
-
-
-
         </sect3>
 
         <sect3 id="zend.tool.usage.cli.installation.pear">
-            <title>Installing Via Pear</title>
+            <title>Installation über Pear</title>
 
             <para>
-                To install via PEAR, you must use the 3rd party zfcampus.org site to retrieve the
-                latest Zend Framework PEAR package.  These packages are typically built within a day
-                of an official Zend Framework release.  The benefit of installing via the PEAR package
-                manager is that during the install process, the ZF library will end up on the
-                include_path, and the zf.php and zf scripts will end up in a place on your system
-                that will allow you to run them without any additional setup.
+                Um es über PEAR zu installieren muss man die 3rd Party Site zfcampus.org verwenden
+                und das letzte Zend Framwork PEAR Paket empfangen. Diese Pakete werden
+                typischerweise innerhalb eines Tages nach einem offiziellen Zend Framework Release
+                erstellt. Der Vorteil der Installation über den PEAR Package Manager ist, dass die
+                ZF Bibliothek im include_path endet, und die zf.php und ZF Skripte an einem Ort im
+                eigenen System enden der es erlaubt Sie ohne zusätzliches Setup zu starten.
             </para>
 
             <programlisting language="text"><![CDATA[
@@ -56,68 +54,67 @@ pear install zfcampus/zf
 ]]></programlisting>
 
             <para>
-                That is it. After the initial install, you should be able to continue on by
-                running the zf command.  Go good way to check to see if it't there is to run
-                zf --help
+                Das ist es schon. Nachdem initialen Setup sollte man in der Lage sein weiter zu
+                machen indem das zf Kommando ausgeführt wird. Ein gute Weg um zu prüfen ob es
+                vorhanden ist, ist es zf --help auszuführen.
             </para>
-
         </sect3>
 
         <sect3 id="zend.tool.usage.cli.installation.install-by-hand">
-            <title>Installing by Hand</title>
+            <title>Installation von Hand</title>
 
             <para>
-                Installing by hand refers to the process of forcing the zf.php and Zend Framework
-                library to work together when they are placed in non-convential places, or at least,
-                in a place that your system cannot dispatch from easily (typical of programs in your
-                system PATH).
+                Die Installtion von Hand zeigt den Prozess um zf.php und die Zend Framework
+                Bibliothek dazu zu zwingen zusammen zu arbeiten wenn diese nicht auf konventionellen
+                Orten abgelegt wurden, oder zumindest, an einem Ort an dem das eigene System diese
+                nicht einfach ausführen kann (typisch für Programme im eigenen System Pfad).
             </para>
 
             <para>
-                If you are on a *nix or mac system, you can also create a link from somewhere in your
-                path to the zf.sh file.  If you do this, you do not need to worry about having
-                Zend Framework's library on your include_path, as the zf.php and zf.sh files will
-                be able to access the library relative to where they are (meaning the ./bin/ files
-                are ../library/ relative to the Zend Framework library).
+                Wenn man auf einem *nix oder Mac System ist, kann man auch einen Link von irgendwo im
+                eigenen Pfad zur zf.sh Datei erstellen. Wenn man das macht muss man sich keine
+                Gedanken darüber machen das die Zend Framework Bibliothek im eigenen include_path
+                ist, da die Dateien zf.php und zf.sh auf die Bibliothek, relativ dazu wo Sie sind,
+                zugreifen können (was bedeutet das die ./bin/ Dateien relativ zu ../library/ der
+                Zend Framework Bibliothek sind).
             </para>
 
             <para>
-                There are a number of other options available for setting up the zf.php and library
-                on your system.  These options revolve around setting specific environment variables.
-                These are described in the later section on "customizing the CLI environement".  The
-                environment variables for setting the zf.php include_path, ZF_INCLUDE_PATH and
-                ZF_INCLUDE_PATH_PREPEND, are the ones of most interest.
+                Es gibt eine Anzahl von anderen vorhandenen Optionen für das Setup von zf.php und
+                der Bibliothek im eigenen System. Diese Optionen drehen sich um das Setzen von
+                speziellen Umgebungsvariablen. Diese werden im späteren Kapitel "Die CLI Umgebung
+                anpassen" beschrieben. Die Umgebungsvariablen für das Setzen von include_path,
+                ZF_INCLUDE_PATH und ZF_INCLUDE_PATH_PREPEND für zf.php sind die interessantesten.
             </para>
-
         </sect3>
-
     </sect2>
 
     <sect2 id="zend.tool.usage.cli.general-purpose-commands">
-        <title>General Purpose Commands</title>
+        <title>Kommandos für generelle Zwecke</title>
 
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.version">
             <title>Version</title>
 
             <para>
-                This will show the current version number of the copy of Zend Framework the zf.php tool is using.
+                Das zeigt die aktuelle Versionsnummer der Kopie vom Zend Framework welche das zf.php
+                Tool verwendet.
             </para>
 
             <programlisting language="text"><![CDATA[
 zf show version
 ]]></programlisting>
-
         </sect3>
 
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.built-in-help">
-            <title>Built-in Help</title>
+            <title>Eingebaute Hilfe</title>
 
             <para>
-                The built-in help system is the primary place where you can get up-to-date information
-                on what your system is capable of doing.  The help system is dynamic in that as providers
-                are added to your system, they are automatically dispatchable, and as such, the parameters
-                required to run them will be in the help screen.  The easiest way to retrieve the help
-                screen is the following:
+                Das eingebaute Hilfe System ist der primäre Ort von dem man up-to-date Informationen
+                darüber erhält was das eigene System in der Lage ist zu tun. Das Hilfe System ist
+                dahingehend dynamisch das Provider dem eigenen System hinzugefügt und
+                automatisch ausgeführt werden, und als solches werden die notwendigen Parameter
+                damit Sie ausgeführt werden können, im Hilfe Schirm vorhanden. Der einfachste Weg um
+                den Hilfe Schirm zu erhalten ist der folgende:
             </para>
 
             <programlisting language="text"><![CDATA[
@@ -125,11 +122,13 @@ zf --help
 ]]></programlisting>
 
             <para>
-                This will give you an overview of the various capabilities of the system.  Sometimes, there
-                are more finite commands than can be run, and to gain more information about these, you might
-                have to run a more specialized help command.  For specialized help, simply replace any of the
-                elements of the command with a "?". This will tell the help system that you want more
-                information about what commands can go in place of the question mark. For example:
+                Das gibt einen Überblick über die verschiedenen Möglichkeiten des Systems. Manchmal
+                gibt es engültigere Kommandos die ausgeführt werden können, und um mehr
+                Informationen über Sie zu erhalten muss man ein spezialisierteres Hilfe Kommando
+                ausführen. Für die spezialisierte Hilfe muss einfach eines der Elemente des
+                Kommandos mit einem "=" ersetzt werden. Das sagt dem Hilfe System das man mehr
+                Informationen darüber will welche Kommandos an Stelle des Fragezeichens stehen
+                können. Zum Beispiel:
             </para>
 
             <programlisting language="text"><![CDATA[
@@ -137,7 +136,8 @@ zf ? controller
 ]]></programlisting>
 
             <para>
-                The above means "show me all 'actions' for the provider 'controller'"; while the following:
+                Das obige bedeutet "zeig mir alle 'Aktionen' für den Provider 'controller'"; wärend
+                das folgende:
             </para>
 
             <programlisting language="text"><![CDATA[
@@ -145,44 +145,40 @@ zf show ?
 ]]></programlisting>
 
             <para>
-                means "show me all providers that support the 'show' action". This works for drilling down
-                into options as well as you can see in the following examples:
+                bedeutet "zeig mit alle Provider welche die 'show' Aktion unterstützen. Das arbeitet
+                auch wenn man in Optionen geht wie man im folgenden Beispiel sehen kann:
             </para>
 
             <programlisting language="text"><![CDATA[
-zf show version.? (show any specialties)
-zf show version ? (show any options)
+zf show version.? (zeige alle Spezialitäten)
+zf show version ? (zeige alle Optionen)
 ]]></programlisting>
-
         </sect3>
 
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.manifest">
             <title>Manifest</title>
 
             <para>
-                This will show what information is in the tooling systems manifest. This is more important
-                for provider developers than casual users of the tooling system.
+                Das zeigt welche Informationen im Tooling System Manifest sind. Das ist wichtiger
+                für Entwickler von Providers als für normale Benutzer des Tooling Systems.
             </para>
 
             <programlisting language="text"><![CDATA[
 zf show manifest
 ]]></programlisting>
-
         </sect3>
 
         <!--
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.tool-configuration">
-            <title>Tool Configuration</title>
-
-            <para>Placeholder   need docs from @beberli </para>
+            <title>Tool Konfiguration</title>
 
+            <para>Platzhalter, benötigt Handbuch von @beberli</para>
         </sect3>
         -->
-
     </sect2>
 
     <sect2 id="zend.tool.usage.cli.project-specific-commands">
-        <title>Project Specific Commands</title>
+        <title>Projekt spezifische Kommandos</title>
 
         <sect3 id="zend.tool.usage.cli.project-specific-commands.project">
             <title>Project</title>

+ 11 - 1
documentation/manual/de/module_specs/Zend_View-Helpers-Doctype.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19436 -->
+<!-- EN-Revision: 19771 -->
 <!-- Reviewed: no -->
 <sect3 id="zend.view.helpers.initial.doctype">
     <title>Doctype Helfer</title>
@@ -84,6 +84,16 @@ if ($view->doctype()->isXhtml()) {
     // etwas anderes machen
 }
 ]]></programlisting>
+
+        <para>
+            Man kann auch prüfen ob der Doctype ein <acronym>HTML5</acronym> Dokument repräsentiert
+        </para>
+
+        <programlisting language="php"><![CDATA[
+if ($view->doctype()->isHtml5()) {
+    // etwas anderes machen
+}
+]]></programlisting>
     </example>
 </sect3>
 <!--

+ 16 - 1
documentation/manual/de/module_specs/Zend_View-Helpers-HeadMeta.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19438 -->
+<!-- EN-Revision: 19771 -->
 <!-- Reviewed: no -->
 <sect3 id="zend.view.helpers.initial.headmeta">
     <title>HeadMeta Helfer</title>
@@ -66,6 +66,12 @@
                 <command>setHttpEquiv($keyValue, $content, $modifiers)</command>
             </para>
         </listitem>
+
+        <listitem>
+            <para>
+                <command>setCharset($charset)</command>
+            </para>
+        </listitem>
     </itemizedlist>
 
     <para>
@@ -146,6 +152,15 @@ $this->headMeta()->appendHttpEquiv('Content-Type',
 ]]></programlisting>
 
         <para>
+            Wenn man ein HTML5 Dokument serviert, sollte man das Character Set wie folgt angeben:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// Das Character Set im HTML5 setzen
+$this->headMeta()->setCharset('UTF-8'); // Sieht aus wie <meta charset="UTF-8">
+]]></programlisting>
+
+        <para>
             Als letztes Beispiel, ein einfacher Weg um eine kurze Nachricht anzuzeigen bevor mit
             Hilfe eines "Meta Refreshes" weitergeleitet wird:
         </para>

+ 21 - 0
documentation/manual/de/tutorials/autoloading-conclusion.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.autoloading.conclusion">
+    <title>Zusammenfassung</title>
+
+    <para>
+        Zend Framework empfiehlt die Verwendung von Autoloading, und initialisiert es standardmäßig
+        sogar in <classname>Zend_Application</classname>. Wir hoffen das dieses Tutorial die
+        benötigten Informationen anbietet damit <classname>Zend_Loader_Autoloader</classname> mit
+        allen Vorteilen die es bietet verwendet werden kann, und damit seine Möglichkeiten erweitert
+        werden können indem eigene Autoloader oder Ressource Autoloader angehängt werden.
+    </para>
+
+    <para>
+        Für weitere Informationen über dessen Verwendung kann in den Seiten von <link
+            linkend="zend.loader.autoloader">Zend_Loader_Autoloader</link> und <link
+            linkend="zend.loader.autoloader-resource">Zend_Loader_Autoloader_Resource</link>
+            im Handbuch nachgelesen werden.
+    </para>
+</sect1>

+ 108 - 0
documentation/manual/de/tutorials/autoloading-design.xml

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.autoloading.design">
+    <title>Ziele und Design</title>
+
+    <sect2 id="learning.autoloading.design.naming">
+        <title>Konventionen für Klassennamen</title>
+
+        <para>
+            Um das Autoloaden im Zend Framework zu verstehen, muss man zuerst die Abhängigkeit
+            zwischen Klassennamen und Klassendateien verstehen.
+        </para>
+
+        <para>
+            Zend Framework hat sich eine Idee von <ulink url="http://pear.php.net/">PEAR</ulink>
+            geborgt wobei Klassennamen eine 1:1 Beziehung zum Dateisystem haben. Einfach gesagt,
+            der Unterstrich ("_") wird durch einen Verzeichnis Separator ersetzt um den Pfad zur
+            Datei aufzulösen, und anschließend wird der Suffix "<filename>.php</filename>"
+            hinzugefügt. Zum Beispiel würde die Klasse "<classname>Foo_Bar_Baz</classname>" mit
+            "<filename>Foo/Bar/Baz.php</filename>" auf dem Dateisystem korrespondieren. Die Annahme
+            ist auch, das die Klassen über <acronym>PHP</acronym>'s
+            <property>include_path</property> Einstellung aufgelöst werden kann, welche es sowohl
+            <methodname>include()</methodname> als auch <methodname>require()</methodname> erlaubt
+            den Dateinamen über einen relativen Pfad Lookup im
+            <property>include_path</property> zu finden.
+        </para>
+
+        <para>
+            Zusätzlich, bei <acronym>PEAR</acronym> wie auch im <ulink
+                url="http://php.net/userlandnaming.tips">PHP Projekt</ulink>, verwenden und
+            empfehlen wir die Verwendung eines Hersteller oder Projekt Präfixes für den eigenen
+            Code. Was das bedeutet ist, dass alle Klassen die man schreibt den gleichen gemeinsamen
+            Klassenpräfix teilen; zum Beispiel hat jeder Code im Zend Framework den Präfix "Zend_".
+            Diese Namenskonvention hilft Namenskollisionen zu verhindern. Im Zend Framework
+            referieren wir hierzu oft als "Namespace" Präfix; man sollte darauf achten das man dies
+            nicht mit <acronym>PHP</acronym>'s nativer Namespace Implementation verwechselt.
+        </para>
+
+        <para>
+            Zend Framework folgt diesen einfachen Regeln intern, und unser Coding Standard empfiehlt
+            dass man dies in jedem Bibliotheks Code macht.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.autoloading.design.autoloader">
+        <title>Autoloader Konventionen und Design</title>
+
+        <para>
+            Zend Framework's unterstützung für das Autoloaden, welche primär über
+            <classname>Zend_Loader_Autoloader</classname> angeboten wird, hat die folgenden Ziele
+            und Design Elemente:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis>Namespace Abgleich anbieten</emphasis>: Wenn der Namespace Präfix der
+                    Klasse nicht in der Liste der registrierten Namespaces ist, wird sofort false
+                    zurückgegeben. Das erlaubt es einen optimistischeren Abgleich anzubieten, sowie
+                    als Fallback für andere Autoloader zu fungieren.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Erlaubt dem Autoloader als Fallback Autoloader zu arbeiten</emphasis>:
+                    Im Falle das ein Team sehr weit verbreitet ist, oder ein unbekanntes Set von
+                    Namespace Präfixes verwendet, sollte der Autoloader trotzdem konfigurierbar sein
+                    damit er versucht jedem Namespace Präfix zu entsprechen. Es sollte trotzdem
+                    erwähnt werden das diese Praxis nicht empfohlen wird, da Sie auch zu unnötigen
+                    Lookups führt.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Erlaubt es Fehlerunterdrückung zu wechseln</emphasis>: Wir denken --
+                    und die größere <acronym>PHP</acronym> Community tut das auch -- dass die
+                    Fehlerunterdrückung eine schlechte Idee ist. Sie ist teuer, und maskiert die
+                    rechten Probleme der Anwendung. Deswegen sollte sie standardmäßig ausgeschaltet
+                    sein. Trotzdem, wenn ein Entwickler darauf <emphasis>besteht</emphasis> das Sie
+                    eingeschaltet wenn soll, erlauben wir es Sie einzuschalten.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Erlaubt spezielle eigene Callbacks für Autoloading</emphasis>:
+                    Einige Entwickler wollen <methodname>Zend_Loader::loadClass()</methodname> für
+                    das Autoloaden nicht, aber trotzdem Zend Framework's Mechanismus hierfür
+                    verwenden. <classname>Zend_Loader_Autoloader</classname> erlaubt es einen
+                    alternativen Callback für das Autoloaden zu spezifizieren.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Erlaubt die Manipulation der Autload Callback Kette von
+                    <acronym>SPL</acronym></emphasis>: Der Zweck hiervon ist es die Spezifikation
+                    von zusätzlichen Autoloadern zu verwenden -- zum Beispiel müssen Ressource Lader
+                    für Klassen keine 1:1 Entsprechung zum Dateisystem haben -- und Sie vor oder
+                    nach dem primären Zend Framework Autoloader zu registrieren.
+                </para>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+</sect1>

+ 35 - 0
documentation/manual/de/tutorials/autoloading-intro.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.autoloading.intro">
+    <title>Einführung</title>
+
+    <para>
+        Autoloading ist ein Mechanismus welcher die Notwendigkeit den Aufrufs von "require" im
+        eigenen <acronym>PHP</acronym> Code eliminiert. Laut <ulink
+            url="http://php.net/autoload">dem PHP Manual für Autoload</ulink> wird ein Autoloader,
+        sobald er definiert wurde, "automatisch aufgerufen im Fall das versucht wird auf eine Klasse
+        oder ein Interface zuzugreifen welche bis zu diesem Zeitpunkt noch nicht definiert wurde.
+    </para>
+
+    <para>
+        Bei Verwendung eines Autoloaders muss man sich keine Gedanken darüber machen
+        <emphasis>wo</emphasis> eine Klasse im eigenen Projekt existiert. Mit gut-definierten
+        Autoloadern muss man sich keine Gedanken darüber machen wo eine Klassendatei relativ zu
+        einer aktuellen Klassendatei ist; man verwendet einfach die Klasse, und der Autoloader führt
+        eine Dateisuche durch.
+    </para>
+
+    <para>
+        Zusätzlich, weil Autoloading dazu führt das man im letzten möglichen Moment lädt und
+        sicherstellt das ein Match nur einmal stattfindet, kann eine große Steigerung der
+        Geschwindigkeit stattfinden -- speziell wenn man sich die Zeit nimmt die Aufrufe zu
+        <methodname>require_once()</methodname> zu entfernen bevor man den Livebetrieb aufnimmt.
+    </para>
+
+    <para>
+        Zend Framework empfiehlt die Verwendung von Autoloaden, und bietet verschiedene Tools um das
+        Autoloading für beide zu unterstützen, sowohl Bibliothekscode als auch Anwendungscode.
+        Das Tutorial zeigt diese Tools und auch wie man Sie effektiv verwendet.
+    </para>
+</sect1>

+ 109 - 0
documentation/manual/de/tutorials/autoloading-resources.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.autoloading.resources">
+    <title>Resource Autoloading</title>
+
+    <para>
+        Often, when developing an application, it's either difficult to package classes in the 1:1
+        classname:filename standard Zend Framework recommends, or it's advantageous for purposes of
+        packaging not to do so. However, this means you class files will not be found by the
+        autoloader.
+    </para>
+
+    <para>
+        If you read through <link linkend="learning.autoloading.design">the design goals</link> for
+        the autoloader, the last point in that section indicated that the solution should cover this
+        situation. Zend Framework does so with
+        <classname>Zend_Loader_Autoloader_Resource</classname>.
+    </para>
+
+    <para>
+        A resource is just a name that corresponds to a component namespace (which
+        is appended to the autoloader's namespace) and a path (which is relative to
+        the autoloader's base path). In action, you'd do something like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$loader = new Zend_Application_Module_Autoloader(array(
+    'namespace' => 'Blog',
+    'basePath'  => APPLICATION_PATH . '/modules/blog',
+));
+]]></programlisting>
+
+    <para>
+        Once you have the loader in place, you then need to inform it of the various resource types
+        it's aware of. These resource types are simply pairs of subtree and prefix.
+    </para>
+
+    <para>
+        As an example, consider the following tree:
+    </para>
+
+    <programlisting language="text"><![CDATA[
+path/to/some/resources/
+|-- forms/
+|   `-- Guestbook.php        // Foo_Form_Guestbook
+|-- models/
+|   |-- DbTable/
+|   |   `-- Guestbook.php    // Foo_Model_DbTable_Guestbook
+|   |-- Guestbook.php        // Foo_Model_Guestbook
+|   `-- GuestbookMapper.php  // Foo_Model_GuestbookMapper
+]]></programlisting>
+
+    <para>
+        Our first step is creating the resource loader:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$loader = new Zend_Loader_Autoloader_Resource(array(
+    'basePath'  => 'path/to/some/resources/',
+    'namespace' => 'Foo',
+));
+]]></programlisting>
+
+    <para>
+        Next, we need to define some resource types.
+        <methodname>Zend_Loader_Autoloader_Resourse::addResourceType()</methodname> has three
+        arguments: the "type" of resource (an arbitrary string), the path under the base path in
+        which the resource type may be found, and the component prefix to use for the resource type.
+        In the above tree, we have three resource types: form (in the subdirectory "forms", with a
+        component prefix of "Form"), model (in the subdirectory "models", with a component prefix of
+        "Model"), and dbtable (in the subdirectory "<filename>models/DbTable</filename>",
+        with a component prefix of "<classname>Model_DbTable</classname>"). We'd define them as
+        follows:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$loader->addResourceType('form', 'forms', 'Form')
+       ->addResourceType('model', 'models', 'Model')
+       ->addResourceType('dbtable', 'models/DbTable', 'Model_DbTable');
+]]></programlisting>
+
+    <para>
+        Once defined, we can simply use these classes:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$form      = new Foo_Form_Guestbook();
+$guestbook = new Foo_Model_Guestbook();
+]]></programlisting>
+
+    <note>
+        <title>Module Resource Autoloading</title>
+
+        <para>
+            Zend Framework's <acronym>MVC</acronym> layer encourages the use of "modules", which
+            are self-contained applications within your site. Modules typically have a number of
+            resource types by default, and Zend Framework even
+            <link linkend="project-structure.filesystem">recommends a standard directory layout
+                for modules</link>. Resource autoloaders are therefore
+            quite useful in this paradigm -- so useful that they are enabled by default when you
+            create a bootstrap class for your module that extends
+            <classname>Zend_Application_Module_Bootstrap</classname>. For more information, read
+            the <link
+                linkend="zend.loader.autoloader-resource.module">Zend_Loader_Autoloader_Module
+                documentation</link>.
+        </para>
+    </note>
+</sect1>

+ 160 - 0
documentation/manual/de/tutorials/autoloading-usage.xml

@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.autoloading.usage">
+    <title>Grundsätzliche Verwendung von Autoloadern</title>
+
+    <para>
+        Now that we have an understanding of what autoloading is and the goals and design of Zend
+        Framework's autoloading solution, let's look at how to use
+        <classname>Zend_Loader_Autoloader</classname>.
+    </para>
+
+    <para>
+        In the simplest case, you would simply require the class, and then instantiate it. Since
+        <classname>Zend_Loader_Autoloader</classname> is a singleton (due to the fact that the
+        <acronym>SPL</acronym> autoloader is a single resource), we use
+        <methodname>getInstance()</methodname> to retrieve an instance.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+require_once 'Zend/Loader/Autoloader.php';
+Zend_Loader_Autoloader::getInstance();
+]]></programlisting>
+
+    <para>
+        By default, this will allow loading any classes with the class namespace prefixes of "Zend_"
+        or "ZendX_", as long as they are on your <property>include_path</property>.
+    </para>
+
+    <para>
+        What happens if you have other namespace prefixes you wish to use? The best, and simplest,
+        way is to call the <methodname>registerNamespace()</methodname> method on the instance. You
+        can pass a single namespace prefix, or an array of them:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+require_once 'Zend/Loader/Autoloader.php';
+$loader = Zend_Loader_Autoloader::getInstance();
+$loader->registerNamespace('Foo_');
+$loader->registerNamespace(array('Foo_', 'Bar_'));
+]]></programlisting>
+
+    <para>
+        Alternately, you can tell <classname>Zend_Loader_Autoloader</classname> to act as a
+        "fallback" autoloader. This means that it will try to resolve any class regardless of
+        namespace prefix.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$loader->setFallbackAutoloader(true);
+]]></programlisting>
+
+    <warning>
+        <title>Do not use as a fallback autoloader</title>
+
+        <para>
+            While it's tempting to use <classname>Zend_Loader_Autoloader</classname> as a fallback
+            autoloader, we do not recommend the practice.
+        </para>
+
+        <para>
+            Internally, <classname>Zend_Loader_Autoloader</classname> uses
+            <methodname>Zend_Loader::loadClass()</methodname> to load classes. That method uses
+            <methodname>include()</methodname> to attempt to load the given class file.
+            <methodname>include()</methodname> will return a boolean <constant>FALSE</constant>
+            if not successful -- but also issues a <acronym>PHP</acronym> warning. This latter
+            fact can lead to some issues:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    If <property>display_errors</property> is enabled, the warning will be included
+                    in output.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Depending on the <property>error_reporting</property> level you have chosen, it
+                    could also clutter your logs.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            You can suppress the error messages (the <classname>Zend_Loader_Autoloader</classname>
+            documentation details this), but note that the suppression is only relevant when
+            <property>display_errors</property> is enabled; the error log will always display the
+            messages. For these reasons, we recommend always configuring the namespace prefixes the
+            autoloader should be aware of
+        </para>
+    </warning>
+
+    <note>
+        <title>Namespace Prefixes vs PHP Namespaces</title>
+
+        <para>
+            At the time this is written, <acronym>PHP</acronym> 5.3 has been released. With that
+            version, <acronym>PHP</acronym> now has official namespace support.
+        </para>
+
+        <para>
+            However, Zend Framework predates <acronym>PHP</acronym> 5.3, and thus namespaces.
+            Within Zend Framework, when we refer to "namespaces", we are referring to a practice
+            whereby classes are prefixed with a vender "namespace". As an example, all Zend
+            Framework class names are prefixed with "Zend_" -- that is our vendor "namespace".
+        </para>
+
+        <para>
+            Zend Framework plans to offer native <acronym>PHP</acronym> namespace support to the
+            autoloader in future revisions, and its own library will utilize namespaces starting
+            with version 2.0.0.
+        </para>
+    </note>
+
+    <para>
+        If you have a custom autoloader you wish to use with Zend Framework -- perhaps an autoloader
+        from a third-party library you are also using -- you can manage it with
+        <classname>Zend_Loader_Autoloader</classname>'s <methodname>pushAutoloader()</methodname>
+        and <methodname>unshiftAutoloader()</methodname> methods. These methods will append or
+        prepend, respectively, autoloaders to a chain that is called prior to executing Zend
+        Framework's internal autoloading mechanism. This approach offers the following benefits:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                Each method takes an optional second argument, a class namespace prefix. This can be
+                used to indicate that the given autoloader should only be used when looking up
+                classes with that given class prefix. If the class being resolved does not have that
+                prefix, the autoloader will be skipped -- which can lead to performance
+                improvements.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                If you need to manipulate <methodname>spl_autoload()</methodname>'s registry, any
+                autoloaders that are callbacks pointing to instance methods can pose issues, as
+                <methodname>spl_autoload_functions()</methodname> does not return the exact same
+                callbacks. <classname>Zend_Loader_Autoloader</classname> has no such limitation.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Autoloaders managed this way may be any valid <acronym>PHP</acronym> callback.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// Append function 'my_autoloader' to the stack,
+// to manage classes with the prefix 'My_':
+$loader->pushAutoloader('my_autoloader', 'My_');
+
+// Prepend static method Foo_Loader::autoload() to the stack,
+// to manage classes with the prefix 'Foo_':
+$loader->unshiftAutoloader(array('Foo_Loader', 'autoload'), 'Foo_');
+]]></programlisting>
+</sect1>

+ 385 - 0
documentation/manual/de/tutorials/form-decorators-composite.xml

@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.composite">
+    <title>Creating and Rendering Composite Elements</title>
+
+    <para>
+        In <link linkend="learning.form.decorators.individual">the last section</link>, we had an
+        example showing a "date of birth element":
+    </para>
+
+
+    <programlisting language="php"><![CDATA[
+<div class="element">
+    <?php echo $form->dateOfBirth->renderLabel() ?>
+    <?php echo $this->formText('dateOfBirth[day]', '', array(
+        'size' => 2, 'maxlength' => 2)) ?>
+    /
+    <?php echo $this->formText('dateOfBirth[month]', '', array(
+        'size' => 2, 'maxlength' => 2)) ?>
+    /
+    <?php echo $this->formText('dateOfBirth[year]', '', array(
+        'size' => 4, 'maxlength' => 4)) ?>
+</div>
+]]></programlisting>
+
+    <para>
+        How might you represent this element as a <classname>Zend_Form_Element</classname>?
+        How might you write a decorator to render it?
+    </para>
+
+    <sect2 id="learning.form.decorators.composite.element">
+        <title>The Element</title>
+
+        <para>
+            The questions about how the element would work include:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    How would you set and retrieve the value?
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    How would you validate the value?
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Regardless, how would you then allow for discrete form inputs for the three
+                    segments (day, month, year)?
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            The first two questions center around the form element itself: how would
+            <methodname>setValue()</methodname> and <methodname>getValue()</methodname> work?
+            There's actually another question implied by the question about the decorator: how would
+            you retrieve the discrete date segments from the element and/or set them?
+        </para>
+
+        <para>
+            The solution is to override the <methodname>setValue()</methodname> method of your
+            element to provide some custom logic. In this particular case, our element should have
+            three discrete behaviors:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    If an integer timestamp is provided, it should be used to determine and store
+                    the day, month, and year.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    If a textual string is provided, it should be cast to a timestamp, and then that
+                    value used to determine and store the day, month, and year.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    If an array containing keys for date, month, and year is provided, those values
+                    should be stored.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Internally, the day, month, and year will be stored discretely. When the value of the
+            element is retrieved, it will be done so in a normalized string format. We'll override
+            <methodname>getValue()</methodname> as well to assemble the discrete date segments into
+            a final string.
+        </para>
+
+        <para>
+            Here's what the class would look like:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class My_Form_Element_Date extends Zend_Form_Element_Xhtml
+{
+    protected $_dateFormat = '%year%-%month%-%day%';
+    protected $_day;
+    protected $_month;
+    protected $_year;
+
+    public function setDay($value)
+    {
+        $this->_day = (int) $value;
+        return $this;
+    }
+
+    public function getDay()
+    {
+        return $this->_day;
+    }
+
+    public function setMonth($value)
+    {
+        $this->_month = (int) $value;
+        return $this;
+    }
+
+    public function getMonth()
+    {
+        return $this->_month;
+    }
+
+    public function setYear($value)
+    {
+        $this->_year = (int) $value;
+        return $this;
+    }
+
+    public function getYear()
+    {
+        return $this->_year;
+    }
+
+    public function setValue($value)
+    {
+        if (is_int($value)) {
+            $this->setDay(date('d', $value))
+                 ->setMonth(date('m', $value))
+                 ->setYear(date('Y', $value));
+        } elseif (is_string($value)) {
+            $date = strtotime($value);
+            $this->setDay(date('d', $date))
+                 ->setMonth(date('m', $date))
+                 ->setYear(date('Y', $date));
+        } elseif (is_array($value)
+                  && (isset($value['day'])
+                      && isset($value['month'])
+                      && isset($value['year'])
+                  )
+        ) {
+            $this->setDay($value['day'])
+                 ->setMonth($value['month'])
+                 ->setYear($value['year']);
+        } else {
+            throw new Exception('Invalid date value provided');
+        }
+
+        return $this;
+    }
+
+    public function getValue()
+    {
+        return str_replace(
+            array('%year%', '%month%', '%day%'),
+            array($this->getYear(), $this->getMonth(), $this->getDay()),
+            $this->_dateFormat
+        );
+    }
+}
+]]></programlisting>
+
+        <para>
+            This class gives some nice flexibility -- we can set default values from our database, and
+            be certain that the value will be stored and represented correctly.  Additionally, we can
+            allow for the value to be set from an array passed via form input. Finally, we have discrete
+            accessors for each date segment, which we can now use in a decorator to create a composite
+            element.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.form.decorators.composite.decorator">
+        <title>The Decorator</title>
+
+        <para>
+            Revisiting the example from the last section, let's assume that we want users to input
+            each of the year, month, and day separately. PHP fortunately allows us to use array
+            notation when creating elements, so it's still possible to capture these three entities
+            into a single value -- and we've now created a <classname>Zend_Form</classname> element
+            that can handle such an array value.
+        </para>
+
+        <para>
+            The decorator is relatively simple: it will grab the day, month, and year from the
+            element, and pass each to a discrete view helper to render individual form inputs; these
+            will then be aggregated to form the final markup.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class My_Form_Decorator_Date extends Zend_Form_Decorator_Abstract
+{
+    public function render($content)
+    {
+        $element = $this->getElement();
+        if (!$element instanceof My_Form_Element_Date) {
+            // only want to render Date elements
+            return $content;
+        }
+
+        $view = $element->getView();
+        if (!$view instanceof Zend_View_Interface) {
+            // using view helpers, so do nothing if no view present
+            return $content;
+        }
+
+        $day   = $element->getDay();
+        $month = $element->getMonth();
+        $year  = $element->getYear();
+        $name  = $element->getFullyQualifiedName();
+
+        $params = array(
+            'size'      => 2,
+            'maxlength' => 2,
+        );
+        $yearParams = array(
+            'size'      => 4,
+            'maxlength' => 4,
+        );
+
+        $markup = $view->formText($name . '[day]', $day, $params)
+                . ' / ' . $view->formText($name . '[month]', $month, $params)
+                . ' / ' . $view->formText($name . '[year]', $year, $yearParams);
+
+        switch ($this->getPlacement()) {
+            case self::PREPEND:
+                return $markup . $this->getSeparator() . $content;
+            case self::APPEND:
+            default:
+                return $content . $this->getSeparator() . $markup;
+        }
+    }
+}
+]]></programlisting>
+
+    <para>
+        We now have to do a minor tweak to our form element, and tell it that we want to use the
+        above decorator as a default. That takes two steps. First, we need to inform the element of
+        the decorator path. We can do that in the constructor:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Form_Element_Date extends Zend_Form_Element_Xhtml
+{
+    // ...
+
+    public function __construct($spec, $options = null)
+    {
+        $this->addPrefixPath(
+            'My_Form_Decorator',
+            'My/Form/Decorator',
+            'decorator'
+        );
+        parent::__construct($spec, $options);
+    }
+
+    // ...
+}
+]]></programlisting>
+
+    <para>
+        Note that this is being done in the constructor and not in <methodname>init()</methodname>.
+        This is for two reasons. First, it allows extending the element later to add logic in
+        <methodname>init</methodname> without needing to worry about calling
+        <methodname>parent::init()</methodname>. Second, it allows passing additional plugin paths
+        via configuration or within an <methodname>init</methodname> method that will then allow
+        overriding the default <classname>Date</classname> decorator with my own replacement.
+    </para>
+
+    <para>
+        Next, we need to override the <methodname>loadDefaultDecorators()</methodname> method to use
+        our new <classname>Date</classname> decorator:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Form_Element_Date extends Zend_Form_Element_Xhtml
+{
+    // ...
+
+    public function loadDefaultDecorators()
+    {
+        if ($this->loadDefaultDecoratorsIsDisabled()) {
+            return;
+        }
+
+        $decorators = $this->getDecorators();
+        if (empty($decorators)) {
+            $this->addDecorator('Date')
+                 ->addDecorator('Errors')
+                 ->addDecorator('Description', array(
+                     'tag'   => 'p',
+                     'class' => 'description'
+                 ))
+                 ->addDecorator('HtmlTag', array(
+                     'tag' => 'dd',
+                     'id'  => $this->getName() . '-element'
+                 ))
+                 ->addDecorator('Label', array('tag' => 'dt'));
+        }
+    }
+
+    // ...
+}
+]]></programlisting>
+
+    <para>
+        What does the final output look like? Let's consider the following element:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$d = new My_Form_Element_Date('dateOfBirth');
+$d->setLabel('Date of Birth: ')
+  ->setView(new Zend_View());
+
+// These are equivalent:
+$d->setValue('20 April 2009');
+$d->setValue(array('year' => '2009', 'month' => '04', 'day' => '20'));
+]]></programlisting>
+
+    <para>
+        If you then echo this element, you get the following markup (with some slight whitespace
+        modifications for readability):
+    </para>
+
+    <programlisting language="html"><![CDATA[
+<dt id="dateOfBirth-label"><label for="dateOfBirth" class="optional">
+    Date of Birth:
+</label></dt>
+<dd id="dateOfBirth-element">
+    <input type="text" name="dateOfBirth[day]" id="dateOfBirth-day"
+        value="20" size="2" maxlength="2"> /
+    <input type="text" name="dateOfBirth[month]" id="dateOfBirth-month"
+        value="4" size="2" maxlength="2"> /
+    <input type="text" name="dateOfBirth[year]" id="dateOfBirth-year"
+        value="2009" size="4" maxlength="4">
+</dd>
+]]></programlisting>
+    </sect2>
+
+    <sect2 id="learning.form.decorators.composite.conclusion">
+        <title>Conclusion</title>
+
+        <para>
+            We now have an element that can render multiple related form input fields, and then
+            handle the aggregated fields as a single entity -- the <varname>dateOfBirth</varname>
+            element will be passed as an array to the element, and the element will then, as we
+            noted earlier, create the appropriate date segments and return a value we can use for
+            most backends.
+        </para>
+
+        <para>
+            Additionally, we can use different decorators with the element. If we wanted to use a
+            <ulink url="http://dojotoolkit.org/">Dojo</ulink> <classname>DateTextBox</classname>
+            dijit decorator -- which accepts and returns string values -- we can, with no
+            modifications to the element itself.
+        </para>
+
+        <para>
+            In the end, you get a uniform element API you can use to describe an element
+            representing a composite value.
+        </para>
+    </sect2>
+</sect1>

+ 13 - 0
documentation/manual/de/tutorials/form-decorators-conclusion.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.conclusion">
+    <title>Fazit</title>
+
+    <para>
+        Formular Dekoratore sind ein System welches einige Zeit in Anspruch nimmt um es zu lernen.
+        Zuerst fühlt es sich mühsam und überaus komplex an. Hoffentlich helfen die verschiedenen
+        Themen die in diesem Kapitel beschrieben sind wie beide arbeiten, sowie Strategien für
+        deren effektive Verwendung in eigenen Formularen.
+    </para>
+</sect1>

+ 284 - 0
documentation/manual/de/tutorials/form-decorators-individual.xml

@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.individual">
+    <title>Rendering Individual Decorators</title>
+
+    <para>
+        In the <link linkend="learning.form.decorators.layering">previous section</link>, we
+        looked at how you can combine decorators to create complex output. We noted that while you
+        have a ton of flexibility with this approach, it also adds some complexity and overhead. In
+        this section, we will examine how to render decorators individually in order to create
+        custom markup for forms and/or individual elements.
+    </para>
+
+    <para>
+        Once you have registered your decorators, you can later retrieve them by name from the
+        element. Let's review the previous example:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$element = new Zend_Form_Element('foo', array(
+    'label'      => 'Foo',
+    'belongsTo'  => 'bar',
+    'value'      => 'test',
+    'prefixPath' => array('decorator' => array(
+        'My_Decorator' => 'path/to/decorators/',
+    )),
+    'decorators' => array(
+        'SimpleInput'
+        array('SimpleLabel', array('placement' => 'append')),
+    ),
+));
+]]></programlisting>
+
+    <para>
+        If we wanted to pull and render just the <classname>SimpleInput</classname> decorator, we
+        can do so using the <methodname>getDecorator()</methodname> method:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$decorator = $element->getDecorator('SimpleInput');
+echo $decorator->render('');
+]]></programlisting>
+
+    <para>
+        This is pretty easy, but it can be made even easier; let's do it in a single line:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+echo $element->getDecorator('SimpleInput')->render('');
+]]></programlisting>
+
+    <para>
+        Not too bad, but still a little complex. To make this easier, a shorthand notation was
+        introduced into <classname>Zend_Form</classname> in 1.7: you can render any registered
+        decorator by calling a method of the format <methodname>renderDecoratorName()</methodname>.
+        This will effectively perform what you see above, but makes the <varname>$content</varname>
+        argument optional and simplifies the usage:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+echo $element->renderSimpleInput();
+]]></programlisting>
+
+    <para>
+        This is a neat trick, but how and why would you use it?
+    </para>
+
+    <para>
+        Many developers and designers have very precise markup needs for their forms. They would
+        rather have full control over the output than rely on a more automated solution which may or
+        may not conform to their design. In other cases, the form layout may require a lot of
+        specialized markup -- grouping arbitrary elements, making some invisible unless a particular
+        link is selected, etc.
+    </para>
+
+    <para>
+        Let's utilize the ability to render individual decorators to create some specialized markup.
+    </para>
+
+    <para>
+        First, let's define a form. Our form will capture a user's demographic details. The markup
+        will be highly customized, and in some cases use view helpers directly instead of form
+        elements in order to achieve its goals.  Here is the basic form definition:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Form_UserDemographics extends Zend_Form
+{
+    public function init()
+    {
+        // Add a path for my own decorators
+        $this->addElementPrefixPaths(array(
+            'decorator' => array('My_Decorator' => 'My/Decorator'),
+        ));
+
+        $this->addElement('text', 'firstName', array(
+            'label' => 'First name: ',
+        ));
+        $this->addElement('text', 'lastName', array(
+            'label' => 'Last name: ',
+        ));
+        $this->addElement('text', 'title', array(
+            'label' => 'Title: ',
+        ));
+        $this->addElement('text', 'dateOfBirth', array(
+            'label' => 'Date of Birth (DD/MM/YYYY): ',
+        ));
+        $this->addElement('text', 'email', array(
+            'label' => 'Your email address: ',
+        ));
+        $this->addElement('password', 'password', array(
+            'label' => 'Password: ',
+        ));
+        $this->addElement('password', 'passwordConfirmation', array(
+            'label' => 'Confirm Password: ',
+        ));
+    }
+}
+]]></programlisting>
+
+    <note>
+        <para>
+            We're not defining any validators or filters at this time, as they are not relevant to
+            the discussion of decoration. In a real-world scenario, you should define them.
+        </para>
+    </note>
+
+    <para>
+        With that out of the way, let's consider how we might want to display this form. One common
+        idiom with first/last names is to display them on a single line; when a title is provided,
+        that is often on the same line as well.  Dates, when not using a JavaScript date chooser,
+        will often be separated into three fields displayed side by side.
+    </para>
+
+    <para>
+        Let's use the ability to render an element's decorators one by one to accomplish this.
+        First, let's note that no explicit decorators were defined for the given elements. As a
+        refresher, the default decorators for (most) elements are:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                <classname>ViewHelper</classname>: utilize a view helper to render a form input
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Errors</classname>: utilize the <classname>FormErrors</classname> view
+                helper to render validation errors
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Description</classname>: utilize the <classname>FormNote</classname> view
+                helper to render the element description (if any)
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>HtmlTag</classname>: wrap the above three items in a
+                <code>&lt;dd&gt;</code> tag
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Label</classname>: render the element label using the
+                <classname>FormLabel</classname> view helper (and wrap it in a
+                <code>&lt;dt&gt;</code> tag)
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Also, as a refresher, you can access any element of a form as if it were a class property;
+        simply reference the element by the name you assigned it.
+    </para>
+
+    <para>
+        Our view script might then look like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<?php
+$form = $this->form;
+// Remove <dt> from label generation
+foreach ($form->getElements() as $element) {
+    $element->getDecorator('label')->setOption('tag', null);
+}
+?>
+<form method="<?php echo $form->getMethod() ?>" action="<?php echo
+    $form->getAction()?>">
+    <div class="element">
+        <?php echo $form->title->renderLabel()
+              . $form->title->renderViewHelper() ?>
+        <?php echo $form->firstName->renderLabel()
+              . $form->firstName->renderViewHelper() ?>
+        <?php echo $form->lastName->renderLabel()
+              . $form->lastName->renderViewHelper() ?>
+    </div>
+    <div class="element">
+        <?php echo $form->dateOfBirth->renderLabel() ?>
+        <?php echo $this->formText('dateOfBirth['day']', '', array(
+            'size' => 2, 'maxlength' => 2)) ?>
+        /
+        <?php echo $this->formText('dateOfBirth['month']', '', array(
+            'size' => 2, 'maxlength' => 2)) ?>
+        /
+        <?php echo $this->formText('dateOfBirth['year']', '', array(
+            'size' => 4, 'maxlength' => 4)) ?>
+    </div>
+    <div class="element">
+        <?php echo $form->password->renderLabel()
+              . $form->password->renderViewHelper() ?>
+    </div>
+    <div class="element">
+        <?php echo $form->passwordConfirmation->renderLabel()
+              . $form->passwordConfirmation->renderViewHelper() ?>
+    </div>
+    <?php echo $this->formSubmit('submit', 'Save') ?>
+</form>
+]]></programlisting>
+
+    <para>
+        If you use the above view script, you'll get approximately the following HTML (approximate,
+        as the HTML below is formatted):
+    </para>
+
+    <programlisting language="html"><![CDATA[
+<form method="post" action="">
+    <div class="element">
+        <label for="title" tag="" class="optional">Title:</label>
+        <input type="text" name="title" id="title" value=""/>
+
+        <label for="firstName" tag="" class="optional">First name:</label>
+        <input type="text" name="firstName" id="firstName" value=""/>
+
+        <label for="lastName" tag="" class="optional">Last name:</label>
+        <input type="text" name="lastName" id="lastName" value=""/>
+    </div>
+
+    <div class="element">
+        <label for="dateOfBirth" tag="" class="optional">Date of Birth
+            (DD/MM/YYYY):</label>
+        <input type="text" name="dateOfBirth[day]" id="dateOfBirth-day"
+            value="" size="2" maxlength="2"/>
+        /
+        <input type="text" name="dateOfBirth[month]" id="dateOfBirth-month"
+            value="" size="2" maxlength="2"/>
+        /
+        <input type="text" name="dateOfBirth[year]" id="dateOfBirth-year"
+            value="" size="4" maxlength="4"/>
+    </div>
+
+    <div class="element">
+        <label for="password" tag="" class="optional">Password:</label>
+        <input type="password" name="password" id="password" value=""/>
+    </div>
+
+    <div class="element">
+        <label for="passwordConfirmation" tag="" class="" id="submit"
+            value="Save"/>
+</form>
+]]></programlisting>
+
+    <para>
+        It may not be truly pretty, but with some CSS, it could be made to look exactly how you
+        might want to see it. The main point, however, is that this form was generated using almost
+        entirely custom markup, while still leveraging decorators for the most common markup (and to
+        ensure things like escaping with htmlentities and value injection occur).
+    </para>
+
+    <para>
+        By this point in the tutorial, you should be getting fairly comfortable with the markup
+        possibilities using <classname>Zend_Form</classname>'s decorators. In the next section, we'll
+        revisit the date element from above, and demonstrate how to create a custom element
+        and decorator for composite elements.
+    </para>
+</sect1>

+ 24 - 0
documentation/manual/de/tutorials/form-decorators-intro.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.intro">
+    <title>Einführung</title>
+
+    <para>
+        <link linkend="zend.form">Zend_Form</link> verwendet das <emphasis>Decorator</emphasis>
+        Pattern um Elemente und Formulare darzustellen. Anders als das klassische <ulink
+            url="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator Pattern</ulink>, dem man
+        ein Objekt übergibt um eine Klasse zu umhüllen, implementieren die Decorators in
+        <classname>Zend_Form</classname> ein <ulink
+            url="http://en.wikipedia.org/wiki/Strategy_pattern">Strategy Pattern</ulink>, und
+        verwenden die Metadaten welche in einem Element oder Formular enthalten sind um eine
+        Repräsenation von Ihm zu erstellen.
+    </para>
+
+    <para>
+        Man sollte sich von der Ausdrucksweise nicht erschrecken lassen. Trotzdem, im Herzen sind
+        Decorators in <classname>Zend_Form</classname> schrecklich einfach, und das nachfolgende
+        Mini-Tutorial sollte helfen damit zurecht zu kommen. Es führt durch die Grundsätze der
+        Decoration, den ganzen Weg für die Erstellung von Decorators für kombinierte Elemente.
+    </para>
+</sect1>

+ 363 - 0
documentation/manual/de/tutorials/form-decorators-layering.xml

@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.layering">
+    <title>Layering Decorators</title>
+
+    <para>
+        If you were following closely in <link linkend="learning.form.decorators.simplest">the
+            previous section</link>, you may have noticed that a decorator's
+        <methodname>render()</methodname> method takes a single argument,
+        <varname>$content</varname>. This is expected to be a string.
+        <methodname>render()</methodname> will then take this string and decide to either replace
+        it, append to it, or prepend it. This allows you to have a chain of decorators -- which
+        allows you to create decorators that render only a subset of the element's metadata, and
+        then layer these decorators to build the full markup for the element.
+    </para>
+
+    <para>
+        Let's look at how this works in practice.
+    </para>
+
+    <para>
+        For most form element types, the following decorators are used:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                <classname>ViewHelper</classname> (render the form input using one of the standard
+                form view helpers).
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Errors</classname> (render validation errors via an unordered list).
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Description</classname> (render any description attached to the element;
+                often used for tooltips).
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>HtmlTag</classname> (wrap all of the above in a <code>&lt;dd&gt;</code>
+                tag.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Label</classname> (render the label preceding the above, wrapped in a
+                <code>&lt;dt&gt;</code> tag.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        You'll notice that each of these decorators does just one thing, and operates on one
+        specific piece of metadata stored in the form element: the <classname>Errors</classname>
+        decorator pulls validation errors and renders them; the <classname>Label</classname>
+        decorator pulls just the label and renders it. This allows the individual decorators to be
+        very succinct, repeatable, and, more importantly, testable.
+    </para>
+
+    <para>
+        It's also where that <varname>$content</varname> argument comes into play: each decorator's
+        <methodname>render()</methodname> method is designed to accept content, and then either
+        replace it (usually by wrapping it), prepend to it, or append to it.
+    </para>
+
+    <para>
+        So, it's best to think of the process of decoration as one of building an onion from the
+        inside out.
+    </para>
+
+    <para>
+        To simplify the process, we'll take a look at the example from <link
+            linkend="learning.form.decorators.simplest">the previous section</link>. Recall:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Decorator_SimpleInput extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<label for="%s">%s</label>'
+                       . '<input id="%s" name="%s" type="text" value="%s"/>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $name    = htmlentities($element->getFullyQualifiedName());
+        $label   = htmlentities($element->getLabel());
+        $id      = htmlentities($element->getId());
+        $value   = htmlentities($element->getValue());
+
+        $markup  = sprintf($this->_format, $id, $label, $id, $name, $value);
+        return $markup;
+    }
+}
+]]></programlisting>
+
+    <para>
+        Let's now remove the label functionality, and build a separate decorator for that.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Decorator_SimpleInput extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<input id="%s" name="%s" type="text" value="%s"/>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $name    = htmlentities($element->getFullyQualifiedName());
+        $id      = htmlentities($element->getId());
+        $value   = htmlentities($element->getValue());
+
+        $markup  = sprintf($this->_format, $id, $name, $value);
+        return $markup;
+    }
+}
+
+class My_Decorator_SimpleLabel extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<label for="%s">%s</label>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $id      = htmlentities($element->getId());
+        $label   = htmlentities($element->getLabel());
+
+        $markup = sprint($this->_format, $id, $label);
+        return $markup;
+    }
+}
+]]></programlisting>
+
+    <para>
+        Now, this may look all well and good, but here's the problem: as written currently, the last
+        decorator to run wins, and overwrites everything.  You'll end up with just the input, or
+        just the label, depending on which you register last.
+    </para>
+
+    <para>
+        To overcome this, simply concatenate the passed in <varname>$content</varname> with the
+        markup somehow:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+return $content . $markup;
+]]></programlisting>
+
+    <para>
+        The problem with the above approach comes when you want to programmatically choose whether
+        the original content should precede or append the new markup. Fortunately, there's a
+        standard mechanism for this already; <classname>Zend_Form_Decorator_Abstract</classname> has
+        a concept of placement and defines some constants for matching it. Additionally, it allows
+        specifying a separator to place between the two. Let's make use of those:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class My_Decorator_SimpleInput extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<input id="%s" name="%s" type="text" value="%s"/>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $name    = htmlentities($element->getFullyQualifiedName());
+        $id      = htmlentities($element->getId());
+        $value   = htmlentities($element->getValue());
+
+        $markup  = sprintf($this->_format, $id, $name, $value);
+
+        $placement = $this->getPlacement();
+        $separator = $this->getSeparator();
+        switch ($placement) {
+            case self::PREPEND:
+                return $markup . $separator . $content;
+            case self::APPEND:
+            default:
+                return $content . $separator . $markup;
+        }
+    }
+}
+
+class My_Decorator_SimpleLabel extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<label for="%s">%s</label>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $id      = htmlentities($element->getId());
+        $label   = htmlentities($element->getLabel());
+
+        $markup = sprint($this->_format, $id, $label);
+
+        $placement = $this->getPlacement();
+        $separator = $this->getSeparator();
+        switch ($placement) {
+            case self::APPEND:
+                return $markup . $separator . $content;
+            case self::PREPEND:
+            default:
+                return $content . $separator . $markup;
+        }
+    }
+}
+]]></programlisting>
+
+    <para>
+        Notice in the above that I'm switching the default case for each; the assumption will be
+        that labels prepend content, and input appends.
+    </para>
+
+    <para>
+        Now, let's create a form element that uses these:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$element = new Zend_Form_Element('foo', array(
+    'label'      => 'Foo',
+    'belongsTo'  => 'bar',
+    'value'      => 'test',
+    'prefixPath' => array('decorator' => array(
+        'My_Decorator' => 'path/to/decorators/',
+    )),
+    'decorators' => array(
+        'SimpleInput',
+        'SimpleLabel',
+    ),
+));
+]]></programlisting>
+
+    <para>
+        How will this work? When we call <methodname>render()</methodname>, the element will iterate
+        through the various attached decorators, calling <methodname>render()</methodname> on each.
+        It will pass an empty string to the very first, and then whatever content is created will be
+        passed to the next, and so on:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                Initial content is an empty string: ''.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                '' is passed to the <classname>SimpleInput</classname> decorator, which then
+                generates a form input that it appends to the empty string: <code>&lt;input
+                    id="bar-foo" name="bar[foo]" type="text" value="test"/&gt;</code>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                The input is then passed as content to the <classname>SimpleLabel</classname>
+                decorator, which generates a label and prepends it to the original content; the
+                default separator is a <constant>PHP_EOL</constant> character, giving us this:
+                <code>&lt;label for="bar-foo"&gt;\n&lt;input id="bar-foo" name="bar[foo]"
+                    type="text" value="test"/&gt;</code>.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        But wait a second! What if you wanted the label to come after the input for some reason?
+        Remember that "placement" flag? You can pass it as an option to the decorator. The easiest
+        way to do this is to pass an array of options with the decorator during element creation:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$element = new Zend_Form_Element('foo', array(
+    'label'      => 'Foo',
+    'belongsTo'  => 'bar',
+    'value'      => 'test',
+    'prefixPath' => array('decorator' => array(
+        'My_Decorator' => 'path/to/decorators/',
+    )),
+    'decorators' => array(
+        'SimpleInput'
+        array('SimpleLabel', array('placement' => 'append')),
+    ),
+));
+]]></programlisting>
+
+    <para>
+        Notice that when passing options, you must wrap the decorator within an array; this hints to
+        the constructor that options are available. The decorator name is the first element of the
+        array, and options are passed in an array to the second element of the array.
+    </para>
+
+    <para>
+        The above results in the markup <code>&lt;input id="bar-foo" name="bar[foo]" type="text"
+            value="test"/&gt;\n&lt;label for="bar-foo"&gt;</code>.
+    </para>
+
+    <para>
+        Using this technique, you can have decorators that target specific metadata of the element
+        or form and create only the markup relevant to that metadata; by using mulitiple decorators,
+        you can then build up the complete element markup. Our onion is the result.
+    </para>
+
+    <para>
+        There are pros and cons to this approach. First, the cons:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                More complex to implement. You have to pay careful attention to the decorators you
+                use and what placement you utilize in order to build up the markup in the correct
+                sequence.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                More resource intensive. More decorators means more objects; multiply this by the
+                number of elements you have in a form, and you may end up with some serious resource
+                usage. Caching can help here.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        The advantages are compelling, though:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                Reusable decorators. You can create truly re-usable decorators with this technique,
+                as you don't have to worry about the complete markup, but only markup for one or a
+                few pieces of element/form metadata.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Ultimate flexibility. You can theoretically generate any markup combination you want
+                from a small number of decorators.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        While the above examples are the intended usage of decorators within
+        <classname>Zend_Form</classname>, it's often hard to wrap your head around how the
+        decorators interact with one another to build the final markup. For this reason, some
+        flexibility was added in the 1.7 series to make rendering individual decorators possible --
+        which gives some Rails-like simplicity to rendering forms. We'll look at that in the next
+        section.
+    </para>
+</sect1>

+ 245 - 0
documentation/manual/de/tutorials/form-decorators-simplest.xml

@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.form.decorators.simplest">
+    <title>Decorator Basics</title>
+
+    <sect2 id="learning.form.decorators.simplest.decorator-overview">
+        <title>Overview of the Decorator Pattern</title>
+
+        <para>
+            To begin, we'll cover some background on the <ulink
+                url="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator design
+                pattern</ulink>.  One common technique is to define a common interface that both
+            your originating object and decorator will implement; your decorator than accepts the
+            originating object as a dependency, and will either proxy to it or override its methods.
+            Let's put that into code to make it more easily understood:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+interface Window
+{
+    public function isOpen();
+    public function open();
+    public function close();
+}
+
+class StandardWindow implements Window
+{
+    protected $_open = false;
+
+    public function isOpen()
+    {
+        return $this->_open;
+    }
+
+    public function open()
+    {
+        if (!$this->_open) {
+            $this->_open = true;
+        }
+    }
+
+    public function close()
+    {
+        if ($this->_open) {
+            $this->_open = false;
+        }
+    }
+}
+
+class LockedWindow implements Window
+{
+    protected $_window;
+
+    public function __construct(Window $window)
+    {
+        $this->_window = $window;
+        $this->_window->close();
+    }
+
+    public function isOpen()
+    {
+        return false;
+    }
+
+    public function open()
+    {
+        throw new Exception('Cannot open locked windows');
+    }
+
+    public function close()
+    {
+        $this->_window->close();
+    }
+}
+]]></programlisting>
+
+        <para>
+            You then create an object of type <classname>StandardWindow</classname>, pass it to the
+            constructor of <classname>LockedWindow</classname>, and your window instance now has
+            different behavior. The beauty is that you don't have to implement any sort of "locking"
+            functionality on your standard window class -- the decorator takes care of that for you.
+            In the meantime, you can pass your locked window around as if it were just another
+            window.
+        </para>
+
+        <para>
+            One particular place where the decorator pattern is useful is for creating textual
+            representations of objects. As an example, you might have a "Person" object that, by
+            itself, has no textual representation. By using the Decorator pattern, you can create an
+            object that will act as if it were a Person, but also provide the ability to render that
+            Person textually.
+        </para>
+
+        <para>
+            In this particular example, we're going to use <ulink
+                url="http://en.wikipedia.org/wiki/Duck_typing">duck typing</ulink> instead of an
+            explicit interface. This allows our implementation to be a bit more flexible, while
+            still allowing the decorator object to act exactly as if it were a Person object.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Person
+{
+    public function setFirstName($name) {}
+    public function getFirstName() {}
+    public function setLastName($name) {}
+    public function getLastName() {}
+    public function setTitle($title) {}
+    public function getTitle() {}
+}
+
+class TextPerson
+{
+    protected $_person;
+
+    public function __construct(Person $person)
+    {
+        $this->_person = $person;
+    }
+
+    public function __call($method, $args)
+    {
+        if (!method_exists($this->_person, $method)) {
+            throw new Exception('Invalid method called on HtmlPerson: '
+                .  $method);
+        }
+        return call_user_func_array(array($this->_person, $method), $args);
+    }
+
+    public function __toString()
+    {
+        return $this->_person->getTitle() . ' '
+            . $this->_person->getFirstName() . ' '
+            . $this->_person->getLastName();
+    }
+}
+]]></programlisting>
+
+        <para>
+            In this example, you pass your <classname>Person</classname> instance to the
+            <classname>TextPerson</classname> constructor. By using method overloading, you are able
+            to continue to call all the methods of <classname>Person</classname> -- to set the first
+            name, last name, or title -- but you also now gain a string representation via the
+            <methodname>__toString()</methodname> method.
+        </para>
+
+        <para>
+            This latter example is getting close to how <classname>Zend_Form</classname> decorators
+            work. The key difference is that instead of a decorator wrapping the element, the
+            element has one or more decorators attached to it that it then injects itself into in
+            order to render.  The decorator then can access the element's methods and properties in
+            order to create a representation of the element -- or a subset of it.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.form.decorators.simplest.first-decorator">
+        <title>Creating Your First Decorator</title>
+
+        <para>
+            <classname>Zend_Form</classname> decorators all implement a common interface,
+            <interfacename>Zend_Form_Decorator_Interface</interfacename>. That interface provides
+            the ability to set decorator-specific options, register and retrieve the element, and
+            render. A base decorator, <classname>Zend_Form_Decorator_Abstract</classname>, provides
+            most of the functionality you will ever need, with the exception of the rendering logic.
+        </para>
+
+        <para>
+            Let's consider a situation where we simply want to render an element as a standard form
+            text input with a label. We won't worry about error handling or whether or not the
+            element should be wrapped within other tags for now -- just the basics. Such a decorator
+            might look like this:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class My_Decorator_SimpleInput extends Zend_Form_Decorator_Abstract
+{
+    protected $_format = '<label for="%s">%s</label>'
+                       . '<input id="%s" name="%s" type="text" value="%s"/>';
+
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $name    = htmlentities($element->getFullyQualifiedName());
+        $label   = htmlentities($element->getLabel());
+        $id      = htmlentities($element->getId());
+        $value   = htmlentities($element->getValue());
+
+        $markup  = sprintf($this->_format, $name, $label, $id, $name, $value);
+        return $markup;
+    }
+}
+]]></programlisting>
+
+        <para>
+            Let's create an element that uses this decorator:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$decorator = new My_Decorator_SimpleInput();
+$element   = new Zend_Form_Element('foo', array(
+    'label'      => 'Foo',
+    'belongsTo'  => 'bar',
+    'value'      => 'test',
+    'decorators' => array($decorator),
+));
+]]></programlisting>
+
+        <para>
+            Rendering this element results in the following markup:
+        </para>
+
+        <programlisting language="html"><![CDATA[
+<label for="bar[foo]">Foo</label>
+<input id="bar-foo" name="bar[foo]" type="text" value="test"/>
+]]></programlisting>
+
+        <para>
+            You could also put this class in your library somewhere, inform your element of that
+            path, and refer to the decorator as simply "SimpleInput" as well:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$element = new Zend_Form_Element('foo', array(
+    'label'      => 'Foo',
+    'belongsTo'  => 'bar',
+    'value'      => 'test',
+    'prefixPath' => array('decorator' => array(
+        'My_Decorator' => 'path/to/decorators/',
+    )),
+    'decorators' => array('SimpleInput'),
+));
+]]></programlisting>
+
+        <para>
+            This gives you the benefit of re-use in other projects, and also opens the door for
+            providing alternate implementations of that decorator later.
+        </para>
+
+        <para>
+            In the next section, we'll look at how to combine decorators in order to create
+            composite output.
+        </para>
+    </sect2>
+</sect1>

+ 21 - 0
documentation/manual/de/tutorials/layout-conclusions.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.layout.conclusions">
+    <title>Zend_Layout: Fazit</title>
+
+    <para>
+        <classname>Zend_Layout</classname> ist ein sehr einfacher Wrapper um
+        <classname>Zend_View</classname> der sofort die Vorteile einer Two Step View anbietet, und
+        die Flexibilität gibt ein Site-weites Design zu erstellen welches man in eigene
+        Anwendungsinhalte injizieren kann.
+    </para>
+
+    <para>
+        Wenn man die Beispiele näher anschaut, könnte man trotzdem auf die Idee kommen das die
+        Funktionalität relativ limitiert ist: Wie ändert man den Seitentitel, injiziert einen
+        optionalen Skript Tag, oder erstellt sogar eine optionale Sidebar? Diese Fragen werden mit
+        dem Konzept einer "Composite View" behandelt -- und sind Teil des nächsten Kapitels in
+        diesem Tutorial, welches View "Platzhalter" behandelt.
+    </para>
+</sect1>

+ 57 - 0
documentation/manual/de/tutorials/layout-intro.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.layout.intro">
+    <title>Einführung</title>
+
+    <para>
+        Wenn eine Website gebaut wird, die Zend Frameworks <acronym>MVC</acronym> Layer verwendet,
+        sind die View Skripte typischerweise nur Abschnitte von <acronym>HTML</acronym> welche der
+        angefragten Aktion angehören. Wenn man zum Beispiel die Aktion
+        "<filename>/user/list</filename>" hat, könnte man ein View Skript erstellen welches durch
+        die Benutzer iteriert und eine unsortierte Liste präsentiert:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<h2>Benutzer</h2>
+<ul>
+    <?php if (!count($this->users)): ?>
+    <li>Keine Benutzer gefunden</li>
+    <?php else: ?>
+    <?php foreach ($this->users as $user): ?>
+    <li>
+        <?php echo $this->escape($user->fullname) ?>
+        (<?php echo $this->escape($user->email) ?>)
+    </li>
+    <?php endforeach ?>
+    <?php endif ?>
+</ul>
+]]></programlisting>
+
+    <para>
+        Da dies nur ein <acronym>HTML</acronym> Abschnitt ist, ist dies keine gültige Seite; es
+        fehlt eine <acronym>DOCTYPE</acronym> Deklaration, und die öffnenden <acronym>HTML</acronym>
+        und <acronym>BODY</acronym> Tags. Die Frage ist also, wie wir diese erstellen?
+    </para>
+
+    <para>
+        In frühen Versionen von Zend Framework erstellten Entwickler oft "header" und "footer" View
+        Skripte welche diese Teile enthielten, und Sie dann in jedem View Skript darstellten. Wärend
+        diese Methode funktioniert ist es auch schwer Sie im Nachhinein zu verändern, oder
+        kombinierte Inhalte zu erstellen indem mehrere Aktionen aufgerufen werden.
+    </para>
+
+    <para>
+        Das <ulink url="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</ulink>
+        Design Pattern beantwortet viele der gezeigten Probleme. In diesem Pattern wird die
+        "application" (Anwendungs) View als erstes erstellt, und dann in die "page" (Seite) Views
+        injiziert, welche anschließend dem Kunden presentiert wird. Die Seitenansicht kann wie ein
+        seitenweites Template oder Layout angesehen werden, und würde übliche Elemente zwischen den
+        verschiedenen Seiten verwenden.
+    </para>
+
+    <para>
+        Im Zend Framework implementiert <classname>Zend_Layout</classname> das Two Step View
+        Pattern.
+    </para>
+</sect1>

+ 255 - 0
documentation/manual/de/tutorials/layout-usage.xml

@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.layout.usage">
+    <title>Zend_Layout verwenden</title>
+
+    <para>
+        Die grundsätzliche Verwendung von <classname>Zend_Layout</classname> ist recht trivial.
+        Angenommen man verwendet bereits <classname>Zend_Application</classname>, dann kann man
+        einfach ein paar Konfigurations Optionen übergeben und ein Layout View Skript erstellen.
+    </para>
+
+    <sect2 id="learning.layout.usage.configuration">
+        <title>Layout Konfiguration</title>
+
+        <para>
+            Der empfohlene Ort für Layouts ist im Unterverzeichnis
+            "<filename>layouts/scripts/</filename>" in der eigenen Anwendung:
+        </para>
+
+        <programlisting language="text"><![CDATA[
+application
+|-- Bootstrap.php
+|-- configs
+|   `-- application.ini
+|-- controllers
+|-- layouts
+|   `-- scripts
+|       |-- layout.phtml
+]]></programlisting>
+
+        <para>
+            Um <classname>Zend_Layout</classname> zu initialisieren muss das folgende in die eigene
+            Konfigurationsdatei eingefügt werden
+            ("<filename>application/configs/application.ini</filename>"):
+        </para>
+
+        <programlisting language="dosini"><![CDATA[
+resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
+resources.layout.layout = "layout"
+]]></programlisting>
+
+        <para>
+            Die erste Zeile zeigt wo nach Layout Skripten nachgesehen werden soll; die zweite Zeile
+            gibt den Namen des Layouts an, welches verwendet werden soll, abzüglich der
+            Erweiterung für View Skripts (welche standardmäßig mit "<filename>.phtml</filename>"
+            angenommen wird).
+        </para>
+    </sect2>
+
+    <sect2 id="learning.layout.usage.layout-script">
+        <title>Ein Layout Skript erstellen</title>
+
+        <para>
+            Jetzt da man die Konfiguration gesetzt hat, muss man sein Layout Skript erstellen.
+            Zuerst muss man sicherstellen dass das Verzeichnis
+            "<filename>application/layouts/scripts</filename>" erstelt wurde; dann ist ein Editor
+            zu öffnen und das Markup für das eigene Layout zu erstellen. Layout Skripte sind einfach
+            View Skripte, mit einigen kleinen Unterschieden.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<html>
+<head>
+    <title>Meine Site</title>
+</head>
+<body>
+    <?php echo $this->layout()->content ?>
+</body>
+</html>
+]]></programlisting>
+
+        <para>
+            Im obigen Beispiel ist der Aufruf zum <methodname>layout()</methodname> View Helper zu
+            sehen. Wenn man die <classname>Zend_Layout</classname> Ressource registriert, erhält man
+            auch Zugriff zum Action und zum View Helper welche es erlauben die
+            <classname>Zend_Layout</classname> Instanz anzusprechen; man kann anschließend
+            Befehle auf dem Layout Objekt aufrufen. In diesem Fall wird eine benannte Variable,
+            <varname>$content</varname>, empfangen und ausgegeben. Standardmäßig wird die Variable
+            <varname>$content</varname> vom Anwendungs-View Skript dargestellt. Andererseits ist
+            alles was man normalerweise in einem View Skript macht perfekt gültig -- aufrufen von
+            Helfern oder View Methoden wie man es will.
+        </para>
+
+        <para>
+            An diesem Punkt hat man ein funktionierendes Layout Skript, und die eigene Anwendung ist
+            über seinen Ort informiert und weis wie es darzustellen ist.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.layout.usage.access">
+        <title>Auf das Layout Objekt zugreifen</title>
+
+        <para>
+            Manchmal ist ein Direktzugriff auf das Layout Objekt notwendig. Es gibt drei Wege wie
+            man das tun kann:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis>In den View Skripten:</emphasis> der <methodname>layout()</methodname>
+                    View Helfer ist zu verwenden, der die Instanz von
+                    <classname>Zend_Layout</classname> zurückgibt welche im Front Controller Plugin
+                    registriert ist.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+<?php $layout = $this->layout(); ?>
+]]></programlisting>
+
+                <para>
+                    Da er die Layout Instanz zurückgibt, kann man also einfach Methoden auf Ihm
+                    aufrufen statt Ihn einer Variablen zuordnen zu müssen.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>In Action Controllern</emphasis>: der
+                    <methodname>layout()</methodname> Action Helfer ist zu verwenden, welcher wie
+                    der View Helfer arbeitet.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+// Aufruf des Helfers als eine Methode auf dem Helfer Broker:
+$layout = $this->_helper->layout();
+
+// Oder etwas komplizierter:
+$helper = $this->_helper->getHelper('Layout');
+$layout = $helper->getLayoutInstance();
+]]></programlisting>
+
+                <para>
+                    Wie mit dem View Helfer gibt der Action Helfer die Instanz des Layouts zurück,
+                    man kann also einfach Methoden auf Ihm aufrufen, statt diese einer Variable
+                    zuordnen zu müssen.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Andernorts</emphasis>: verwenden der statischen Methode
+                    <methodname>getMvcInstance()</methodname>. Das gibt die Layout Instanz zurück,
+                    welche durch die Bootstrap Ressource registriert wurde.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+$layout = Zend_Layout::getMvcInstance();
+]]></programlisting>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Über die Bootstrap</emphasis>: empfangen der Layout Ressource, welche
+                    die <classname>Zend_Layout</classname> Instanz ist.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+$layout = $bootstrap->getResource('Layout');
+]]></programlisting>
+
+                <para>
+                    Überall wo man auf das Bootstrap Objekt Zugriff hat, wird diese Methode
+                    empfohlen und nicht die statische <methodname>getMvcInstance()</methodname>
+                    Methode.
+                </para>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="learning.layout.usage.other-operations">
+        <title>Andere Operationen</title>
+
+        <para>
+            In den meisten Fällen empfängt die obige Konfiguration und das Layout Skript (mit
+            Änderungen) das, was benötigt wird. Trotzdem existieren einigen andere Funktionalitäten
+            die man früher oder später verwenden wird. In allen der folgenden Beispiele kann man
+            eine der <link
+                linkend="learning.layout.usage.access">oben aufgeführten Methoden</link> verwenden
+            um das Layout Objekt zu erhalten.
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis>Setzen von Layout Variablen</emphasis>:
+                    <classname>Zend_Layout</classname> hat seine eigene Registry von
+                    Layout-spezifischen View Variablen auf die man zugreifen kann; der
+                    <varname>$content</varname> Schlüssel welche im ursprünglichen Layout Skript
+                    gezeigt wird, ist so ein Beispiel. Man kann diese zuweisen und empfangen indem
+                    ein normaler Zugriff auf Eigenschaften verwendet wird, oder über die
+                    <methodname>assign()</methodname> Methode.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+// Inhalt setzen:
+$layout->somekey = "foo"
+
+// Den selben Inhalt ausgeben:
+echo $layout->somekey; // 'foo'
+
+// Verwenden der assign() Methode:
+$layout->assign('someotherkey', 'bar');
+
+// Der Zugriff auf assign()'ed Variablen bleibt der gleiche:
+echo $layout->someotherkey; // 'bar'
+]]></programlisting>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <methodname>disableLayout()</methodname>: Üblicherweise wird man Layouts
+                    ausschalten wollen; zum Beispiel wenn eine Ajax Anfrage beantwortet wird, oder
+                    eine RESTvolle Darstellung einer Ressource angeboten wird. In diesem Fällen kann
+                    man die <methodname>disableLayout()</methodname> Methode auf dem Layout Objekt
+                    ausführen.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+$layout->disableLayout();
+]]></programlisting>
+
+                <para>
+                    Das Gegenteil dieser Methode ist natürlich
+                    <methodname>enableLayout()</methodname>, welches jederzeit aufgerufen werden
+                    kann um Layouts für die angefragte Aktion wieder einzuschalten.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>Ein alternatives Layout auswählen</emphasis>: Wenn man mehrere Layouts
+                    für die eigene Site oder Anwendung hat, kann das Layout welches verwendet werden
+                    soll jederzeit ausgewählt werden indem einfach die
+                    <methodname>setLayout()</methodname> Methode aufgerufen wird. Es ist
+                    aufzurufen indem der Name des Layout Skripts ohne die Dateiendung spezifiziert
+                    wird.
+                </para>
+
+                <programlisting language="php"><![CDATA[
+// Verwendung des Layout Skripts "alternate.phtml":
+$layout->setLayout('alternate');
+]]></programlisting>
+
+                <para>
+                    Das Layout Skript sollte im <varname>$layoutPath</varname> Verzeichnis enthalten
+                    sein, welche in der eigenen Konfiguration spezifiziert ist.
+                    <classname>Zend_Layout</classname> wird anschließend dieses neue Layout bei der
+                    Darstellung verwenden.
+                </para>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+</sect1>

+ 28 - 0
documentation/manual/de/tutorials/lucene-index-opening.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.index-opening">
+    <title>Index Opening and Creation</title>
+
+    <para>
+        All index operations (e.g., creating a new index, adding a document to the index, deleting a
+        document, searching through the index) need an index object. One can be obtained using one
+        of the following two methods.
+    </para>
+
+    <example id="learning.lucene.index-opening.creation">
+        <title>Lucene Index Creation</title>
+
+        <programlisting language="php"><![CDATA[
+$index = Zend_Search_Lucene::create($indexPath);
+]]></programlisting>
+    </example>
+
+    <example id="learning.lucene.index-opening.opening">
+        <title>Lucene Index Opening</title>
+
+        <programlisting language="php"><![CDATA[
+$index = Zend_Search_Lucene::open($indexPath);
+]]></programlisting>
+    </example>
+</sect1>

+ 118 - 0
documentation/manual/de/tutorials/lucene-index-structure.xml

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.index-structure">
+    <title>Lucene Index Structure</title>
+
+    <para>
+        In order to fully utilize <classname>Zend_Search_Lucene</classname>'s capabilities with
+        maximum performance, you need to understand it's internal index structure.
+    </para>
+
+    <para>
+        An <emphasis>index</emphasis> is stored as a set of files within a single directory.
+    </para>
+
+    <para>
+        An <emphasis>index</emphasis> consists of any number of independent
+        <emphasis>segments</emphasis> which store information about a subset of indexed documents.
+        Each <emphasis>segment</emphasis> has its own <emphasis>terms dictionary</emphasis>, terms
+        dictionary index, and document storage (stored field values) <footnote><para>Starting with
+                Lucene 2.3, document storage files can be shared between segments; however,
+                <classname>Zend_Search_Lucene</classname> doesn't use this
+                capability</para></footnote>. All segment data is stored in
+        <filename>_xxxxx.cfs</filename> files, where <emphasis>xxxxx</emphasis> is a segment name.
+    </para>
+
+    <para>
+        Once an index segment file is created, it can't be updated. New documents are added to new
+        segments. Deleted documents are only marked as deleted in an optional
+        <filename>&lt;segmentname&gt;.del</filename> file.
+    </para>
+
+    <para>
+        Document updating is performed as separate delete and add operations, even though it's done
+        using an <methodname>update()</methodname> <acronym>API</acronym> call
+        <footnote><para>This call is provided only by Java Lucene now, but it's planned to extend
+            the <classname>Zend_Search_Lucene</classname> <acronym>API</acronym> with similar
+            functionality</para></footnote>.
+        This simplifies adding new documents, and allows updating concurrently with search
+        operations.
+    </para>
+
+    <para>
+        On the other hand, using several segments (one document per segment as a borderline case)
+        increases search time:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                retrieving a term from a dictionary is performed for each segment;
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                the terms dictionary index is pre-loaded for each segment (this process takes the
+                most search time for simple queries, and it also requires additional memory).
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        If the terms dictionary reaches a saturation point, then search through one segment is
+        <emphasis>N</emphasis> times faster than search through <emphasis>N</emphasis> segments
+        in most cases.
+    </para>
+
+    <para>
+        <emphasis>Index optimization</emphasis> merges two or more segments into a single new one. A
+        new segment is added to the index segments list, and old segments are excluded.
+    </para>
+
+    <para>
+        Segment list updates are performed as an atomic operation. This gives the ability of
+        concurrently adding new documents, performing index optimization, and searching through the
+        index.
+    </para>
+
+    <para>
+        Index auto-optimization is performed after each new segment generation. It merges sets of
+        the smallest segments into larger segments, and larger segments into even larger segments,
+        if we have enough segments to merge.
+    </para>
+
+    <para>
+        Index auto-optimization is controlled by three options:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                <emphasis>MaxBufferedDocs</emphasis> (the minimal number of documents required
+                before the buffered in-memory documents are written into a new segment);
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis>MaxMergeDocs</emphasis> (the largest number of documents ever merged by
+                an optimization operation); and
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis>MergeFactor</emphasis> (which determines how often segment indices are
+                merged by auto-optimization operations).
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        If we add one document per script execution, then <emphasis>MaxBufferedDocs</emphasis> is
+        actually not used (only one new segment with only one document is created at the end of
+        script execution, at which time the auto-optimization process starts).
+    </para>
+</sect1>

+ 95 - 0
documentation/manual/de/tutorials/lucene-indexing.xml

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.indexing">
+    <title>Indexing</title>
+
+    <para>
+        Indexing is performed by adding a new document to an existing or new index:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$index->addDocument($doc);
+]]></programlisting>
+
+    <para>
+        There are two ways to create document object. The first is to do it manually.
+    </para>
+
+    <example id="learning.lucene.indexing.doc-creation">
+        <title>Manual Document Construction</title>
+
+        <programlisting language="php"><![CDATA[
+$doc = new Zend_Search_Lucene_Document();
+$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));
+$doc->addField(Zend_Search_Lucene_Field::Text('title', $docTitle));
+$doc->addField(Zend_Search_Lucene_Field::unStored('contents', $docBody));
+$doc->addField(Zend_Search_Lucene_Field::binary('avatar', $avatarData));
+]]></programlisting>
+    </example>
+
+    <para>
+        The second method is to load it from <acronym>HTML</acronym> or Microsoft Office 2007 files:
+    </para>
+
+    <example id="learning.lucene.indexing.doc-loading">
+        <title>Document loading</title>
+
+        <programlisting language="php"><![CDATA[
+$doc = Zend_Search_Lucene_Document_Html::loadHTML($htmlString);
+$doc = Zend_Search_Lucene_Document_Docx::loadDocxFile($path);
+$doc = Zend_Search_Lucene_Document_Pptx::loadPptFile($path);
+$doc = Zend_Search_Lucene_Document_Xlsx::loadXlsxFile($path);
+]]></programlisting>
+    </example>
+
+    <para>
+        If a document is loaded from one of the supported formats, it still can be extended manually
+        with new user defined fields.
+    </para>
+
+    <sect2 id="learning.lucene.indexing.policy">
+        <title>Indexing Policy</title>
+
+        <para>
+            You should define indexing policy within your application architectural design.
+        </para>
+
+        <para>
+            You may need an on-demand indexing configuration (something like <acronym>OLTP</acronym>
+            system). In such systems, you usually add one document per user request. As such, the
+            <emphasis>MaxBufferedDocs</emphasis> option will not affect the system. On the other
+            hand, <emphasis>MaxMergeDocs</emphasis> is really helpful as it allows you to limit
+            maximum script execution time. <emphasis>MergeFactor</emphasis> should be set to a value
+            that keeps balance between the average indexing time (it's also affected by average
+            auto-optimization time) and search performance (index optimization level is dependent on
+            the number of segments).
+        </para>
+
+        <para>
+            If you will be primarily performing batch index updates, your configuration should use a
+            <emphasis>MaxBufferedDocs</emphasis> option set to the maximum value supported by the
+            available amount of memory. <emphasis>MaxMergeDocs</emphasis> and
+            <emphasis>MergeFactor</emphasis> have to be set to values reducing auto-optimization
+            involvement as much as possible <footnote><para>An additional limit is the maximum file
+                    handlers supported by the operation system for concurrent open
+                    operations</para></footnote>. Full index optimization should be applied after
+            indexing.
+        </para>
+
+        <example id="learning.lucene.indexing.optimization">
+            <title>Index optimization</title>
+
+            <programlisting language="php"><![CDATA[
+$index->optimize();
+]]></programlisting>
+        </example>
+
+        <para>
+            In some configurations, it's more effective to serialize index updates by organizing
+            update requests into a queue and processing several update requests in a single script
+            execution. This reduces index opening overhead, and allows utilizing index document
+            buffering.
+        </para>
+    </sect2>
+</sect1>

+ 103 - 0
documentation/manual/de/tutorials/lucene-intro.xml

@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.intro">
+    <title>Zend_Search_Lucene Introduction</title>
+
+    <para>
+        The <classname>Zend_Search_Lucene</classname> component is intended to provide a
+        ready-for-use full-text search solution. It doesn't require any <acronym>PHP</acronym>
+        extensions<footnote><para>Though some <acronym>UTF-8</acronym> processing functionality
+                requires the <emphasis>mbstring</emphasis> extension to be turned
+                on</para></footnote> or additional software to be installed, and can be used
+        immediately after Zend Framework installation.
+    </para>
+
+    <para>
+        <classname>Zend_Search_Lucene</classname> is a pure <acronym>PHP</acronym> port of the
+        popular open source full-text search engine known as Apache Lucene. See <ulink
+            url="http://lucene.apache.org">http://lucene.apache.org/</ulink> for the details.
+    </para>
+
+    <para>
+        Information must be indexed to be available for searching.
+        <classname>Zend_Search_Lucene</classname> and Java Lucene use a document concept known as an
+        "atomic indexing item."
+    </para>
+
+    <para>
+        Each document is a set of fields: &lt;name, value&gt; pairs where name and value are
+        <acronym>UTF-8</acronym> strings<footnote><para>Binary strings are also allowed to be used
+                as field values</para></footnote>. Any subset of the document fields may be marked
+        as "indexed" to include field data in the text indexing process.
+    </para>
+
+    <para>
+        Field values may or may not be tokenized while indexing. If a field is not tokenized, then
+        the field value is stored as one term; otherwise, the current analyzer is used for
+        tokenization.
+    </para>
+
+    <para>
+        Several analyzers are provided within the <classname>Zend_Search_Lucene</classname> package.
+        The default analyzer works with <acronym>ASCII</acronym> text (since the
+        <acronym>UTF-8</acronym> analyzer needs the <emphasis>mbstring</emphasis> extension to be
+        turned on). It is case insensitive, and it skips numbers. Use other analyzers or create your
+        own analyzer if you need to change this behavior.
+    </para>
+
+    <note>
+        <title>Using analyzers during indexing and searching</title>
+
+        <para>
+            Important note! Search queries are also tokenized using the "current analyzer", so the
+            same analyzer must be set as the default during both the indexing and searching process.
+            This will guarantee that source and searched text will be transformed into terms in the
+            same way.
+        </para>
+    </note>
+
+    <para>
+        Field values are optionally stored within an index. This allows the original field data to
+        be retrieved from the index while searching. This is the only way to associate search
+        results with the original data (internal document IDs may be changed after index
+        optimization or auto-optimization).
+    </para>
+
+    <para>
+        The thing that should be remembered is that a Lucene index is not a database. It doesn't
+        provide index backup mechanisms except backup of the file system directory. It doesn't
+        provide transactional mechanisms though concurrent index update as well as concurrent update
+        and read are supported. It doesn't compare with databases in data retrieving speed.
+    </para>
+
+    <para>
+        So it's good idea:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                <emphasis>Not</emphasis> to use Lucene index as a storage since it may dramatically
+                decrease search hit retrieving performance. Store only unique document identifiers
+                (doc paths, <acronym>URL</acronym>s, database unique IDs) and associated data within
+                an index. E.g. title, annotation, category, language info, avatar. (Note: a field
+                may be included in indexing, but not stored, or stored, but not indexed).
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                To write functionality that can rebuild an index completely if it's corrupted for
+                any reason.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Individual documents in the index may have completely different sets of fields. The same
+        fields in different documents don't need to have the same attributes. E.g. a field may be
+        indexed for one document and skipped from indexing for another. The same applies for
+        storing, tokenizing, or treating field value as a binary string.
+    </para>
+</sect1>

+ 49 - 0
documentation/manual/de/tutorials/lucene-pagination.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.pagination">
+    <title>Search result pagination</title>
+
+    <para>
+        As <link linkend="learning.lucene.searching.identifiers">mentioned above</link>, search
+        result hit objects use lazy loading for stored document fields. When any stored field is
+        accessed, the complete document is loaded.
+    </para>
+
+    <para>
+        Do not retrieve all documents if you actually need to work only with some portion of them.
+        Go through the search results and store document IDs (and optionally the score) somewhere to
+        retrive documents from the index during the next script execution.
+    </para>
+
+    <example id="learning.lucene.pagination.example">
+        <title>Search result pagination example</title>
+
+        <programlisting language="php"><![CDATA[
+$cacheId = md5($query);
+
+if (!$resultSet = $cache->load($cacheId)) {
+    $hits = $index->find($query);
+    $resultSet = array();
+    foreach ($hits as $hit) {
+        $resultSetEntry          = array();
+        $resultSetEntry['id']    = $hit->id;
+        $resultSetEntry['score'] = $hit->score;
+
+        $resultSet[] = $resultSetEntry;
+    }
+
+    $cache->save($resultSet, $cacheId);
+}
+
+$publishedResultSet = array();
+for ($resultId = $startId; $resultId < $endId; $resultId++) {
+    $publishedResultSet[$resultId] = array(
+        'id'    => $resultSet[$resultId]['id'],
+        'score' => $resultSet[$resultId]['score'],
+        'doc'   => $index->getDocument($resultSet[$resultId]['id']),
+    );
+}
+]]></programlisting>
+    </example>
+</sect1>

+ 229 - 0
documentation/manual/de/tutorials/lucene-queries.xml

@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.queries">
+    <title>Supported queries</title>
+
+    <para>
+        <classname>Zend_Search_Lucene</classname> and Java Lucene support a powerful query language.
+        It allows searching for individual terms, phrases, ranges of terms; using wildcards and
+        fuzzy search; combining queries using boolean operators; and so on.
+    </para>
+
+    <para>
+        A detailed query language description can be found in the <link
+            linkend="zend.search.lucene.query-language">
+            Zend_Search_Lucene component documentation</link>.
+    </para>
+
+    <para>
+        What follows are examples of some common query types and strategies.
+    </para>
+
+    <example id="learning.lucene.queries.keyword">
+        <title>Querying for a single word</title>
+
+        <programlisting language="text"><![CDATA[
+hello
+]]></programlisting>
+
+        <para>
+            Searches for the word "hello" through all document fields.
+        </para>
+    </example>
+
+    <note>
+        <title>Default search field</title>
+
+        <para>
+            Important note! Java Lucene searches only through the "contents" field by default, but
+            <classname>Zend_Search_Lucene</classname> searches through <emphasis>all</emphasis>
+            fields. This behavior can be modified using the
+            <methodname>Zend_Search_Lucene::setDefaultSearchField($fieldName)</methodname> method.
+        </para>
+    </note>
+
+    <example id="learning.lucene.queries.multiple-words">
+        <title>Querying for multiple words</title>
+
+        <programlisting language="text"><![CDATA[
+hello dolly
+]]></programlisting>
+
+        <para>
+            Searches for two words. Both words are optional; at least one of them must be present in
+            the result.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.required-words">
+        <title>Requiring words in a query</title>
+
+        <programlisting language="text"><![CDATA[
++hello dolly
+]]></programlisting>
+
+        <para>
+            Searches for two words; "hello" is required, "dolly" is optional.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.prohibited-words">
+        <title>Prohibiting words in queried documents</title>
+
+        <programlisting language="text"><![CDATA[
++hello -dolly
+]]></programlisting>
+
+        <para>
+            Searches for two words; "hello" is required, 'dolly' is prohibited. In other words, if
+            the document matches "hello", but contains the word "dolly", it will not be returned in
+            the set of matches.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.phrases">
+        <title>Querying for phrases</title>
+
+        <programlisting language="text"><![CDATA[
+"hello dolly"
+]]></programlisting>
+
+        <para>
+            Searches for the phrase "hello dolly"; a document only matches if that exact string is
+            present.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.fields">
+        <title>Querying against specific fields</title>
+
+        <programlisting language="text"><![CDATA[
+title:"The Right Way" AND text:go
+]]></programlisting>
+
+        <para>
+            Searches for the phrase "The Right Way" within the <property>title</property> field and
+            the word "go" within the <property>text</property> field.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.fields-and-document">
+        <title>Querying against specific fields as well as the entire document</title>
+
+        <programlisting language="text"><![CDATA[
+title:"The Right Way" AND  go
+]]></programlisting>
+
+        <para>
+            Searches for the phrase "The Right Way" within the <property>title</property> field and
+            the word "go" word appearing in any field of the document.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.fields-and-document-alt">
+        <title>Querying against specific fields as well as the entire document (alternate)</title>
+
+        <programlisting language="text"><![CDATA[
+title:Do it right
+]]></programlisting>
+
+        <para>
+            Searches for the word "Do" within the <property>title</property> field and the words
+            "it" and "right" words through all fields; any single one matching will result in
+            a document match.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.wildcard-question">
+        <title>Querying with the wildcard "?"</title>
+
+        <programlisting language="text"><![CDATA[
+te?t
+]]></programlisting>
+
+        <para>
+            Search for words matching the pattern "te?t", where "?" is any single character.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.wildcard-asterisk">
+        <title>Querying with the wildcard "*"</title>
+
+        <programlisting language="text"><![CDATA[
+test*
+]]></programlisting>
+
+        <para>
+            Search for words matching the pattern "test*", where "*" is any sequence of zero or more
+            characters.
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.range-inclusive">
+        <title>Querying for an inclusive range of terms</title>
+
+        <programlisting language="text"><![CDATA[
+mod_date:[20020101 TO 20030101]
+]]></programlisting>
+
+        <para>
+            Search for the range of terms (inclusive).
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.range-exclusive">
+        <title>Querying for an exclusive range of terms</title>
+
+        <programlisting language="text"><![CDATA[
+title:{Aida to Carmen}
+]]></programlisting>
+
+        <para>
+            Search for the range of terms (exclusive).
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.fuzzy">
+        <title>Fuzzy searches</title>
+
+        <programlisting language="text"><![CDATA[
+roam~
+]]></programlisting>
+
+        <para>
+            Fuzzy search for the word "roam".
+        </para>
+    </example>
+
+    <example id="learning.lucene.queries.boolean">
+        <title>Boolean searches</title>
+
+        <programlisting language="text"><![CDATA[
+(framework OR library) AND php
+]]></programlisting>
+
+        <para>
+            Boolean query.
+        </para>
+    </example>
+
+    <para>
+        All supported queries can be constructed through <classname>Zend_Search_Lucene</classname>'s
+        <link linkend="zend.search.lucene.query-api"> query
+            construction API</link>. Moreover, query parsing and query constructing may be
+        combined:
+    </para>
+
+    <example id="learning.lucene.queries.combining">
+        <title>Combining parsed and constructed queries</title>
+
+        <programlisting language="php"><![CDATA[
+$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
+
+$query = new Zend_Search_Lucene_Search_Query_Boolean();
+$query->addSubquery($userQuery, true  /* required */);
+$query->addSubquery($constructedQuery, true  /* required */);
+]]></programlisting>
+    </example>
+</sect1>

+ 99 - 0
documentation/manual/de/tutorials/lucene-searching.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.lucene.searching">
+    <title>Searching</title>
+
+    <para>
+        Searching is performed by using the <methodname>find()</methodname> method:
+    </para>
+
+    <example id="learning.lucene.searching.search-example">
+        <title>Searching through the index</title>
+
+        <programlisting language="php"><![CDATA[
+$hits = $index->find($query);
+
+foreach ($hits as $hit) {
+    printf("%d %f %s\n", $hit->id, $hit->score, $hit->title);
+}
+]]></programlisting>
+    </example>
+
+    <para>
+        This example demonstrates the usage of two special search hit properties -
+        <property>id</property> and <property>score</property>.
+    </para>
+
+    <para>
+        <property>id</property> is an internal document identifier used within a Lucene index.
+        It may be used for a variety of operations, including deleting a document from the
+        index:
+    </para>
+
+    <example id="learning.lucene.searching.delete-example">
+        <title>Deleting an Indexed Document</title>
+
+        <programlisting language="php"><![CDATA[
+$index->delete($id);
+]]></programlisting>
+    </example>
+
+    <para>
+        Or retrieving the document from the index:
+    </para>
+
+    <example id="learning.lucene.searching.retrieve-example">
+        <title>Retrieving an Indexed Document</title>
+
+        <programlisting language="php"><![CDATA[
+$doc = $index->getDocument($id);
+]]></programlisting>
+    </example>
+
+    <note id="learning.lucene.searching.identifiers">
+        <title>Internal Document Identifiers</title>
+
+        <para>
+            Important note! Internal document identifiers may be changed by index optimization or
+            the auto-optimization process, but it's never changed within a single script's execution
+            unless the <methodname>addDocument()</methodname> (which may involve an
+            auto-optimization procedure) or <methodname>optimize()</methodname> methods are called.
+        </para>
+    </note>
+
+    <para>
+        The <property>score</property> field is a hit score. Search results are ordered by score by
+        default (best results returned first).
+    </para>
+
+    <para>
+        It's also possible to order result sets by specific field values. See the <link
+            linkend="zend.search.lucene.searching.sorting">
+            <classname>Zend_Search_Lucene</classname> documentation</link> for more details about
+        this possibility.
+    </para>
+
+    <para>
+        The example also demonstrates an ability to access stored fields (e.g.,
+        <command>$hit->title</command>). At the first access to any hit property other than
+        <property>id</property> or <property>score</property>, document stored fields are loaded,
+        and the corresponding field value is returned.
+    </para>
+
+    <para>
+        This causes an ambiguity for documents having their own <property>id</property> or
+        <property>score</property> fields; as a result, it's not recommended to use these field
+        names within stored documents. Nevertheless, they still can be accessed via the
+        <methodname>getDocument()</methodname> method:
+    </para>
+
+    <example id="learning.lucene.searching.id-score-fields">
+        <title>Accessing the original document's "id" and "score" fields</title>
+
+        <programlisting language="php"><![CDATA[
+$id    = $hit->getDocument()->id;
+$score = $hit->getDocument()->score;
+]]></programlisting>
+    </example>
+</sect1>

+ 184 - 0
documentation/manual/de/tutorials/multiuser-authentication.xml

@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.multiuser.authentication">
+    <title>Authenticating Users in Zend Framework</title>
+
+    <sect2 id="learning.multiuser.authentication.intro">
+        <title>Introduction to Authentication</title>
+
+        <para>
+            Once a web application has been able to distinguish one user from another by
+            establishing a session, web applications typically want to validate the identity
+            of a user. The process of validating a consumer as being authentic is "authentication."
+            Authentication is made up of two distinctive parts: an identity and a set of
+            credentials. It takes some variation of both presented to the application for
+            processing so that it may authenticate a user.
+        </para>
+
+        <para>
+            While the most common pattern of authentication revolves around usernames and
+            passwords, it should be stated that this is not always the case. Identities are
+            not limited to usernames. In fact, any public identifier can be used: an assigned
+            number, social security number, or residence address. Likewise, credentials are not
+            limited to passwords. Credentials can come in the form of protected private
+            information: fingerprint, eye retinal scan, passphrase, or any other obscure personal
+            information.
+        </para>
+
+    </sect2>
+
+    <sect2 id="learning.multiuser.authentication.basic-usage">
+        <title>Basic Usage of Zend_Auth</title>
+
+        <para>
+            In the following example, we will be using <classname>Zend_Auth</classname> to
+            complete what is probably the most prolific form of authentication: username and
+            password from a database table. This example assumes that you have already setup your
+            application using <classname>Zend_Application</classname>, and that inside that
+            application you have configured a database connection.
+        </para>
+
+        <para>
+            The job of the <classname>Zend_Auth</classname> class is twofold. First, it should
+            be able to accept an authentication adapter to use to authenticate a user. Secondly,
+            after a successful authentication of a user, it should persist throughout each and
+            every request that might need to know if the current user has indeed been
+            authenticated. To persist this data, <classname>Zend_Auth</classname> consumes
+            <classname>Zend_Session_Namespace</classname>, but you will generally never need
+            to interact with this session object.
+        </para>
+
+        <para>
+            Lets assume we have the following database table setup:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+CREATE TABLE users (
+    id INTEGER  NOT NULL PRIMARY KEY,
+    username VARCHAR(50) UNIQUE NOT NULL,
+    password VARCHAR(32) NULL,
+    password_salt VARCHAR(32) NULL,
+    real_name VARCHAR(150) NULL
+)
+]]></programlisting>
+
+        <para>
+            The above demonstrates a user table that includes a username, password, and also a
+            password salt column. This salt column is used as part of a technique called salting
+            that would improve the security of your database of information against brute force
+            attacks targeting the algorithm of your password hashing. <ulink
+                url="http://en.wikipedia.org/wiki/Salting_%28cryptography%29">More
+                information</ulink> on salting.
+        </para>
+
+        <para>
+            For this implementation, we must first make a simple form that we can utilized as
+            the "login form". We will use <classname>Zend_Form</classname> to accomplish this.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// located at application/forms/Auth/Login.php
+
+class Default_Form_Auth_Login extends Zend_Form
+{
+    public function init()
+    {
+        $this->setMethod('post');
+
+        $this->addElement(
+            'text', 'username', array(
+                'label' => 'Username:',
+                'required' => true,
+                'filters'    => array('StringTrim'),
+            ));
+
+        $this->addElement('password', 'password', array(
+            'label' => 'Password:',
+            'required' => true,
+            ));
+
+        $this->addElement('submit', 'submit', array(
+            'ignore'   => true,
+            'label'    => 'Login',
+            ));
+
+    }
+}
+]]></programlisting>
+
+        <para>
+            With the above form, we can now go about creating our login action for
+            our authentication controller. This controller will be called
+            "<classname>AuthController</classname>", and will be located at
+            <filename>application/controllers/AuthController.php</filename>. It will have a
+            single method called "<methodname>loginAction()</methodname>" which will serve as the
+            self-posting action. In other words, regardless of the url was POSTed to or GETed
+            to, this method will handle the logic.
+        </para>
+
+        <para>
+            The following code will demonstrate how to construct the proper adapter, integrate it
+            with the form:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class AuthController extends Zend_Controller_Action
+{
+
+    public function loginAction()
+    {
+        $db = $this->_getParam('db');
+
+        $loginForm = new Default_Form_Auth_Login($_POST);
+
+        if ($loginForm->isValid()) {
+
+            $adapter = new Zend_Auth_Adapter_DbTable(
+                $db,
+                'users',
+                'username',
+                'password',
+                'MD5(CONCAT(?, password_salt))'
+                );
+
+            $adapter->setIdentity($loginForm->getValue('username'));
+            $adapter->setCredential($loginForm->getValue('password'));
+
+            $result = $auth->authenticate($adapter);
+
+            if ($result->isValid()) {
+                $this->_helper->FlashMessenger('Successful Login');
+                $this->redirect('/');
+                return;
+            }
+
+        }
+
+        $this->view->loginForm = $loginForm;
+
+    }
+
+}
+]]></programlisting>
+
+        <para>
+            The corresponding view script is quite simple for this action. It will set the current
+            url since this form is self processing, and it will display the form. This view script
+            is located at <filename>application/views/scripts/auth/login.phtml</filename>:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$this->form->setAction($this->url());
+echo $this->form;
+]]></programlisting>
+
+        <para>
+            There you have it. With these basics you can expand the general concepts to include
+            more complex authentication scenarios. For more information on other
+            <classname>Zend_Auth</classname> adapters, have a look in
+            <link linkend="zend.auth">the reference guide</link>.
+        </para>
+    </sect2>
+</sect1>
+

+ 246 - 0
documentation/manual/de/tutorials/multiuser-authorization.xml

@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.multiuser.authorization">
+    <title>Building an Authorization System in Zend Framework</title>
+
+    <sect2 id="learning.multiuser.authorization.intro">
+        <title>Introduction to Authorization</title>
+
+        <para>
+            After a user has been identified as being authentic, an application can go about its
+            business of providing some useful and desirable resources to a consumer. In many cases,
+            applications might contain different resource types, with some resources having stricter
+            rules regarding access. This process of determining who has access to which resources is
+            the process of "authorization". Authorization in its simplest form is the composition of
+            these elements:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    the identity whom wishes to be granted access
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    the resource the identity is asking permission to consume
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    and optionally, what the identity is privileged to do with the resource
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            In Zend Framework, the <classname>Zend_Acl</classname> component handles the task of
+            building a tree of roles, resources and privileges to manage and query authorization
+            requests against.
+        </para>
+
+    </sect2>
+
+    <sect2 id="learning.multiuser.authorization.basic-usage">
+        <title>Basic Usage of Zend_Acl</title>
+
+<!-- explain the interaction with a User object, how -->
+
+        <para>
+            When using <classname>Zend_Acl</classname>, any models can serve as roles or resources
+            by simply implementing the proper interface. To be used in a role capacity, the class
+            must implement the <classname>Zend_Acl</classname>, which requires only
+            <methodname>getRoleId()</methodname>. To be used in a resource capacity, a class must
+            implement the <classname>Zend_Acl_Resource_Interface</classname> which similarly
+            requires the class implement the <methodname>getResourceId()</methodname> method.
+        </para>
+
+        <para>
+            Demonstrated below is a simple user model. This model can take part in our
+            <acronym>ACL</acronym> system simply by implementing the
+            <classname>Zend_Acl_Role_Interface</classname>. The method
+            <methodname>getRoleId()</methodname> will return the id "guest" when an ID is not known,
+            or it will return the role ID that was assigned to this actual user object. This value
+            can effectively come from anywhere, a static definition or perhaps dynamically from the
+            users database role itself.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Default_Model_User implements Zend_Acl_Role_Interface
+{
+    protected $_aclRoleId = null;
+
+    public function getRoleId()
+    {
+        if ($this->_aclRoleId == null) {
+            return 'guest';
+        }
+
+        return $this->_aclRoleId;
+    }
+}
+]]></programlisting>
+
+        <para>
+            While the concept of a user as a role is pretty straight forward, your application
+            might choose to have any other models in your system as a potential "resource" to be
+            consumed in this <acronym>ACL</acronym> system. For simplicity, we'll use the example
+            of a blog post. Since the type of the resource is tied to the type of the object,
+            this class will only return 'blogPost' as the resource ID in this system. Naturally,
+            this value can be dynamic if your system requires it to be so.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Default_Model_BlogPost implements Zend_Acl_Resource_Interface
+{
+    public function getResourceId()
+    {
+        return 'blogPost';
+    }
+}
+]]></programlisting>
+
+        <para>
+            Now that we have at least a role and a resource, we can go about defining the rules
+            of the <acronym>ACL</acronym> system. These rules will be consulted when the system
+            receives a query about what is possible given a certain role, resources, and optionally
+            a privilege.
+        </para>
+
+        <para>
+            Lets assume the following rules:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$acl = new Zend_Acl();
+
+// setup the various roles in our system
+$acl->addRole('guest');
+// owner inherits all of the rules of guest
+$acl->addRole('owner', 'guest');
+
+// add the resources
+$acl->addResource('blogPost');
+
+// add privileges to roles and resource combinations
+$acl->allow('guest', 'blogPost', 'view');
+$acl->allow('owner', 'blogPost', 'post');
+$acl->allow('owner', 'blogPost', 'publish');
+]]></programlisting>
+
+        <para>
+            The above rules are quite simple: a guest role and an owner role exist; as does a
+            blogPost type resource. Guests are allowed to view blog posts, and owners are
+            allowed to post and publish blog posts. To query this system one might do any of
+            the following:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// assume the user model is of type guest resource
+$guestUser = new Default_Model_User();
+$ownerUser = new Default_Model_Owner('OwnersUsername');
+
+$post = new Default_Model_BlogPost();
+
+$acl->isAllowed($guestUser, $post, 'view'); // true
+$acl->isAllowed($ownerUser, $post, 'view'); // true
+$acl->isAllowed($guestUser, $post, 'post'); // false
+$acl->isAllowed($ownerUser, $post, 'post'); // true
+]]></programlisting>
+
+        <para>
+            As you can see, the above rules exercise whether owners and guests can view posts,
+            which they can, or post new posts, which owners can and guests cannot. But as you
+            might expect this type of system might not be as dynamic as we wish it to be.
+            What if we want to ensure a specific owner actual owns a very specific blog post
+            before allowing him to publish it? In other words, we want to ensure that only post
+            owners have the ability to publish their own posts.
+        </para>
+
+        <para>
+            This is where assertions come in. Assertions are methods that will be called out to
+            when the static rule checking is simply not enough. When registering an assertion
+            object this object will be consulted to determine, typically dynamically, if some
+            roles has access to some resource, with some optional privlidge that can only be
+            answered by the logic within the assertion. For this example, we'll use the following
+            assertion:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class OwnerCanPublishBlogPostAssertion implements Zend_Acl_Assert_Interface
+{
+    /**
+     * This assertion should receive the actual User and BlogPost objects.
+     *
+     * @param Zend_Acl $acl
+     * @param Zend_Acl_Role_Interface $user
+     * @param Zend_Acl_Resource_Interface $blogPost
+     * @param $privilege
+     * @return bool
+     */
+    public function assert(Zend_Acl $acl,
+                           Zend_Acl_Role_Interface $user = null,
+                           Zend_Acl_Resource_Interface $blogPost = null,
+                           $privilege = null)
+    {
+        if (!$user instanceof Default_Model_User) {
+            throw new Exception(__CLASS__
+                              . '::'
+                              . __METHOD__
+                              . ' expects the role to be'
+                              . ' an instance of User');
+        }
+
+        if (!$blogPost instanceof Default_Model_BlogPost) {
+            throw new Exception(__CLASS__
+                              . '::'
+                              . __METHOD__
+                              . ' expects the resource to be'
+                              . ' an instance of BlogPost');
+        }
+
+        // if role is publisher, he can always modify a post
+        if ($user->getRoleId() == 'publisher') {
+            return true;
+        }
+
+        // check to ensure that everyone else is only modifying their own post
+        if ($user->id != null && $blogPost->ownerUserId == $user->id) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+]]></programlisting>
+
+        <para>
+            To hook this into our <acronym>ACL</acronym> system, we would do the following:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// replace this:
+//   $acl->allow('owner', 'blogPost', 'publish');
+// with this:
+$acl->allow('owner',
+            'blogPost',
+            'publish',
+            new OwnerCanPublishBlogPostAssertion());
+
+// lets also add the role of a "publisher" who has access to everything
+$acl->allow('publisher', 'blogPost', 'publish');
+]]></programlisting>
+
+        <para>
+            Now, anytime the <acronym>ACL</acronym> is consulted about whether or not an owner
+            can publish a specific blog post, this assertion will be run. This assertion will
+            ensure that unless the role type is 'publisher' the owner role must be logically
+            tied to the blog post in question. In this example, we check to see that the
+            <property>ownerUserId</property> property of the blog post matches the id of the
+            owner passed in.
+        </para>
+    </sect2>
+</sect1>

+ 76 - 0
documentation/manual/de/tutorials/multiuser-intro.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.multiuser.intro">
+    <title>Building Multi-User Applications With Zend Framework</title>
+
+    <sect2 id="learning.multiuser.intro.zf">
+        <title>Zend Framework</title>
+
+        <para>
+            When the original "web" was created, it was designed to be a publishing platform
+            for predominantly static content. As demand for content on the web grew, as did
+            the number of consumers on the internet for web content, the demand for using the
+            web as an application platform also grew. Since the web is inherently good at
+            delivering a simultaneous experience to many consumers from a single location,
+            it makes it an ideal environment for building dynamically driven, multi-user,
+            and more commonly today, social systems.
+        </para>
+
+        <para>
+            <acronym>HTTP</acronym> is the protocol of the web: a stateless, typically short
+            lived, request and response protocol. This protocol was designed this way because
+            the original intent of the web was to serve or publish static content. It is this
+            very design that has made the web as immensely successful as it is. It is also
+            exactly this design that brings new concerns to developers who wish to use the
+            web as an application platform.
+        </para>
+
+        <para>
+            These concerns and responsibilities can effectively be summed up by three questions:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    How do you distinguish one application consumer from another?
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    How do you identify a consumer as authentic?
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    How do you control what a consumer has access to?
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <note>
+            <title>Consumer Vs. User</title>
+
+            <para>
+                Notice we use the term "consumer" instead of person. Increasingly, web applications
+                are becoming service driven. This means that not only are real people ("users") with
+                real web browsers consuming and using your application, but also other web
+                applications through machine service technologies such as <acronym>REST</acronym>,
+                <acronym>SOAP</acronym>, and <acronym>XML-RPC</acronym>. In this respect,
+                people, as well as other consuming applications, should all be treated in same with
+                regard to the concerns outlined above.
+            </para>
+
+        </note>
+
+        <para>
+            In the following chapters, we'll take a look at these common problems relating to
+            authentication and authorization in detail. We will discover how 3 main components:
+            <classname>Zend_Session</classname>, <classname>Zend_Auth</classname>, and
+            <classname>Zend_Acl</classname>; provide an out-of-the-box solution as well as the
+            extension points each have that will cater to a more customized solution.
+        </para>
+    </sect2>
+</sect1>

+ 134 - 0
documentation/manual/de/tutorials/multiuser-sessions.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.multiuser.sessions">
+    <title>Managing User Sessions In ZF</title>
+
+    <sect2 id="learning.multiuser.sessions.intro">
+        <title>Introduction to Sessions</title>
+
+        <para>
+            The success of the web is deeply rooted in the protocol that drives the web: HTTP.  HTTP
+            over TCP is by its very nature stateless, which means that inherently the web is also
+            stateless.  While this very aspect is one of the dominating factors for why the web has
+            become such a popular medium, it also causes an interesting problem for developers that
+            want to use the web as an application platform.
+        </para>
+
+        <para>
+            The act of interacting with a web application is typically defined by the sum
+            of all requests sent to a web server.  Since there can be many consumers being served
+            simultaneously, the application must decide which requests belong to which consumer.  These
+            requests are typically known as a "session".
+        </para>
+
+        <para>
+            In PHP, the session problem is solved by the session extension which utilizes some state
+            tracking, typically cookies, and some form of local storage which is exposed via the
+            $_SESSION superglobal.  In Zend Framework, the component Zend_Session adds value to the php
+            session extension making it easier to use and depend on inside object-oriented
+            applications.
+        </para>
+
+    </sect2>
+
+    <sect2 id="learning.multiuser.sessions.basic-usage">
+        <title>Basic Usage of Zend_Session</title>
+
+        <para>
+            The Zend_Session component is both a session manager as well as an API for
+            storing data into a session object for long-term persistence.  The Zend_Session API is
+            for managing the options and behavior of a session, like options, starting and stopping
+            a session, whereas Zend_Session_Namespace is the actual object used to store data.
+        </para>
+
+        <para>
+            While its generally good practice to start a session inside a bootstrap process, this
+            is generally not necessary as all sessions will be automatically started upon the first
+            creation of a Zend_Session_Namespace object.
+        </para>
+
+        <para>
+            Zend_Application is capable of configuring Zend_Session for you as part of the
+            Zend_Application_Resource system.  To use this, assuming your project uses
+            Zend_Application to bootstrap, you would add the following code to your
+            application.ini file:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+resources.session.save_path = APPLICATION_PATH "/../data/session"
+resources.session.use_only_cookies = true
+resources.session.remember_me_seconds = 864000
+]]></programlisting>
+
+        <para>
+            As you can see, the options passed in are the same options that you'd expect to find
+            in the ext/session extension in PHP.  Those options setup the path to the session
+            files where data will be stored within the project.  Since ini files can additionally
+            use constants, the above will use the APPLICATION_PATH constant and relatively point
+            to a data session directory.
+        </para>
+
+        <para>
+            Most Zend Framework components that use sessions need nothing more to use Zend_Session.
+            At this point, you an either use a component that consumes Zend_Session, or start
+            storing your own data inside a session with Zend_Session_Namespace.
+        </para>
+
+        <para>
+            Zend_Session_Namespace is a simple class that proxies data via an easy to use API
+            into the Zend_Session managed $_SESSION superglobal.  The reason it is called
+            Zend_Session_Namespace is that it effectively namespaces the data inside $_SESSION, thus
+            allowing multiple components and objects to safely store and retrieve data.  In the
+            following code, we'll explore how to build a simple session incrementing counter, starting
+            at 1000 and resetting itself after 1999.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$mysession = Zend_Session_Namespace('mysession');
+
+if (!isset($mysession->counter)) {
+    $mysession->counter = 1000;
+} else {
+    $mysession->counter++;
+}
+
+if ($mysession->counter > 1999) {
+    unset($mysession->counter);
+}
+]]></programlisting>
+
+        <para>
+            As you can see above, the session namespace object uses the magic __get, __set,
+            __isset, and __unset to allow you to seemlessly and fluently interact with the session.
+            The information stored in the above example is stored at $_SESSION['mysession']['counter'].
+        </para>
+
+    </sect2>
+    <sect2 id="learning.multiuser.sessions.advanced-usage">
+        <title>Advanced Usage of Zend_Session</title>
+
+        <para>
+            Addionally, if you wanted to use the DbTable
+            save handler for Zend_Session, you'd add the following code to your application.ini:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
+resources.session.saveHandler.options.name = "session"
+resources.session.saveHandler.options.primary.session_id = "session_id"
+resources.session.saveHandler.options.primary.save_path = "save_path"
+resources.session.saveHandler.options.primary.name = "name"
+resources.session.saveHandler.options.primaryAssignment.sessionId = "sessionId"
+resources.session.saveHandler.options.primaryAssignment.sessionSavePath = "sessionSavePath"
+resources.session.saveHandler.options.primaryAssignment.sessionName = "sessionName"
+resources.session.saveHandler.options.modifiedColumn = "modified"
+resources.session.saveHandler.options.dataColumn = "session_data"
+resources.session.saveHandler.options.lifetimeColumn = "lifetime"
+]]></programlisting>
+
+
+    </sect2>
+
+
+</sect1>

+ 107 - 0
documentation/manual/de/tutorials/paginator-control.xml

@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.paginator.control">
+    <title>Pagination Control and ScrollingStyles</title>
+
+    <para>
+        Rendering the items for a page on the screen has been a good start. In the code
+        snippets in previous section we have also seen the <methodname>setCurrentPageNumber()</methodname>
+        method to set the active page number. The next step is to navigate through your pages.
+        To do this, Paginator provides you with two important tools: the ability to render the Paginator
+        with help of a View Partial, and support for so-called ScrollingStyles.
+    </para>
+
+    <para>
+        The View Partial is a small view script that renders the Pagination controls, such as buttons to go
+        to the next or previous page. Which pagination controls are rendered depends on the contents of
+        the view partial. Working with the view partial requires that you have set up Zend_View.
+        To get started with the pagination control, create a new view script somewhere in
+        your view scripts path. You can name it anything you want, but we'll call it "controls.phtml" in this text.
+        The reference manual contains various examples of what might go in the view script. Here is one example.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<?php if ($this->pageCount): ?>
+<!-- First page link -->
+<?php if (isset($this->previous)): ?>
+  <a href="<?php echo $this->url(array('page' => $this->first)); ?>">
+    First
+  </a> |
+<?php else: ?>
+  <span class="disabled">First</span> |
+<?php endif; ?>
+
+<!-- Previous page link -->
+<?php if (isset($this->previous)): ?>
+  <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
+    &lt; Previous
+  </a> |
+<?php else: ?>
+  <span class="disabled">&lt; Previous</span> |
+<?php endif; ?>
+
+<!-- Next page link -->
+<?php if (isset($this->next)): ?>
+  <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
+    Next &gt;
+  </a> |
+<?php else: ?>
+  <span class="disabled">Next &gt;</span> |
+<?php endif; ?>
+
+<!-- Last page link -->
+<?php if (isset($this->next)): ?>
+  <a href="<?php echo $this->url(array('page' => $this->last)); ?>">
+    Last
+  </a>
+<?php else: ?>
+  <span class="disabled">Last</span>
+<?php endif; ?>
+
+</div>
+<?php endif; ?>
+]]></programlisting>
+
+    <para>
+        The next step is to tell Zend_Paginator which view partial can be used to render
+        the navigation controls. Put the following line in your application's bootstrap file.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+Zend_View_Helper_PaginationControl::setDefaultViewPartial('controls.phtml');
+]]></programlisting>
+
+    <para>
+        The last step is probably the easiest. Make sure you have assigned your Paginator object
+        to the a script (NOT the 'controls.phtml' script!). The only thing left to do is echo the Paginator in the view script.
+        This will automatically render the Paginator using the PaginationControl view helper.
+        In this next example, the Paginator object has been assigned to the 'paginator' view variable.
+        Don't worry if you don't fully get how it all works yet. The next section will feature
+        a complete example.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<?php echo $this->paginator; ?>
+]]></programlisting>
+
+    <para>
+        <classname>Zend_Paginator</classname>, together with the 'controls.phtml' view script you wrote,
+        makes sure your Paginator navigation is rendered properly. In order to decide
+        which page numbers need to be displayed on screen, Paginator uses so-called ScrollingStyles.
+        The default style is called "Sliding", which is similar to the way Yahoo's search result
+        navigation works. To mimick Google's ScrollingStyle, use the Elastic style.
+        You can set a default ScrollingStyle with the static <methodname>setDefaultScrollingStyle()</methodname> method,
+        or you can specify a ScrollingStyle dynamically when rendering the Paginator in your view script. This
+        requires manual invocation of the view helper in your view script.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// $this->paginator is a Paginator object
+<?php echo $this->paginationControl($this->paginator, 'Elastic', 'controls.phtml'); ?>
+]]></programlisting>
+
+    <para>
+        For a list of all available ScrollingStyles, see the reference manual.
+    </para>
+</sect1>

+ 38 - 0
documentation/manual/de/tutorials/paginator-intro.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.paginator.intro">
+    <title>Introduction</title>
+
+    <para>
+        Let's say you're creating a blogging application that will be home to your vast
+        collection of blog posts. There is a good chance that you do not want all of
+        your blog posts to appear on one single page when someone visits your blog.
+        An obvious solution would be to only display a small number of blog posts
+        on the screen at a time, and allow the user to browse through the different pages,
+        much like your favorite search engine shows you the result of your search query.
+        <classname>Zend_Paginator</classname> is designed to help you achieve the goal of dividing collections
+        of data in smaller, more manageable sets more easily, with more consistency,
+        and with less duplicate code.
+    </para>
+
+    <para>
+        <classname>Zend_Paginator</classname> uses Adapters to support various data sources and ScrollingStyles
+        to support various methods of showing the user which pages are available.
+        In later sections of this text we will have a closer look at what these things
+        are and how they can help you to make the most out of <classname>Zend_Paginator</classname>.
+    </para>
+
+    <para>
+        Before going in-depth, we will have a look at some simple examples first.
+        After these simple examples, we will see how <classname>Zend_Paginator</classname> supports the most
+        common use-case; paginating database results.
+    </para>
+
+    <para>
+        This introduction has given you a quick overview of <classname>Zend_Paginator</classname>. To get
+        started and to have a look at some code snippets, let's have a look at some
+        simple examples.
+    </para>
+
+</sect1>

+ 125 - 0
documentation/manual/de/tutorials/paginator-simple.xml

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.paginator.simple">
+    <title>Simple Examples</title>
+
+    <para>
+        In this first example we won't do anything spectacular, but hopefully it will
+        give you a good idea of what Zend_Paginator is designed to do.
+        Let's say we have an array called $data with the numbers 1 to 100 in it, which
+        we want to divide over a number of pages. We can use the static <methodname>factory()</methodname>
+        method in the <classname>Zend_Paginator</classname> class to get a <classname>Zend_Paginator</classname>
+        object with our array in it.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// Create an array with numbers 1 to 100
+$data = range(1, 100);
+
+// Get a Paginator object using Zend_Paginator's built-in factory.
+$paginator = Zend_Paginator::factory($data);
+]]></programlisting>
+
+    <para>
+        We're already almost done! The $paginator variable now contains a reference to the
+        Paginator object. By default it is setup to display 10 items per page.
+        To display the items for the currently active page, all you need to do is iterate
+        over the Paginator object with a foreach loop. The currently active page defaults
+        to the first page if it's not explicitly specified. We will see how you can select
+        a specific page later on. The snippet below will display an unordered list containing the
+        numbers 1 to 10, which are the numbers on the first page.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// Create an array with numbers 1 to 100
+$data = range(1, 100);
+
+// Get a Paginator object using Zend_Paginator's built-in factory.
+$paginator = Zend_Paginator::factory($data);
+
+?><ul><?php
+
+// Render each item for the current page in a list-item
+foreach ($paginator as $item) {
+    echo '<li>' . $item . '</li>';
+}
+
+?></ul>
+]]></programlisting>
+
+    <para>
+        Now let's try and render the items on the second page. You can use the
+        <methodname>setCurrentPageNumber()</methodname> method to select which page you want to view.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// Create an array with numbers 1 to 100
+$data = range(1, 100);
+
+// Get a Paginator object using Zend_Paginator's built-in factory.
+$paginator = Zend_Paginator::factory($data);
+
+// Select the second page
+$paginator->setCurrentPageNumber(2);
+
+?><ul><?php
+
+// Render each item for the current page in a list-item
+foreach ($paginator as $item) {
+    echo '<li>' . $item . '</li>';
+}
+
+?></ul>
+]]></programlisting>
+
+    <para>
+        As expected, this little snippet will render an unordered list with the numbers
+        11 to 20 in it.
+    </para>
+
+    <para>
+        These simple examples demonstrate a small portion of what can be achieved with
+        <classname>Zend_Paginator</classname>. However, a real application rarely reads its data from a plain
+        array, so the next section is dedicated to showing you how you can use Paginator
+        to paginate the results of a database query. Before reading on, make sure you're familiar with
+        the way <classname>Zend_Db_Select</classname> works!
+    </para>
+
+    <para>
+        In the database examples we will look at a table with blog posts called 'posts'.
+        The 'posts' table has four columns: id, title, body, date_created.
+        Let's dive right in and have a look at a simple example.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// Create a select query. $db is a Zend_Db_Adapter object, which we assume
+// already exists in your script.
+$select = $db->select()->from('posts')->order('date_created DESC');
+
+// Get a Paginator object using Zend_Paginator's built-in factory.
+$paginator = Zend_Paginator::factory($select);
+
+// Select the second page
+$paginator->setCurrentPageNumber(2);
+
+?><ul><?php
+
+// Render each the title of each post for the current page in a list-item
+foreach ($paginator as $item) {
+    echo '<li>' . $item->title . '</li>';
+}
+
+?></ul>
+]]></programlisting>
+
+    <para>
+        As you can see, this example is not that different from the previous one.
+        The only difference is that you pass a <classname>Zend_Db_Select</classname> object to the
+        Paginator's <methodname>factory()</methodname> method, rather than an array.
+        For more details on how the database adapter makes sure that your query
+        is being executed efficiently, see the Zend_Paginator chapter in the reference manual
+        on the DbSelect and DbTableSelect adapters.
+    </para>
+
+</sect1>

+ 75 - 0
documentation/manual/de/tutorials/paginator-together.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.paginator.together">
+    <title>Putting it all Together</title>
+
+    <para>
+        You have seen how to create a Paginator object, how to render the items on the current page, and
+        how to render a navigation element to browse through your pages. In this section you will
+        see how Paginator fits in with the rest of your MVC application.
+    </para>
+
+    <para>
+        In the following examples we will ignore the best practice implementation of using a Service Layer to keep
+        the example simple and easier to understand. Once you get familiar with using Service Layers, it should be easy to see
+        how Paginator can fit in with the best practice approach.
+    </para>
+
+    <para>
+        Lets start with the controller. The sample application is simple, and we'll just put everything
+        in the IndexController and the IndexAction. Again, this is for demonstration purposes only. A real application
+        should not use controllers in this manner.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class IndexController extends Zend_Controller_Action
+{
+    public function indexAction()
+    {
+        // Setup pagination control view script. See the pagation control tutorial page
+        // for more information about this view script.
+        Zend_View_Helper_PaginationControl::setDefaultViewPartial('controls.phtml');
+
+        // Fetch an already instantiated database connection from the registry
+        $db = Zend_Registry::get('db');
+
+        // Create a select object which fetches blog posts, sorted decending by date of creation
+        $select = $db->select()->from('posts')->sort('date_created DESC');
+
+        // Create a Paginator for the blog posts query
+        $paginator = Zend_Paginator::factory($select);
+
+        // Read the current page number from the request. Default to 1 if no explicit page number is provided.
+        $paginator->setCurrentPageNumber($this->_getParam('page', 1));
+
+        // Assign the Paginator object to the view
+        $this->view->paginator = $paginator;
+    }
+}
+]]></programlisting>
+
+    <para>
+        The following view script is the index.phtml view script for the IndexController's indexAction.
+        The view script can be kept simple. We're assuming the use of the default ScrollingStyle.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<ul>
+<?php
+// Render each the title of each post for the current page in a list-item
+foreach ($this->paginator as $item) {
+    echo '<li>' . $item->title . '</li>';
+}
+?>
+</ul>
+<?php echo $this->paginator; ?>
+]]></programlisting>
+
+    <para>
+        Now navigate to your project's index and see Paginator in action. What we have discussed in this
+        tutorial is just the tip of the iceberg. The reference manual and API documentation can tell
+        you more about what you can do with Zend_Paginator.
+    </para>
+
+</sect1>

+ 63 - 0
documentation/manual/de/tutorials/plugins-conclusion.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.plugins.conclusion">
+    <title>Fazit</title>
+
+    <para>
+        Das Verstehen des Konzepts von Präfix Pfaden und dem Übersteuern von existierenden Plugins
+        hilft beim Verstehen von vielen Konzepten im Framework. Plugins werden in einer Vielzahl
+        von Orten verwendet:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                <classname>Zend_Application</classname>: Ressourcen.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Zend_Controller_Action</classname>: Action Helfer.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Zend_Feed_Reader</classname>: Plugins.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Zend_Form</classname>: Elemente, Filter, Prüfungen und Dekorateure.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <classname>Zend_View</classname>: View Helfer.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Und verschiedene andere Orte. Wenn man die Konzepte früh lernt kann man diesen wichtigen
+        Erweiterungspunkt im Zend Framework entsprechend umsetzen.
+    </para>
+
+    <note>
+        <title>Nachteile</title>
+
+        <para>
+            Wir haben erwähnt das <classname>Zend_Controller_Front</classname> ein Plugin System
+            hat - aber es hält sich nicht an irgendwelche Richtlinien die in diesem Tutorial
+            angeboten werden. Die im Front Controller registrierten Plugins müssen direkt
+            instanziert und individuell in Ihm registriert werden. Der Grund hierfür ist, dass das
+            System jedem anderen Plugin System im Zend Framework vorausgeht, und Änderungen an Ihm
+            müssen sorgfältig abgewägt werden um sicherzustellen das Plugins welche von Entwicklern
+            geschrieben wurden weiterhin funktionieren.
+        </para>
+    </note>
+</sect1>

+ 58 - 0
documentation/manual/de/tutorials/plugins-intro.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.plugins.intro">
+    <title>Einführung</title>
+
+    <para>
+        Zend Framework verwendet sehr stark Plugin Architekturen. Plugins erlauben eine einfache
+        Erweiterung und Anpassung vom Framework wärend der eigene Code vom Zend Framework Code
+        seperiert bleibt.
+    </para>
+
+    <para>
+        Typischerweise arbeiten Plugins im Zend Framework wie folgt:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                Plugins sind Klassen. Die aktuelle Klassendefinition ist unterschiedlich basierend
+                auf der Komponente -- man muss eine abstrakte Klasse erweitern oder ein Interface
+                implementieren, aber der Fakt bleibt bestehen dass das Plugin selbst eine Klasse
+                ist.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Zusammengehörende Plugins teilen sich einen gemeinsamen Klassenpräfix. Zum Beispiel
+                wenn man eine Anzahl von View Helfern erstellt, könnten alle den Klassenpräfix
+                "Foo_View_Helper_" teilen.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Alles nach dem gemeinsamen Präfix wird als <emphasis>Name des Plugins</emphasis>
+                oder <emphasis>Kurzname</emphasis> angenommen (gegenüber dem "langen Namen" welcher
+                der komplette Klassenname ist).  Wenn der Plugin Präfix zum Beispiel
+                "Foo_View_Helper_" ist, und der Klassenname "Foo_View_Helper_Bar", dann wird der
+                Name des Plugins einfach "Bar" sein.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Namen von Plugins sind typischerweise abhängig von der Schreibweise. Ein Nachteil
+                ist, das der initiale Buchstabe ost entweder klein- oder großgeschrieben ist; in
+                unserem vorherigen Beispiel würden beide, sowohl "bat" als auch "Bar" auf das
+                gleiche Plugin verweisen.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Jetzt sehen wir uns die Verwendung von Plugins an.
+    </para>
+</sect1>

+ 157 - 0
documentation/manual/de/tutorials/plugins-usage.xml

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.plugins.usage">
+    <title>Verwenden von Plugins</title>
+
+    <para>
+        Komponenten die Plugins verwenden, verwenden typischerweise
+        <classname>Zend_Loader_PluginLoader</classname> um Ihre Arbeit zu tun. Diese Klasse
+        registriert Plugins indem ein oder mehrere "Präfix Pfade" spezifiziert werden. Diese
+        Komponente ruft anschließend die <methodname>load()</methodname> Methode des PluginLoader's
+        auf, und übergibt Ihm den Kurznamen des Plugins. Der PluginLoader wird anschließend jeden
+        Präfix Pfad abfragen um zu sehen ob eine Klasse passt die dem Kurznamen entspricht.
+        Präfix Pfade werden also LIFO Reihenfolge (Last In, First Out) durchsucht, deshalb werden
+        jene Präfix Pfade abgeglichen die zuletzt registriert wurden -- was es erlaubt existierende
+        Plugins zu überladen.
+    </para>
+
+    <para>
+        Einige Beispiele werden das alles etwas aufklären.
+    </para>
+
+    <example id="learning.plugins.usage.basic">
+        <title>Grundsätzliches Plugin Beispiel: Hinzufügen eines einzelnen Präfix Pfades</title>
+
+        <para>
+            In diesem Beispiel nehmen wir an das einige Prüfungen geschrieben und im Verzeichnis
+            <filename>foo/plugins/validators/</filename> wurden, und das alle Klassen den
+            Klassenpräfix "Foo_Validate_" teilen; diese zwei Teile von Information formen unseren
+            "Präfix Pfad". Weiters nehmen wir an das wir zwei Prüfungen haben, einen der "Even"
+            genannt wird (und sicherstellt das eine Zahl die geprüft wird gerade ist), und eine
+            andere die "Dozens" genannt wird (und sicherstellt das eine Zahl ein Vielfaches von 12
+            ist). Die drei könnten wie folgt anschauen:
+        </para>
+
+        <programlisting language="text"><![CDATA[
+foo/
+|-- plugins/
+|   |-- validators/
+|   |   |-- Even.php
+|   |   |-- Dozens.php
+]]></programlisting>
+
+        <para>
+            Jetzt informieren wir eine <classname>Zend_Form_Element</classname> Instanz über diesen
+            Präfix Pfad. <classname>Zend_Form_Element</classname>'s
+            <methodname>addPrefixPath()</methodname> Methode erwartet ein drittes Argument welches
+            den Typ des Plugins zeigt für den der Pfad registriert wird; in diesem Fall ist es ein
+            "validate" Plugin.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$element->addPrefixPath('Foo_Validate', 'foo/plugins/validators/', 'validate');
+]]></programlisting>
+
+        <para>
+            Jetzt können wir dem Element einfach den kurzen Namen der Prüfung angeben die wir
+            verwenden wollen. Im folgenden Beispiel verwenden wir einen Mix aus Standardprüfungen
+            ("NotEmpty", "Int") und eigenen Prüfungen ("Even", "Dozens").
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$element->addValidator('NotEmpty')
+        ->addValidator('Int')
+        ->addValidator('Even')
+        ->addValidator('Dozens');
+]]></programlisting>
+
+        <para>
+            Wenn das Element geprüft werden soll, ruft es die Plugin Klasse vom PluginLoader ab.
+            Die ersten zwei Prüfungen werden zu <classname>Zend_Validate_NotEmpty</classname> und
+            <classname>Zend_Validate_Int</classname> aufgelöst; die nächsten zwei werden zu
+            <classname>Foo_Validate_Even</classname> und <classname>Foo_Validate_Dozens</classname>
+            aufgelöst.
+        </para>
+    </example>
+
+    <note>
+        <title>Was passiert wenn ein Plugin nicht gefunden wird?</title>
+
+        <para>
+            Was passiert wenn ein Plugin angefragt wird, aber der PluginLoader nicht in der Lage ist
+            eine zu Ihm passende Klasse zu finden? Im obigen Beispiel, zum Beispiel, wenn wir das
+            Plugin "Bar" mit dem Element registrieren, was würde dann passieren?
+        </para>
+
+        <para>
+            Der Plugin Loader durchsucht jeden Präfix Pfad, prüft ob eine Datei gefunden wird die
+            in diesem Pfad auf den Plugin Namen passt. Wenn die Datei nicht gefunden wird, geht er
+            auf den nächsten Präfix Pfad weiter.
+        </para>
+
+        <para>
+            Sobald der Stack von Präfix Pfaden erschöpft ist, und keine passende Datei gefunden
+            wurde, wirft es eine <exceptionname>Zend_Loader_PluginLoader_Exception</exceptionname>.
+        </para>
+    </note>
+
+    <example id="learning.plugins.usage.override">
+        <title>Fortgeschrittene Plugin Verwendung: Überladen existierender Plugins</title>
+
+        <para>
+            Eine Stärke des PluginLoaders ist dessen Verwendung eines LIFO Stacks welche es erlaubt
+            existierende Plugins zu überladen indem eine eigene Version lokal mit einem anderen
+            Präfix Pfad erstellt wird, und der Präfix Pfad später im Stack registriert wird.
+        </para>
+
+        <para>
+            Nehmen wir zum Beispiel <classname>Zend_View_Helper_FormButton</classname> an (View
+            Helfer sind eine Form von Plugins). Dieser View Helfer akzeptiert drei Argumente, ein
+            Elementname (der auch als DOM Identifikator des Elements verwendet wird), einen Wert
+            (der als Button Label verwendet wird), und ein optionales Array an Attributen. Der
+            Helfer erzeugt dann das HTML Markup für ein Formular Eingabeelement.
+        </para>
+
+        <para>
+            Sagen wir, dass der Helfer stattdessen ein echtes HTML <constant>button</constant>
+            Element erzeugen soll; dass wir nicht wollen das der Helfer einen DOM Identifikator
+            erzeugt, sondern statt dessen den Wert für einen CSS Klassen Selektor; und das wir kein
+            Interesse an der behandling eigener Attribute haben. Man könnte dies auf verschiedenen
+            wegen erreichen. In beiden Fällen erstellen wir eine eigene View Helfer Klasse die das
+            Verhalten implementiert welches wir wollen; der Unterschied liegt darin wie wir Sie
+            benennen und aufrufen wollen.
+        </para>
+
+        <para>
+            Unser erstes Beispiel wird der Name des Elements mit einem eindeutigen Namen sein:
+            <classname>Foo_View_Helper_CssButton</classname> welcher den Plugin Namen "CssButton"
+            impliziert. Wärend das ein recht brauchbarer Ansatz ist, wirft es einige Probleme auf:
+            Wenn man bereits einen Button View Helfer im eigenen Code verwendet, muss man jetzt
+            einges umarbeiten; alternativ, wenn ein anderer Entwickler damit beginnt Code für diese
+            Anwendung zu schreiben, mus er unbeabsichtlicher Weise den Button View Helfer verwenden
+            statt den neuen View Helfer.
+        </para>
+
+        <para>
+            Deshalb ist es better den Plugin Namen "Button" zu verwenden was uns den Klassennamen
+            <classname>Foo_View_Helper_Button</classname> gibt. Wir registrieren den Präfix Pfad in
+            der View:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// Zend_View::addHelperPath() verwendet den PluginLoader; Trotzdem invertiert
+// er die Argumente, da er den Standardwert "Zend_View_Helper" für den Plugin
+// Präfix anbietet.
+//
+// Anbei nehmen wir an das die eigene Klasse im Verzeichnis
+// 'foo/view/helpers/' ist.
+$view->addHelperPath('foo/view/helpers', 'Foo_View_Helper');
+]]></programlisting>
+
+        <para>
+            Sobald das getan wurde, wird überall wo wir den "Button" Helfer verwenden auf die
+            eigene <classname>Foo_View_Helper_Button</classname> Klasse verwiesen!
+        </para>
+    </example>
+</sect1>

+ 17 - 0
documentation/manual/de/tutorials/quickstart-conclusion.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.quickstart.conclusion">
+    <title>Gratulation!</title>
+
+    <para>
+        Es wurde eine sehr einfache Anwendung erstellt indem einige der üblichsten Zend Framework
+        Komponenten verwendet wurden. Zend Framework stellt viele Komponenten zur Verfügung welche
+        übliche Anforderungen für Web Anwendungen behandeln, inklusive Web Services, Suchen, PDFs
+        Lesen und Schreiben, Authentifizierung, Authorisierung und viele mehr. Der <link
+            linkend="reference">Referenz Guide</link> ist ein großartiger Platz um mehr über die
+        Komponenten zu erfahren welche man in diesem Schnellstart verwendet hat, wie auch über
+        andere Komponenten. Wir hoffen das Sie Zend Framework nützlich finden - und wichtiger -
+        Spass damit haben!
+    </para>
+</sect1>

+ 172 - 0
documentation/manual/de/tutorials/quickstart-create-form.xml

@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.quickstart.create-form">
+    <title>Create A Form</title>
+
+    <para>
+        For our guestbook to be useful, we need a form for submitting new entries.
+    </para>
+
+    <para>
+        Our first order of business is to create the actual form class. First, create the directory
+        <filename>application/forms/</filename>. This directory will contain form classes for the
+        application. Next, we'll create a form class in
+        <filename>application/forms/Guestbook.php</filename>:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/forms/Guestbook.php
+
+class Default_Form_Guestbook extends Zend_Form
+{
+    public function init()
+    {
+        // Set the method for the display form to POST
+        $this->setMethod('post');
+
+        // Add an email element
+        $this->addElement('text', 'email', array(
+            'label'      => 'Your email address:',
+            'required'   => true,
+            'filters'    => array('StringTrim'),
+            'validators' => array(
+                'EmailAddress',
+            )
+        ));
+
+        // Add the comment element
+        $this->addElement('textarea', 'comment', array(
+            'label'      => 'Please Comment:',
+            'required'   => true,
+            'validators' => array(
+                array('validator' => 'StringLength', 'options' => array(0, 20))
+                )
+        ));
+
+        // Add a captcha
+        $this->addElement('captcha', 'captcha', array(
+            'label'      => 'Please enter the 5 letters displayed below:',
+            'required'   => true,
+            'captcha'    => array(
+                'captcha' => 'Figlet',
+                'wordLen' => 5,
+                'timeout' => 300
+            )
+        ));
+
+        // Add the submit button
+        $this->addElement('submit', 'submit', array(
+            'ignore'   => true,
+            'label'    => 'Sign Guestbook',
+        ));
+
+        // And finally add some CSRF protection
+        $this->addElement('hash', 'csrf', array(
+            'ignore' => true,
+        ));
+    }
+}
+]]></programlisting>
+
+    <para>
+        The above form defines five elements: an email address field, a comment field, a CAPTCHA for
+        preventing spam submissions, a submit button, and a CSRF protection token.
+    </para>
+
+    <para>
+        Next, we will add a <methodname>signAction()</methodname> to our
+        <classname>GuestbookController</classname> which will process the form upon submission. To
+        create the action and related view script, execute the following:
+    </para>
+
+    <programlisting language="shell"><![CDATA[
+# Unix-like systems:
+% zf.sh create action sign guestbook
+
+# DOS/Windows:
+C:> zf.bat create action sign guestbook
+]]></programlisting>
+
+    <para>
+        This will create a <methodname>signAction()</methodname> method in our controller, as well
+        as the appropriate view script.
+    </para>
+
+    <para>
+        Let's add some logic into our guestbook controller's sign action. We need to first check if
+        we're getting a POST or a GET request; in the latter case, we'll simply display the form.
+        However, if we get a POST request, we'll want to validate the posted data against our form,
+        and, if valid, create a new entry and save it. The logic might look like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/controllers/GuestbookController.php
+
+class GuestbookController extends Zend_Controller_Action
+{
+    // snipping indexAction()...
+
+    public function signAction()
+    {
+        $request = $this->getRequest();
+        $form    = new Default_Form_Guestbook();
+
+        if ($this->getRequest()->isPost()) {
+            if ($form->isValid($request->getPost())) {
+                $model = new Default_Model_Guestbook($form->getValues());
+                $model->save();
+                return $this->_helper->redirector('index');
+            }
+        }
+
+        $this->view->form = $form;
+    }
+}
+]]></programlisting>
+
+    <para>
+        Of course, we also need to edit the view script; edit <filename>application/views/scripts/guestbook/sign.phtml</filename> to read:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<!-- application/views/scripts/guestbook/sign.phtml -->
+
+Please use the form below to sign our guestbook!
+
+<?php
+$this->form->setAction($this->url());
+echo $this->form;
+]]></programlisting>
+
+    <note>
+        <title>Better Looking Forms</title>
+
+        <para>
+            No one will be waxing poetic about the beauty of this form anytime soon. No matter -
+            form appearance is fully customizable! See the <link
+                linkend="zend.form.decorators">decorators section in the reference guide</link>
+            for details.
+        </para>
+
+        <para>
+            Additionally, you may be interested in <ulink
+                url="http://weierophinney.net/matthew/plugin/tag/decorators">this series of posts on
+                decorators</ulink>.
+        </para>
+    </note>
+
+    <note>
+        <title>Checkpoint</title>
+
+        <para>
+            Now browse to "http://localhost/guestbook/sign". You should see the following in your
+            browser:
+        </para>
+
+        <para>
+            <inlinegraphic width="421" scale="100" align="center" valign="middle"
+                fileref="figures/learning.quickstart.create-form.png" format="PNG" />
+        </para>
+    </note>
+</sect1>

+ 214 - 0
documentation/manual/de/tutorials/quickstart-create-layout.xml

@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- 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 HTML 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 HTML 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 Zend_Layout, first we need to inform our bootstrap to use the
+        <classname>Layout</classname> resource. This can be done by adding the following line to
+        your <filename>application/configs/application.ini</filename> file, 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 INI 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"
+resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
+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>. Create those directories now.
+    </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
+
+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 HTML 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>

+ 761 - 0
documentation/manual/de/tutorials/quickstart-create-model.xml

@@ -0,0 +1,761 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.quickstart.create-model">
+    <title>Create a Model and Database Table</title>
+
+    <para>
+        Before we get started, let's consider something: where will these classes live, and how will
+        we find them? The default project we created instantiates an autoloader. We can attach other
+        autoloaders to it so that it knows where to find different classes. Typically, we want our
+        various MVC classes grouped under the same tree -- in this case,
+        <filename>application/</filename> -- and most often using a common prefix.
+    </para>
+
+    <para>
+        <classname>Zend_Controller_Front</classname> has a notion of "modules", which are individual
+        mini-applications.  Modules mimic the directory structure that the <command>zf</command>
+        tool sets up under <filename>application/</filename>, and all classes inside them are
+        assumed to begin with a common prefix, the module name.  <filename>application/</filename>
+        is itself a module -- the "default" module. As such, let's setup autoloading for resources
+        within this directory, giving them a prefix of "Default". We can do this by creating another
+        bootstrap resource.
+    </para>
+
+    <para>
+        <classname>Zend_Application_Module_Autoloader</classname> provides the functionality needed
+        to map the various resources under a module to the appropriate directories, and provides a
+        standard naming mechanism as well. In our bootstrap resource, we'll instantiate this, and be
+        done. The method looks like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/Bootstrap.php
+
+// Add this method to the Bootstrap class:
+
+    protected function _initAutoload()
+    {
+        $autoloader = new Zend_Application_Module_Autoloader(array(
+            'namespace' => 'Default_',
+            'basePath'  => dirname(__FILE__),
+        ));
+        return $autoloader;
+    }
+]]></programlisting>
+
+    <para>
+        The final bootstrap class will look as follows:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/Bootstrap.php
+
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+    protected function _initAutoload()
+    {
+        $autoloader = new Zend_Application_Module_Autoloader(array(
+            'namespace' => 'Default',
+            'basePath'  => dirname(__FILE__),
+        ));
+        return $autoloader;
+    }
+
+    protected function _initDoctype()
+    {
+        $this->bootstrap('view');
+        $view = $this->getResource('view');
+        $view->doctype('XHTML1_STRICT');
+    }
+}
+]]></programlisting>
+
+    <para>
+        Now, let's consider what makes up a guestbook. Typically, they are simply a list of entries
+        with a <emphasis>comment</emphasis>, <emphasis>timestamp</emphasis>, and, often,
+        <emphasis>email address</emphasis>. Assuming we store them in a database, we may also want a
+        <emphasis>unique identifier</emphasis> for each entry. We'll likely want to be able to save
+        an entry, fetch individual entries, and retrieve all entries. As such, a simple guestbook
+        model API might look something like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/models/Guestbook.php
+
+class Default_Model_Guestbook
+{
+    protected $_comment;
+    protected $_created;
+    protected $_email;
+    protected $_id;
+
+    public function __set($name, $value);
+    public function __get($name);
+
+    public function setComment($text);
+    public function getComment();
+
+    public function setEmail($email);
+    public function getEmail();
+
+    public function setCreated($ts);
+    public function getCreated();
+
+    public function setId($id);
+    public function getId();
+
+    public function save();
+    public function find($id);
+    public function fetchAll();
+}
+]]></programlisting>
+
+    <para>
+        <methodname>__get()</methodname> and <methodname>__set()</methodname> will provide a
+        convenience mechanism for us to access the individual entry properties, and proxy to the
+        other getters and setters. They also will help ensure that only properties we whitelist will
+        be available in the object.
+    </para>
+
+    <para>
+        <methodname>find()</methodname> and <methodname>fetchAll()</methodname> provide the ability
+        to fetch a single entry or all entries.
+    </para>
+
+    <para>
+        Now from here, we can start thinking about setting up our database.
+    </para>
+
+    <para>
+        First we need to initialize our <classname>Db</classname> resource. As with the
+        <classname>Layout</classname> and <classname>View</classname> resource, we can provide
+        configuration for the <classname>Db</classname> resource. In your
+        <filename>application/configs/application.ini</filename> file, add the following lines in
+        the appropriate sections.
+    </para>
+
+    <programlisting language="ini"><![CDATA[
+; application/configs/application.ini
+
+; Add these lines to the appropriate sections:
+[production]
+resources.db.adapter       = "PDO_SQLITE"
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
+
+[testing : production]
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
+
+[development : production]
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
+]]></programlisting>
+
+    <para>
+        Your final configuration file should look like the following:
+    </para>
+
+    <programlisting language="ini"><![CDATA[
+; application/configs/application.ini
+
+[production]
+phpSettings.display_startup_errors = 0
+phpSettings.display_errors = 0
+bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
+bootstrap.class = "Bootstrap"
+resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
+resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
+resources.view[] =
+resources.db.adapter = "PDO_SQLITE"
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
+
+[staging : production]
+
+[testing : production]
+phpSettings.display_startup_errors = 1
+phpSettings.display_errors = 1
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
+
+[development : production]
+phpSettings.display_startup_errors = 1
+phpSettings.display_errors = 1
+resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
+]]></programlisting>
+
+    <para>
+        Note that the database(s) will be stored in <filename>data/db/</filename>. Create those
+        directories, and make them world-writeable. On unix-like systems, you can do that as
+        follows:
+    </para>
+
+    <programlisting language="shell"><![CDATA[
+% mkdir -p data/db; chmod -R a+rwX data
+]]></programlisting>
+
+    <para>
+        On Windows, you will need to create the directories in Explorer and set the permissions to
+        allow anyone to write to the directory.
+    </para>
+
+    <para>
+        At this point we have a connection to a database; in our case, its a connection to a Sqlite
+        database located inside our <filename>application/data/</filename> directory. So, let's
+        design a simple table that will hold our guestbook entries.
+    </para>
+
+    <programlisting language="sql"><![CDATA[
+-- scripts/schema.sqlite.sql
+--
+-- You will need load your database schema with this SQL.
+
+CREATE TABLE guestbook (
+    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+    email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
+    comment TEXT NULL,
+    created DATETIME NOT NULL
+);
+
+CREATE INDEX "id" ON "guestbook" ("id");
+]]></programlisting>
+
+    <para>
+        And, so that we can have some working data out of the box, lets create a few rows of
+        information to make our application interesting.
+    </para>
+
+    <programlisting language="sql"><![CDATA[
+-- scripts/data.sqlite.sql
+--
+-- You can begin populating the database with the following SQL statements.
+
+INSERT INTO guestbook (email, comment, created) VALUES
+    ('ralph.schindler@zend.com',
+    'Hello! Hope you enjoy this sample zf application!',
+    DATETIME('NOW'));
+INSERT INTO guestbook (email, comment, created) VALUES
+    ('foo@bar.com',
+    'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
+    DATETIME('NOW'));
+]]></programlisting>
+
+    <para>
+        Now that we have both the schema and some data defined. Lets get a script together that we
+        can now execute to build this database. Naturally, this is not needed in production, but
+        this script will help developers build out the database requirements locally so they can
+        have the fully working application. Create the script as
+        <filename>scripts/load.sqlite.php</filename> with the following contents:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// scripts/load.sqlite.php
+
+/**
+ * Script for creating and loading database
+ */
+
+// Initialize the application path and autoloading
+defined('APPLICATION_PATH')
+    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
+set_include_path(implode(PATH_SEPARATOR, array(
+    APPLICATION_PATH . '/../library',
+    get_include_path(),
+)));
+require_once 'Zend/Loader/Autoloader.php';
+Zend_Loader_Autoloader::getInstance();
+
+// Define some CLI options
+$getopt = new Zend_Console_Getopt(array(
+    'withdata|w' => 'Load database with sample data',
+    'env|e-s'    => 'Application environment for which to create database (defaults to development)',
+    'help|h'     => 'Help -- usage message',
+));
+try {
+    $getopt->parse();
+} catch (Zend_Console_Getopt_Exception $e) {
+    // Bad options passed: report usage
+    echo $e->getUsageMessage();
+    return false;
+}
+
+// If help requested, report usage message
+if ($getopt->getOption('h')) {
+    echo $getopt->getUsageMessage();
+    return true;
+}
+
+// Initialize values based on presence or absence of CLI options
+$withData = $getopt->getOption('w');
+$env      = $getopt->getOption('e');
+defined('APPLICATION_ENV')
+    || define('APPLICATION_ENV', (null === $env) ? 'development' : $env);
+
+// Initialize Zend_Application
+$application = new Zend_Application(
+    APPLICATION_ENV,
+    APPLICATION_PATH . '/configs/application.ini'
+);
+
+// Initialize and retrieve DB resource
+$bootstrap = $application->getBootstrap();
+$bootstrap->bootstrap('db');
+$dbAdapter = $bootstrap->getResource('db');
+
+// let the user know whats going on (we are actually creating a
+// database here)
+if ('testing' != APPLICATION_ENV) {
+    echo 'Writing Database Guestbook in (control-c to cancel): ' . PHP_EOL;
+    for ($x = 5; $x > 0; $x--) {
+        echo $x . "\r"; sleep(1);
+    }
+}
+
+// Check to see if we have a database file already
+$options = $bootstrap->getOption('resources');
+$dbFile  = $options['db']['params']['dbname'];
+if (file_exists($dbFile)) {
+    unlink($dbFile);
+}
+
+// this block executes the actual statements that were loaded from
+// the schema file.
+try {
+    $schemaSql = file_get_contents(dirname(__FILE__) . '/schema.sqlite.sql');
+    // use the connection directly to load sql in batches
+    $dbAdapter->getConnection()->exec($schemaSql);
+    chmod($dbFile, 0666);
+
+    if ('testing' != APPLICATION_ENV) {
+        echo PHP_EOL;
+        echo 'Database Created';
+        echo PHP_EOL;
+    }
+
+    if ($withData) {
+        $dataSql = file_get_contents(dirname(__FILE__) . '/data.sqlite.sql');
+        // use the connection directly to load sql in batches
+        $dbAdapter->getConnection()->exec($dataSql);
+        if ('testing' != APPLICATION_ENV) {
+            echo 'Data Loaded.';
+            echo PHP_EOL;
+        }
+    }
+
+} catch (Exception $e) {
+    echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
+    echo $e->getMessage() . PHP_EOL;
+    return false;
+}
+
+// generally speaking, this script will be run from the command line
+return true;
+]]></programlisting>
+
+    <para>
+        Now, let's execute this script. From a terminal or the DOS command line, do the following:
+    </para>
+
+    <programlisting language="shell"><![CDATA[
+% php scripts/load.sqlite.php --withdata
+]]></programlisting>
+
+    <para>
+        You should see output like the following:
+    </para>
+
+    <programlisting language="text"><![CDATA[
+path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
+Writing Database Guestbook in (control-c to cancel):
+1
+Database Created
+Data Loaded.
+]]></programlisting>
+
+    <para>
+        Now we have a fully working database and table for our guestbook application. Our next few
+        steps are to build out our application code. This includes building a data source (in our
+        case, we will use <classname>Zend_Db_Table</classname>), and a data mapper to connect that
+        data source to our domain model. Finally we'll also create the controller that will interact
+        with this model to both display existing entries and process new entries.
+    </para>
+
+    <para>
+        We'll use a <ulink url="http://martinfowler.com/eaaCatalog/tableDataGateway.html">Table Data
+            Gateway</ulink> to connect to our data source; <classname>Zend_Db_Table</classname>
+        provides this functionality. To get started, lets create a
+        <classname>Zend_Db_Table</classname>-based table class. First, create the directory
+        <filename>application/models/DbTable/</filename>. Then create and edit a file
+        <filename>Guestbook.php</filename> within it, and add the following contents:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/models/DbTable/Guestbook.php
+
+/**
+ * This is the DbTable class for the guestbook table.
+ */
+class Default_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
+{
+    /** Table name */
+    protected $_name    = 'guestbook';
+}
+]]></programlisting>
+
+    <para>
+        Note the class prefix: <classname>Default_Model_DbTable</classname>. The class prefix
+        "Default" from our autoloader is the first segment, and then we have the component,
+        "Model_DbTable"; the latter is mapped to the <filename>models/DbTable/</filename> directory
+        of the module.
+    </para>
+
+    <para>
+        All that is truly necessary when extending <classname>Zend_Db_Table</classname> is to
+        provide a table name and optionally the primary key (if it is not "id").
+    </para>
+
+    <para>
+        Now let's create a <ulink url="http://martinfowler.com/eaaCatalog/dataMapper.html">Data
+            Mapper</ulink>. A <emphasis>Data Mapper</emphasis> maps a domain object to the database.
+        In our case, it will map our model, <classname>Default_Model_Guestbook</classname>, to our
+        data source, <classname>Default_Model_DbTable_Guestbook</classname>. A typical API for a
+        data mapper is as follows:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/models/GuestbookMapper.php
+
+class Default_Model_GuestbookMapper
+{
+    public function save($model);
+    public function find($id, $model);
+    public function fetchAll();
+}
+]]></programlisting>
+
+    <para>
+        In addition to these methods, we'll add methods for setting and retrieving the Table Data
+        Gateway. The final class, located in
+        <filename>application/models/GuestbookMapper.php</filename>, looks like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/models/GuestbookMapper.php
+
+class Default_Model_GuestbookMapper
+{
+    protected $_dbTable;
+
+    public function setDbTable($dbTable)
+    {
+        if (is_string($dbTable)) {
+            $dbTable = new $dbTable();
+        }
+        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
+            throw new Exception('Invalid table data gateway provided');
+        }
+        $this->_dbTable = $dbTable;
+        return $this;
+    }
+
+    public function getDbTable()
+    {
+        if (null === $this->_dbTable) {
+            $this->setDbTable('Default_Model_DbTable_Guestbook');
+        }
+        return $this->_dbTable;
+    }
+
+    public function save(Default_Model_Guestbook $guestbook)
+    {
+        $data = array(
+            'email'   => $guestbook->getEmail(),
+            'comment' => $guestbook->getComment(),
+            'created' => date('Y-m-d H:i:s'),
+        );
+
+        if (null === ($id = $guestbook->getId())) {
+            unset($data['id']);
+            $this->getDbTable()->insert($data);
+        } else {
+            $this->getDbTable()->update($data, array('id = ?' => $id));
+        }
+    }
+
+    public function find($id, Default_Model_Guestbook $guestbook)
+    {
+        $result = $this->getDbTable()->find($id);
+        if (0 == count($result)) {
+            return;
+        }
+        $row = $result->current();
+        $guestbook->setId($row->id)
+                  ->setEmail($row->email)
+                  ->setComment($row->comment)
+                  ->setCreated($row->created);
+    }
+
+    public function fetchAll()
+    {
+        $resultSet = $this->getDbTable()->fetchAll();
+        $entries   = array();
+        foreach ($resultSet as $row) {
+            $entry = new Default_Model_Guestbook();
+            $entry->setId($row->id)
+                  ->setEmail($row->email)
+                  ->setComment($row->comment)
+                  ->setCreated($row->created)
+                  ->setMapper($this);
+            $entries[] = $entry;
+        }
+        return $entries;
+    }
+}
+]]></programlisting>
+
+    <para>
+        Now it's time to update our model class slightly, to accomodate the data mapper. Just like
+        the data mapper contains a reference to the data source, the model contains a reference to
+        the data mapper. Additionally, we'll make it easy to populate the model by passing an array
+        of data either to the constructor or a <methodname>setOptions()</methodname> method. The
+        final model class, located in <filename>application/models/Guestbook.php</filename>, looks
+        like this:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/models/Guestbook.php
+
+class Default_Model_Guestbook
+{
+    protected $_comment;
+    protected $_created;
+    protected $_email;
+    protected $_id;
+    protected $_mapper;
+
+    public function __construct(array $options = null)
+    {
+        if (is_array($options)) {
+            $this->setOptions($options);
+        }
+    }
+
+    public function __set($name, $value)
+    {
+        $method = 'set' . $name;
+        if (('mapper' == $name) || !method_exists($this, $method)) {
+            throw new Exception('Invalid guestbook property');
+        }
+        $this->$method($value);
+    }
+
+    public function __get($name)
+    {
+        $method = 'get' . $name;
+        if (('mapper' == $name) || !method_exists($this, $method)) {
+            throw new Exception('Invalid guestbook property');
+        }
+        return $this->$method();
+    }
+
+    public function setOptions(array $options)
+    {
+        $methods = get_class_methods($this);
+        foreach ($options as $key => $value) {
+            $method = 'set' . ucfirst($key);
+            if (in_array($method, $methods)) {
+                $this->$method($value);
+            }
+        }
+        return $this;
+    }
+
+    public function setComment($text)
+    {
+        $this->_comment = (string) $text;
+        return $this;
+    }
+
+    public function getComment()
+    {
+        return $this->_comment;
+    }
+
+    public function setEmail($email)
+    {
+        $this->_email = (string) $email;
+        return $this;
+    }
+
+    public function getEmail()
+    {
+        return $this->_email;
+    }
+
+    public function setCreated($ts)
+    {
+        $this->_created = $ts;
+        return $this;
+    }
+
+    public function getCreated()
+    {
+        return $this->_created;
+    }
+
+    public function setId($id)
+    {
+        $this->_id = (int) $id;
+        return $this;
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function setMapper($mapper)
+    {
+        $this->_mapper = $mapper;
+        return $this;
+    }
+
+    public function getMapper()
+    {
+        if (null === $this->_mapper) {
+            $this->setMapper(new Default_Model_GuestbookMapper());
+        }
+        return $this->_mapper;
+    }
+
+    public function save()
+    {
+        $this->getMapper()->save($this);
+    }
+
+    public function find($id)
+    {
+        $this->getMapper()->find($id, $this);
+        return $this;
+    }
+
+    public function fetchAll()
+    {
+        return $this->getMapper()->fetchAll();
+    }
+}
+]]></programlisting>
+
+    <para>
+        Lastly, to connect these elements all together, lets create a guestbook controller that will
+        both list the entries that are currently inside the database.
+    </para>
+
+    <para>
+        To create a new controller, open a terminal or DOS console, navigate to your project
+        directory, and enter the following:
+    </para>
+
+    <programlisting language="shell"><![CDATA[
+# Unix-like systems:
+% zf.sh create controller guestbook
+
+# DOS/Windows:
+C:> zf.bat create controller guestbook
+]]></programlisting>
+
+    <para>
+        This will create a new controller, <classname>GuestbookController</classname>, in
+        <filename>application/controllers/GuestbookController.php</filename>, with a single action
+        method, <methodname>indexAction()</methodname>.  It will also create a view script directory
+        for the controller, <filename>application/views/scripts/guestbook/</filename>, with a view
+        script for the index action.
+    </para>
+
+    <para>
+        We'll use the "index" action as a landing page to view all guestbook entries.
+    </para>
+
+    <para>
+        Now, let's flesh out the basic application logic. On a hit to
+        <methodname>indexAction()</methodname>, we'll display all guestbook entries. This would look
+        like the following:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application/controllers/GuestbookController.php
+
+class GuestbookController extends Zend_Controller_Action
+{
+    public function indexAction()
+    {
+        $guestbook = new Default_Model_Guestbook();
+        $this->view->entries = $guestbook->fetchAll();
+    }
+}
+]]></programlisting>
+
+    <para>
+        And, of course, we need a view script to go along with that. Edit
+        <filename>application/views/scripts/guestbook/index.phtml</filename> to read as follows:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+<!-- application/views/scripts/guestbook/index.phtml -->
+
+<p><a href="<?php echo $this->url(
+    array(
+        'controller' => 'guestbook',
+        'action'     => 'sign'
+    ),
+    'default',
+    true) ?>">Sign Our Guestbook</a></p>
+
+Guestbook Entries: <br />
+<dl>
+    <?php foreach ($this->entries as $entry): ?>
+    <dt><?php echo $this->escape($entry->email) ?></dt>
+    <dd><?php echo $this->escape($entry->comment) ?></dd>
+    <?php endforeach ?>
+</dl>
+]]></programlisting>
+
+    <note>
+        <title>Checkpoint</title>
+
+        <para>
+            Now browse to "http://localhost/guestbook". You should see the following in your
+            browser:
+        </para>
+
+        <para>
+            <inlinegraphic width="525" scale="100" align="center" valign="middle"
+                fileref="figures/learning.quickstart.create-model.png" format="PNG" />
+        </para>
+    </note>
+
+    <note>
+        <title>Using the data loader script</title>
+
+        <para>
+            The data loader script introduced in this section
+            (<filename>scripts/load.sqlite.php</filename>) can be used to create the database for
+            each environment you have defined, as well as to load it with sample data. Internally,
+            it utilizes <classname>Zend_Console_Getopt</classname>, which allows it to provide a
+            number of command line switches. If you pass the "-h" or "--help" switch, it will give
+            you the available options:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+Usage: load.sqlite.php [ options ]
+--withdata|-w         Load database with sample data
+--env|-e [  ]         Application environment for which to create database
+                      (defaults to development)
+--help|-h             Help -- usage message)]]
+]]></programlisting>
+
+        <para>
+            The "-e" switch allows you to specify the value to use for the constant
+            <constant>APPLICATION_ENV</constant> -- which in turn allows you to create a SQLite
+            database for each environment you define.  Be sure to run the script for the environment
+            you choose for your application when deploying.
+        </para>
+    </note>
+</sect1>

+ 430 - 0
documentation/manual/de/tutorials/quickstart-create-project.xml

@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.quickstart.create-project">
+    <title>Create Your Project</title>
+
+    <para>
+        In order to create your project, you must first download and extract Zend Framework.
+    </para>
+
+    <sect2 id="learning.quickstart.create-project.install-zf">
+        <title>Install Zend Framework</title>
+
+        <para>
+            The easiest way to get Zend Framework along with a complete PHP stack is by installing
+            <ulink url="http://www.zend.com/en/products/server-ce/downloads">Zend Server</ulink>.
+            Zend Server has native installers for Mac OSX, Windows, Fedora Core, and Ubuntu, as well
+            as a universal installation package compatible with most Linux distributions.
+        </para>
+
+        <para>
+            After you have installed Zend Server, the Framework files may be found
+            under <filename>/Applications/ZendServer/share/ZendFramework</filename> on Mac
+            OSX, <filename>C:\Program Files\Zend\ZendServer\share\ZendFramework</filename> on
+            Windows, and <filename>/usr/local/zend/share/ZendFramework</filename> on Linux.
+            The <constant>include_path</constant> will already be configured to include
+            Zend Framework.
+        </para>
+
+        <para>
+            Alternately, you can <ulink url="http://framework.zend.com/download/latest">Download the
+            latest version of Zend Framework</ulink> and extract the contents; make a note of where
+            you have done so.
+        </para>
+
+        <para>
+            Optionally, you can add the path to the <filename>library/</filename> subdirectory of
+            the archive to your <filename>php.ini</filename>'s <constant>include_path</constant>
+            setting.
+        </para>
+
+        <para>
+            That's it! Zend Framework is now installed and ready to use.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.create-project">
+        <title>Create Your Project</title>
+
+        <note>
+            <title>zf Command Line Tool</title>
+
+            <para>
+                In your Zend Framework installation is a <filename>bin/</filename> subdirectory,
+                containing the scripts <filename>zf.sh</filename> and <filename>zf.bat</filename>
+                for Unix-based and Windows-based users, respectively. Make a note of the absolute
+                path to this script.
+            </para>
+
+            <para>
+                Wherever you see references to <filename>zf.sh</filename> or
+                <filename>zf.bat</filename>, please substitute the absolute path to the script. On
+                Unix-like systems, you may want to use your shell's alias functionality:
+                <command>alias zf.sh=path/to/ZendFramework/bin/zf.sh</command>.
+            </para>
+
+            <para>
+                If you have problems setting up the <command>zf</command> command-line tool, please
+                refer to <link linkend="zend.tool.framework.clitool.setup-general">the
+                    manual</link>.
+            </para>
+        </note>
+
+        <para>
+            Open a terminal (in Windows, <command>Start -> Run</command>, and then use
+            <command>cmd</command>). Navigate to a directory where you would like to start a
+            project. Then, use the path to the appropriate script, and execute one of the following:
+        </para>
+
+        <programlisting language="shell"><![CDATA[
+# Unix:
+% zf.sh create project quickstart
+
+# DOS/Windows:
+C:> zf.bat create project quickstart
+]]></programlisting>
+
+        <para>
+            Running this command will create your basic site structure, including your initial
+            controllers and views. The tree looks like the following:
+        </para>
+
+        <programlisting language="text"><![CDATA[
+quickstart
+|-- application
+|   |-- Bootstrap.php
+|   |-- configs
+|   |   `-- application.ini
+|   |-- controllers
+|   |   |-- ErrorController.php
+|   |   `-- IndexController.php
+|   |-- models
+|   `-- views
+|       |-- helpers
+|       `-- scripts
+|           |-- error
+|           |   `-- error.phtml
+|           `-- index
+|               `-- index.phtml
+|-- library
+|-- public
+|   `-- index.php
+`-- tests
+    |-- application
+    |   `-- bootstrap.php
+    |-- library
+    |   `-- bootstrap.php
+    `-- phpunit.xml
+]]></programlisting>
+
+        <para>
+            At this point, if you haven't added Zend Framework to your
+            <constant>include_path</constant>, we recommend either copying or symlinking it into
+            your <filename>library/</filename> directory. In either case, you'll want to either
+            recursively copy or symlink the <filename>library/Zend/</filename> directory of your
+            Zend Framework installation into the <filename>library/</filename> directory of your
+            project. On unix-like systems, that would look like one of the following:
+        </para>
+
+        <programlisting language="shell"><![CDATA[
+# Symlink:
+% cd library; ln -s path/to/ZendFramework/library/Zend .
+
+# Copy:
+% cd library; cp -r path/to/ZendFramework/library/Zend .
+]]></programlisting>
+
+        <para>
+            On Windows systems, it may be easiest to do this from the Explorer.
+        </para>
+
+        <para>
+            Now that the project is created, the main artifacts to begin understanding are the
+            bootstrap, configuration, action controllers, and views.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.bootstrap">
+        <title>The Bootstrap</title>
+
+        <para>
+            Your <classname>Bootstrap</classname> class defines what resources and components to
+            initialize. By default, Zend Framework's <link linkend="zend.controller.front">Front
+                Controller</link> is initialized, and it uses the
+            <filename>application/controllers/</filename> as the default directory in which to look
+            for action controllers (more on that later). The class looks like the following:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// application/Bootstrap.php
+
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+}
+]]></programlisting>
+
+        <para>
+            As you can see, not much is necessary to begin with.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.configuration">
+        <title>Configuration</title>
+
+        <para>
+            While Zend Framework is itself configurationless, you often need to configure your
+            application. The default configuration is placed in
+            <filename>application/configs/application.ini</filename>, and contains some basic
+            directives for setting your PHP environment (for instance, turning error reporting on
+            and off), indicating the path to your bootstrap class (as well as its class name), and
+            the path to your action controllers. It looks as follows:
+        </para>
+
+        <programlisting language="ini"><![CDATA[
+; application/configs/application.ini
+
+[production]
+phpSettings.display_startup_errors = 0
+phpSettings.display_errors = 0
+includePaths.library = APPLICATION_PATH "/../library"
+bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
+bootstrap.class = "Bootstrap"
+resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
+
+[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>
+            Several things about this file should be noted. First, when using INI-style
+            configuration, you can reference constants directly and expand them;
+            <constant>APPLICATION_PATH</constant> is actually a constant. Additionally note that
+            there are several sections defined: production, staging, testing, and development. The
+            latter three inherit settings from the "production" environment. This is a useful way to
+            organize configuration to ensure that appropriate settings are available in each stage
+            of application development.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.action-controllers">
+        <title>Action Controllers</title>
+
+        <para>
+            Your application's <emphasis>action controllers</emphasis> contain your application
+            workflow, and do the work of mapping your requests to the appropriate models and views.
+        </para>
+
+        <para>
+            An action controller should have one or more methods ending in "Action"; these methods
+            may then be requested via the web. By default, Zend Framework URLs follow the schema
+            <constant>/controller/action</constant>, where "controller" maps to the action
+            controller name (minus the "Controller" suffix) and "action" maps to an action method
+            (minus the "Action" suffix).
+        </para>
+
+        <para>
+            Typically, you always need an <classname>IndexController</classname>, which is a
+            fallback controller and which also serves the home page of the site, and an
+            <classname>ErrorController</classname>, which is used to indicate things such as HTTP
+            404 errors (controller or action not found) and HTTP 500 errors (application errors).
+        </para>
+
+        <para>
+            The default <classname>IndexController</classname> is as follows:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// application/controllers/IndexController.php
+
+class IndexController extends Zend_Controller_Action
+{
+
+    public function init()
+    {
+        /* Initialize action controller here */
+    }
+
+    public function indexAction()
+    {
+        // action body
+    }
+}
+]]></programlisting>
+
+        <para>
+            And the default <classname>ErrorController</classname> is as follows:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+// application/controllers/ErrorController.php
+
+class ErrorController extends Zend_Controller_Action
+{
+
+    public function errorAction()
+    {
+        $errors = $this->_getParam('error_handler');
+
+        switch ($errors->type) {
+            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
+            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
+
+                // 404 error -- controller or action not found
+                $this->getResponse()->setHttpResponseCode(404);
+                $this->view->message = 'Page not found';
+                break;
+            default:
+                // application error
+                $this->getResponse()->setHttpResponseCode(500);
+                $this->view->message = 'Application error';
+                break;
+        }
+
+        $this->view->exception = $errors->exception;
+        $this->view->request   = $errors->request;
+    }
+}
+]]></programlisting>
+
+        <para>
+            You'll note that (1) the <classname>IndexController</classname> contains no real code,
+            and (2) the <classname>ErrorController</classname> makes reference to a "view" property.
+            That leads nicely into our next subject.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.views">
+        <title>Views</title>
+
+        <para>
+            Views in Zend Framework are written in plain old PHP. View scripts are placed in
+            <filename>application/views/scripts/</filename>, where they are further categorized
+            using the controller names. In our case, we have an
+            <classname>IndexController</classname> and an <classname>ErrorController</classname>,
+            and thus we have corresponding <filename>index/</filename> and
+            <filename>error/</filename> subdirectories within our view scripts directory. Within
+            these subdirectories, you will then find and create view scripts that correspond to each
+            controller action exposed; in the default case, we thus have the view scripts
+            <filename>index/index.phtml</filename> and <filename>error/error.phtml</filename>.
+        </para>
+
+        <para>
+            View scripts may contain any markup you want, and use the <code>&lt;?php</code> opening
+            tag and <code>?&gt;</code> closing tag to insert PHP directives.
+        </para>
+
+        <para>
+            The following is what we install by default for the
+            <filename>index/index.phtml</filename> view script:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<!-- application/views/scripts/index/index.phtml -->
+<style>
+
+    a:link,
+    a:visited
+    {
+        color: #0398CA;
+    }
+
+    span#zf-name
+    {
+        color: #91BE3F;
+    }
+
+    div#welcome
+    {
+        color: #FFFFFF;
+        background-image: url(http://framework.zend.com/images/bkg_header.jpg);
+        width:  600px;
+        height: 400px;
+        border: 2px solid #444444;
+        overflow: hidden;
+        text-align: center;
+    }
+
+    div#more-information
+    {
+        background-image: url(http://framework.zend.com/images/bkg_body-bottom.gif);
+        height: 100%;
+    }
+
+</style>
+<div id="welcome">
+    <h1>Welcome to the <span id="zf-name">Zend Framework!</span><h1 />
+    <h3>This is your project's main page<h3 />
+    <div id="more-information">
+        <p>
+            <img src="http://framework.zend.com/images/PoweredBy_ZF_4LightBG.png" />
+        </p>
+
+        <p>
+            Helpful Links: <br />
+            <a href="http://framework.zend.com/">Zend Framework Website</a> |
+            <a href="http://framework.zend.com/manual/en/">Zend Framework
+                Manual</a>
+        </p>
+    </div>
+</div>
+]]></programlisting>
+
+        <para>
+            The <filename>error/error.phtml</filename> view script is slightly more interesting as
+            it uses some PHP conditionals:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<!-- application/views/scripts/error/error.phtml -->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN";
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Zend Framework Default Application</title>
+</head>
+<body>
+  <h1>An error occurred</h1>
+  <h2><?php echo $this->message ?></h2>
+
+  <?php if ('development' == $this->env): ?>
+
+  <h3>Exception information:</h3>
+  <p>
+      <b>Message:</b> <?php echo $this->exception->getMessage() ?>
+  </p>
+
+  <h3>Stack trace:</h3>
+  <pre><?php echo $this->exception->getTraceAsString() ?>
+  </pre>
+
+  <h3>Request Parameters:</h3>
+  <pre><?php echo var_export($this->request->getParams(), 1) ?>
+  </pre>
+  <?php endif ?>
+
+</body>
+</html>
+]]></programlisting>
+    </sect2>
+
+    <sect2 id="learning.quickstart.create-project.checkpoint">
+        <title>Checkpoint</title>
+
+        <para>
+            At this point, you should be able to fire up your initial Zend Framework application.
+            Create a virtual host in your web server, and point its document root to your
+            application's <filename>public/</filename> subdirectory. Make sure your host's name is
+            in your DNS or hosts file, and then point your browser to it. You should be able to see
+            a welcome page at this point.
+        </para>
+    </sect2>
+</sect1>

+ 115 - 0
documentation/manual/de/tutorials/quickstart-intro-mvc.xml

@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.quickstart.intro">
+    <title>ZF &amp; MVC Introduction</title>
+
+    <sect2 id="learning.quickstart.intro.zf">
+        <title>Zend Framework</title>
+
+        <para>
+            Zend Framework is an open source, object oriented web application framework for PHP 5.
+            ZF is often called a 'component library', because it has many loosely coupled components
+            that you can use more or less independently. But Zend Framework also provides an
+            advanced Model-View-Controller (MVC) implementation that can be used to establish a
+            basic structure for your ZF applications. A full list of Zend Framework components along
+            with short descriptions may be found in the <ulink
+                url="http://framework.zend.com/about/components">components overview</ulink>. This
+            QuickStart will introduce you to some of ZF's most commonly used components, including
+            <classname>Zend_Controller</classname>, <classname>Zend_Layout</classname>,
+            <classname>Zend_Config</classname>, <classname>Zend_Db</classname>,
+            <classname>Zend_Db_Table</classname>, <classname>Zend_Registry</classname>, along
+            with a few view helpers.
+        </para>
+
+        <para>
+            Using these components, we will build a simple database-driven guest book application
+            within minutes. The complete source code for this application is available in the
+            following archives:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <ulink
+                        url="http://framework.zend.com/demos/ZendFrameworkQuickstart.zip">zip</ulink>
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <ulink
+                        url="http://framework.zend.com/demos/ZendFrameworkQuickstart.tar.gz">tar.gz</ulink>
+                </para>
+            </listitem>
+        </itemizedlist>
+    </sect2>
+
+    <sect2 id="learning.quickstart.intro.mvc">
+        <title>Model-View-Controller</title>
+
+        <para>
+            So what exactly is this MVC pattern everyone keeps talking about, and why should you
+            care? MVC is much more than just a three-letter acronym (TLA) that you can whip out
+            anytime you want to sound smart; it has become something of a standard in the design of
+            modern web applications. And for good reason. Most web application code falls under one
+            of the following three categories: presentation, business logic, and data access. The
+            MVC pattern models this separation of concerns well. The end result is that your
+            presentation code can be consolidated in one part of your application with your business
+            logic in another and your data access code in yet another. Many developers have found
+            this well-defined separation indispensable for keeping their code organized, especially
+            when more than one developer is working on the same application.
+        </para>
+
+        <note>
+            <title>More Information</title>
+
+            <para>
+                Let's break down the pattern and take a look at the individual pieces:
+            </para>
+
+            <para>
+                <inlinegraphic width="321" scale="100" align="center" valign="middle"
+                    fileref="figures/learning.quickstart.intro.mvc.png" format="PNG" />
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <emphasis role="strong">Model</emphasis> - This is the part of your
+                        application that defines its basic functionality behind a set of
+                        abstractions. Data access routines and some business logic can be defined in
+                        the model.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <emphasis role="strong">View</emphasis> - Views define exactly what is
+                        presented to the user. Usually controllers pass data to each view to render
+                        in some format. Views will often collect data from the user, as well. This
+                        is where you're likely to find HTML markup in your MVC applications.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <emphasis role="strong">Controller</emphasis> - Controllers bind the whole
+                        pattern together. They manipulate models, decide which view to display based
+                        on the user's request and other factors, pass along the data that each view
+                        will need, or hand off control to another controller entirely. Most MVC
+                        experts recommend <ulink
+                            url="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model">keeping
+                        controllers as skinny as possible</ulink>.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Of course there is <ulink url="http://ootips.org/mvc-pattern.html">more to be
+                    said</ulink> about this critical pattern, but this should give you enough
+                background to understand the guestbook application we'll be building.
+            </para>
+        </note>
+    </sect2>
+</sect1>

+ 255 - 0
documentation/manual/de/tutorials/view-placeholders-basics.xml

@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- 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
+        <acronym>DocType</acronym> 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 "user/_sidebar.phtml", 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 HTML 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 "user/view.phtml" 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 "/user/view" 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>

+ 17 - 0
documentation/manual/de/tutorials/view-placeholders-conclusion.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.view.placeholders.conclusion">
+    <title>View Placeholders: Conclusion</title>
+
+    <para>
+        View placeholders are a simple and powerful method for creating rich layouts for your
+        application. You can use a variety of standard placeholders, such as those discussed
+        (<methodname>doctype()</methodname>, <methodname>headTitle()</methodname>,
+        <methodname>headLink()</methodname>, and <methodname>headScript()</methodname>), or use
+        the generic <methodname>placeholder()</methodname> helper to aggregate content and render it
+        in custom ways. Experiment with their exposed functionality, and visit the appropriate
+        sections in the reference guide to find out about the additional features they offer -- and
+        how you may leverage those features to create rich content for your readers.
+    </para>
+</sect1>

+ 44 - 0
documentation/manual/de/tutorials/view-placeholders-intro.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 19766 -->
+<!-- Reviewed: no -->
+<sect1 id="learning.view.placeholders.intro">
+    <title>Einführung</title>
+
+    <para>
+        Im <link linkend="learning.layout">vorherigen Kapitel</link> haben wir primär das Two Step
+        Pattern betrachtet, welches es erlaubt individuelle Anwendungsviews in einem Siteweitem
+        Layout einzubetten. Am Ende dieses Kapitels diskutieren wir trotzdem noch einige
+        Limitationen:
+    </para>
+
+    <itemizedlist>
+        <listitem>
+            <para>
+                Wie verändert man den Titel der Seite?
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Wie könnte man konditionale Skripte oder Stylesheets in ein Siteweites Layout
+                injizieren?
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                Wie würde man eine optionale Sidebar erstellen und darstellen? Was wenn ein Teil des
+                Inhalts nicht konditional, und anderer Inhalt für die Sidebar konditional war?
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        Diese Fragen werden im <ulink
+            url="http://java.sun.com/blueprints/corej2eepatterns/Patterns/CompositeView.html">Composite
+        View</ulink> Design Pattern behandelt. Ein Weg zu diesem Pattern ist es "hints" oder Inhalt
+        für das Siteweite Layout anzubieten. Im Zend Framwork wird das durch spezialisierte View
+        Helfer ermöglicht welche "placeholders" (Platzhalter) heißen. Platzhalter erlauben es einem
+        Inhalte zu erstellen, und diese erstellten Inghalte anschließend an anderer Stelle darzustellen.
+    </para>
+</sect1>

+ 460 - 0
documentation/manual/de/tutorials/view-placeholders-standard.xml

@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="learning.view.placeholders.standard">
+    <title>Standard Placeholders</title>
+
+    <para>
+        In the <link linkend="learning.view.placeholders.basics">previous section</link>, we learned
+        about the <methodname>placeholder()</methodname> view helper, and how it can be used to
+        aggregate custom content. In this section, we'll look at some of the concrete placeholders
+        shipped with Zend Framework, and how you can use them to your advantage when creating
+        complex composite layouts.
+    </para>
+
+    <para>
+        Most of the shipped placeholders are for generating content for the
+        <code>&lt;head&gt;</code> section of your layout content -- an area you typically cannot
+        manipulate directly via your application view scripts, but one you may want to influence. As
+        examples: you may want your title to contain certain content on every page, but specific
+        content based on the controller and/or action; you may want to specify
+        <acronym>CSS</acronym> files to load based on what section of the application you're in; you
+        may need specific JavaScript scripts loaded at different times; or you may want to set the
+        <acronym>DocType</acronym> declaration.
+    </para>
+
+    <para>
+        Zend Framework ships with placeholder implementations for each of these situations, and
+        several more.
+    </para>
+
+    <sect2 id="learning.view.placeholders.standard.doctype">
+        <title>Setting the DocType</title>
+
+        <para>
+            <acronym>DocType</acronym> declarations are troublesome to memorize, and often essential
+            to include in your document to ensure the browser properly renders your content. The
+            <methodname>doctype()</methodname> view helper allows you to use simple string mnemonics
+            to specify the desired <acronym>DocType</acronym>; additionally, other helpers will
+            query the <methodname>doctype()</methodname> helper to ensure the output generated
+            conforms with the requested <acronym>DocType</acronym>.
+        </para>
+
+        <para>
+            As an example, if you want to use the <acronym>XHTML1</acronym> Strict
+            <acronym>DTD</acronym>, you can simply specify:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$this->doctype('XHTML1_STRICT');
+]]></programlisting>
+
+        <para>
+            Among the other available mnemonics, you'll find these common types:
+        </para>
+
+        <variablelist>
+            <varlistentry>
+                <term>XHTML1_STRICT</term>
+
+                <listitem>
+                    <para>
+                        <acronym>XHTML</acronym> 1.0 Strict
+                    </para>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>XHTML1_TRANSITIONAL</term>
+
+                <listitem>
+                    <para>
+                        <acronym>XHTML</acronym> 1.0 Transitional
+                    </para>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>HTML4_STRICT</term>
+
+                <listitem>
+                    <para>
+                        <acronym>HTML</acronym> 4.01 Strict
+                    </para>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>HTML4_Loose</term>
+
+                <listitem>
+                    <para>
+                        <acronym>HTML</acronym> 4.01 Loose
+                    </para>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>HTML5</term>
+
+                <listitem>
+                    <para>
+                        <acronym>HTML</acronym> 5
+                    </para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+
+        <para>
+            You can assign the type and render the declaration in a single call:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+echo $this->doctype('XHTML1_STRICT');
+]]></programlisting>
+
+        <para>
+            However, the better approach is to assign the type in your bootstrap, and then render it
+            in your layout. Try adding the following to your bootstrap class:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+    protected function _initDocType()
+    {
+        $this->bootstrap('View');
+        $view = $this->getResource('View');
+        $view->doctype('XHTML1_STRICT');
+    }
+}
+]]></programlisting>
+
+        <para>
+            Then, in your layout script, simply <function>echo</function> the helper at the
+            top of the file:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php echo $this->doctype() ?>
+<html>
+    <!-- ... -->
+]]></programlisting>
+
+        <para>
+            This will ensure that your DocType-aware view helpers render the appropriate markup,
+            ensure that the type is set well before the layout is rendered, and provide a single
+            location to change the DocType.
+        </para>
+    </sect2>
+
+    <sect2 id="learning.view.placeholders.standard.head-title">
+        <title>Specifying the Page Title</title>
+
+        <para>
+            Often, a site will include the site or business name as  part of the page title, and
+            then add additional information based on the location within the site. As an example,
+            the zend.com website includes the string "Zend.com" on all pages, and the prepends
+            information based on the page: "Zend Server - Zend.com". Within Zend Framework, the
+            <methodname>headTitle()</methodname> view helper can help simplify this task.
+        </para>
+
+        <para>
+            At its simplest, the <methodname>headTitle()</methodname> helper allows you to aggregate
+            content for the <code>&lt;title&gt;</code> tag; when you echo it, it then assembles it
+            based on the order in which segments are added. You can control the order using
+            <methodname>prepend()</methodname> and <methodname>append()</methodname>, and provide a
+            separator to use between segments using the <methodname>setSeparator()</methodname>
+            method.
+        </para>
+
+        <para>
+            Typically, you should specify any segments common to all pages in your bootstrap,
+            similar to how we define the doctype. In this case, we'll define a
+            <methodname>_initPlaceholders()</methodname> method for operating on all the various
+            placeholders, and specify an initial title as well as a separator.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+    // ...
+
+    protected function _initPlaceholders()
+    {
+        $this->bootstrap('View');
+        $view = $this->getResource('View');
+        $view->doctype('XHTML1_STRICT');
+
+        // Set the initial title and separator:
+        $view->headTitle('My Site')
+             ->setSeparator(' :: ');
+    }
+
+    // ...
+}
+]]></programlisting>
+
+        <para>
+            Within a view script, we might want to add another segment:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php $this->headTitle()->append('Some Page'); // place after other segments ?>
+<?php $this->headTitle()->prepend('Some Page'); // place before ?>
+]]></programlisting>
+
+        <para>
+            In our layout, we will simply echo the <methodname>headTitle()</methodname> helper:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php echo $this->doctype() ?>
+<html>
+    <?php echo $this->headTitle() ?>
+    <!-- ... -->
+]]></programlisting>
+
+        <para>
+            This will generate the following output:
+        </para>
+
+        <programlisting language="html"><![CDATA[
+<!-- If append() was used: -->
+<title>My Site :: Some Page</title>
+
+<!-- If prepend() was used: -->
+<title>Some Page :: My Site</title>
+]]></programlisting>
+    </sect2>
+
+    <sect2 id="learning.view.placeholders.standard.head-link">
+        <title>Specifying Stylesheets with HeadLink</title>
+
+        <para>
+            Good CSS developers will often create a general stylesheet for sitewide styles, and
+            individual stylesheets for specific sections or pages of the website, and load these
+            latter conditionally so as to decrease the amount of data needing to be transferred on
+            each request. The <methodname>headLink()</methodname> placeholder makes such conditional
+            aggregation of stylesheets trivial within your application.
+        </para>
+
+        <para>
+            To accomplish this, <methodname>headLink()</methodname> defines a number of "virtual"
+            methods (via overloading) to make the process trivial. The ones we will be concerned
+            with are <methodname>appendStylesheet()</methodname> and
+            <methodname>prependStylesheet()</methodname>. Each takes up to four arguments,
+            <varname>$href</varname> (the relative path to the stylesheet),
+            <varname>$media</varname> (the MIME type, which defaults to "text/css"),
+            <varname>$conditionalStylesheet</varname> (which can be used to specify a "condition"
+            under which the stylesheet will be evaluated), and <varname>$extras</varname> (an
+            associative array of key/value pairs, commonly used to specify a key for "media"). In
+            most cases, you will only need to specify the first argument, the relative path to the
+            stylesheet.
+        </para>
+
+        <para>
+            In our example, we'll assume that all pages need to load the stylesheet located in
+            "/styles/site.css" (relative to the document root); we'll specify this in our
+            <methodname>_initPlaceholders()</methodname> bootstrap method.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+    // ...
+
+    protected function _initPlaceholders()
+    {
+        $this->bootstrap('View');
+        $view = $this->getResource('View');
+        $view->doctype('XHTML1_STRICT');
+
+        // Set the initial title and separator:
+        $view->headTitle('My Site')
+             ->setSeparator(' :: ');
+
+        // Set the initial stylesheet:
+        $view->headLink()->prependStylesheet('/styles/site.css');
+    }
+
+    // ...
+}
+]]></programlisting>
+
+        <para>
+            Later, in a controller or action-specific view script, we can add more stylesheets:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php $this->headLink()->appendStylesheet('/styles/user-list.css') ?>
+]]></programlisting>
+
+        <para>
+            Within our layout view script, once again, we simply echo the placeholder:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php echo $this->doctype() ?>
+<html>
+    <?php echo $this->headTitle() ?>
+    <?php echo $this->headLink() ?>
+    <!-- ... -->
+]]></programlisting>
+
+        <para>
+            This will generate the following output:
+        </para>
+
+        <programlisting language="html"><![CDATA[
+<link rel="stylesheet" type="text/css" href="/styles/site.css" />
+<link rel="stylesheet" type="text/css" href="/styles/user-list.css" />
+]]></programlisting>
+    </sect2>
+
+    <sect2 id="learning.view.placeholders.standard.head-script">
+        <title>Aggregating Scripts Using HeadScript</title>
+
+        <para>
+            Another common tactic to prevent long page load times is to only load JavaScript when
+            necessary. That said, you may need several layers of scripts: perhaps one for
+            progressively enhancing menus on the site, and another for page-specific content. In
+            these situations, the <methodname>headScript()</methodname> helper presents a solution.
+        </para>
+
+        <para>
+            Similar to the <methodname>headLink()</methodname> helper,
+            <methodname>headScript()</methodname> provides the ability to append or prepend scripts
+            to the collection, and then echo the entire set. It provides the flexibility to specify
+            either script files themselves to load, or explicit JavaScript. You also have the option
+            of capturing JavaScript via
+            <methodname>captureStart()</methodname>/<methodname>captureEnd()</methodname>, which
+            allows you to simply inline the JavaScript instead of requiring an additional call to
+            your server.
+        </para>
+
+        <para>
+            Also like <methodname>headLink()</methodname>, <methodname>headScript</methodname>
+            provides "virtual" methods via overloading as a convenience when specifying items to
+            aggregate; common methods include <methodname>prependFile()</methodname>,
+            <methodname>appendFile()</methodname>, <methodname>prependScript()</methodname>, and
+            <methodname>appendScript()</methodname>. The first two allow you to specify files that
+            will be referenced in a <code>&lt;script&gt;</code> tag's <varname>src</varname>
+            attribute; the latter two will take the content provided and render it as literal
+            JavaScript within a <code>&lt;script&gt;</code> tag.
+        </para>
+
+        <para>
+            In this example, we'll specify that a script, "/js/site.js" needs to be loaded on every
+            page; we'll update our <methodname>_initPlaceholders()</methodname> bootstrap method to
+            do this.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
+{
+    // ...
+
+    protected function _initPlaceholders()
+    {
+        $this->bootstrap('View');
+        $view = $this->getResource('View');
+        $view->doctype('XHTML1_STRICT');
+
+        // Set the initial title and separator:
+        $view->headTitle('My Site')
+             ->setSeparator(' :: ');
+
+        // Set the initial stylesheet:
+        $view->headLink()->prependStylesheet('/styles/site.css');
+
+        // Set the initial JS to load:
+        $view->headScript()->prependFile('/js/site.js');
+    }
+
+    // ...
+}
+]]></programlisting>
+
+        <para>
+            Within a view script, we might then add an extra script file to source, or capture some
+            JavaScript to include in our document.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php $this->headScript()->appendFile('/js/user-list.js') ?>
+<?php $this->headScript()->captureStart() ?>
+site = {
+    baseUrl: "<?php echo $this->baseUrl() ?>"
+};
+<?php $this->headScript()->captureEnd() ?>
+]]></programlisting>
+
+        <para>
+            Within our layout script, we then simply echo the placeholder, just as we have all the
+            others:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<?php echo $this->doctype() ?>
+<html>
+    <?php echo $this->headTitle() ?>
+    <?php echo $this->headLink() ?>
+    <?php echo $this->headScript() ?>
+    <!-- ... -->
+]]></programlisting>
+
+        <para>
+            This will generate the following output:
+        </para>
+
+        <programlisting language="html"><![CDATA[
+<script type="text/javascript" src="/js/site.js"></script>
+<script type="text/javascript" src="/js/user-list.js"></script>
+<script type="text/javascript">
+site = {
+    baseUrl: "<?php echo $this->baseUrl() ?>"
+};
+</script>
+]]></programlisting>
+
+        <note>
+            <title>InlineScript Variant</title>
+
+            <para>
+                Many browsers will often block display of a page until all scripts and stylesheets
+                referenced in the <code>&lt;head&gt;</code> section have loaded. If you have a
+                number of such directives, this can impact how soon somebody can start actually
+                viewing the page.
+            </para>
+
+            <para>
+                One way around this is to emit your <code>&lt;script&gt;</code> tags just prior to
+                closing the <code>&lt;body&gt;</code> of your document. (This is a practice
+                specifically recommend by the <ulink
+                    url="http://developer.yahoo.com/yslow/">Y! Slow project</ulink>.)
+            </para>
+
+            <para>
+                Zend Framework supports this in two different ways:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        You can render your <methodname>headScript()</methodname> tag whereever you
+                        like in your layout script; just because the title references "head" does
+                        not mean it needs to be rendered in that location.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Alternately, you may use the <methodname>inlineScript()</methodname> helper,
+                        which is simply a variant on <methodname>headScript()</methodname>, and
+                        retains the same behavior, but uses a separate registry.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </note>
+    </sect2>
+</sect1>