Sfoglia il codice sorgente

[MANUAL] German:

- sync to r19776

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19924 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 anni fa
parent
commit
76829bf871
55 ha cambiato i file con 8248 aggiunte e 264 eliminazioni
  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"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 16720 -->
+<!-- EN-Revision: 19768 -->
 <!-- Reviewed: no -->
 <!-- Reviewed: no -->
 <sect1 id="zend.dojo.build-layers">
 <sect1 id="zend.dojo.build-layers">
     <title>Support für den Build Layer von Zend_Dojo</title>
     <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()
     public function getBuild()
     {
     {
+        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
+            'ViewRenderer'
+        );
+        $viewRenderer->initView();
         if (null === $this->_build) {
         if (null === $this->_build) {
             $this->_build = new Zend_Dojo_BuildLayer(array(
             $this->_build = new Zend_Dojo_BuildLayer(array(
-                'view'      => $view,
+                'view'      => $viewRenderer->view,
                 'layerName' => 'custom.main',
                 'layerName' => 'custom.main',
             ));
             ));
         }
         }

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

@@ -55,48 +55,52 @@
         </para>
         </para>
 
 
         <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>
 
 
         <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>
 
 
         <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>
         </para>
     </sect2>
     </sect2>
 
 
     <sect2 id="zend.feed.writer.getting.started">
     <sect2 id="zend.feed.writer.getting.started">
-        <title>Getting Started</title>
+        <title>Beginnen</title>
 
 
         <para>
         <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>
         </para>
 
 
         <programlisting language="php"><![CDATA[
         <programlisting language="php"><![CDATA[
 /**
 /**
- * Create the parent feed
+ * Den Eltern Feed erstellen
  */
  */
 $feed = new Zend_Feed_Writer_Feed;
 $feed = new Zend_Feed_Writer_Feed;
 $feed->setTitle('Paddy\'s Blog');
 $feed->setTitle('Paddy\'s Blog');
@@ -111,8 +115,8 @@ $feed->setDateModified(time());
 $feed->addHub('http://pubsubhubbub.appspot.com/');
 $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 = $feed->createEntry();
 $entry->setTitle('All Your Base Are Belong To Us');
 $entry->setTitle('All Your Base Are Belong To Us');
@@ -124,19 +128,22 @@ $entry->addAuthor(array(
 ));
 ));
 $entry->setDateModified(time());
 $entry->setDateModified(time());
 $entry->setDateCreated(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);
 $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');
 $out = $feed->export('atom');
 ]]></programlisting>
 ]]></programlisting>
 
 
         <para>
         <para>
-            The output rendered should be as follows:
+            Die dargestellt Ausgabe sollte folgende sein:
         </para>
         </para>
 
 
         <programlisting language="xml">
         <programlisting language="xml">
@@ -160,7 +167,7 @@ $out = $feed->export('atom');
     &#60;entry&#62;
     &#60;entry&#62;
         &#60;title type="html"&#62;&#60;![CDATA[All Your Base Are Belong To Us]]&#62;&#60;/title&#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;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;/summary&#62;
         &#60;published&#62;2009-12-14T20:28:18+00:00&#60;/published&#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;
         &#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;uri&#62;http://www.example.com&#60;/uri&#62;
         &#60;/author&#62;
         &#60;/author&#62;
         &#60;content type="html"&#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;/content&#62;
     &#60;/entry&#62;
     &#60;/entry&#62;
 &#60;/feed&#62;
 &#60;/feed&#62;
 </programlisting>
 </programlisting>
 
 
         <para>
         <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>
         </para>
     </sect2>
     </sect2>
 
 
     <sect2 id="zend.feed.writer.setting.feed.data.points">
     <sect2 id="zend.feed.writer.setting.feed.data.points">
-        <title>Setting Feed Data Points</title>
+        <title>Die Datenpunkte eines Feeds setzen</title>
 
 
         <para>
         <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>
 
 
         <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>
 
 
         <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>
         </para>
 
 
         <table>
         <table>
-            <title>Feed Level API Methods</title>
+            <title>API Methoden auf Feed Level</title>
 
 
             <tgroup cols="2">
             <tgroup cols="2">
                 <tbody>
                 <tbody>
                     <row>
                     <row>
                         <entry><methodname>setId()</methodname></entry>
                         <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>
 
 
                     <row>
                     <row>
                         <entry><methodname>setTitle()</methodname></entry>
                         <entry><methodname>setTitle()</methodname></entry>
-
-                        <entry>Set the title of the feed.</entry>
+                        <entry>Setzt den Titel des Feeds.</entry>
                     </row>
                     </row>
 
 
                     <row>
                     <row>
                         <entry><methodname>setDescription()</methodname></entry>
                         <entry><methodname>setDescription()</methodname></entry>
-
-                        <entry>Set the text description of the feed.</entry>
+                        <entry>Setzt die textuelle Beschreibung des Feeds.</entry>
                     </row>
                     </row>
 
 
                     <row>
                     <row>
                         <entry><methodname>setLink()</methodname></entry>
                         <entry><methodname>setLink()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -264,15 +273,16 @@ $out = $feed->export('atom');
                         <entry><methodname>setFeedLinks()</methodname></entry>
                         <entry><methodname>setFeedLinks()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -280,13 +290,13 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthors()</methodname></entry>
                         <entry><methodname>setAuthors()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -294,8 +304,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthor()</methodname></entry>
                         <entry><methodname>setAuthor()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -303,10 +313,11 @@ $out = $feed->export('atom');
                         <entry><methodname>setDateCreated()</methodname></entry>
                         <entry><methodname>setDateCreated()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -314,8 +325,9 @@ $out = $feed->export('atom');
                         <entry><methodname>getDateModified()</methodname></entry>
                         <entry><methodname>getDateModified()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -323,7 +335,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setLanguage()</methodname></entry>
                         <entry><methodname>setLanguage()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -331,11 +344,11 @@ $out = $feed->export('atom');
                         <entry><methodname>getGenerator()</methodname></entry>
                         <entry><methodname>getGenerator()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -343,7 +356,7 @@ $out = $feed->export('atom');
                         <entry><methodname>setCopyright()</methodname></entry>
                         <entry><methodname>setCopyright()</methodname></entry>
 
 
                         <entry>
                         <entry>
-                            Sets a copyright notice associated with the feed.
+                            Setzt eine Copyright Notiz die mit dem Feed assoziiert ist.
                         </entry>
                         </entry>
                     </row>
                     </row>
 
 
@@ -351,11 +364,12 @@ $out = $feed->export('atom');
                         <entry><methodname>setHubs()</methodname></entry>
                         <entry><methodname>setHubs()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -363,12 +377,14 @@ $out = $feed->export('atom');
                         <entry><methodname>setCategories()</methodname></entry>
                         <entry><methodname>setCategories()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
                 </tbody>
                 </tbody>
@@ -377,53 +393,53 @@ $out = $feed->export('atom');
     </sect2>
     </sect2>
 
 
     <sect2 id="zend.feed.writer.setting.entry.data.points">
     <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>
         <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>
         </para>
 
 
         <table>
         <table>
-            <title>Entry Level API Methods</title>
+            <title>API Methoden auf Eintrags Level</title>
 
 
             <tgroup cols="2">
             <tgroup cols="2">
                 <tbody>
                 <tbody>
                     <row>
                     <row>
                         <entry><methodname>setId()</methodname></entry>
                         <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>
 
 
                     <row>
                     <row>
                         <entry><methodname>setTitle()</methodname></entry>
                         <entry><methodname>setTitle()</methodname></entry>
-
-                        <entry>Set the title of the feed.</entry>
+                        <entry>Setzt den Titel des Feeds.</entry>
                     </row>
                     </row>
 
 
                     <row>
                     <row>
                         <entry><methodname>setDescription()</methodname></entry>
                         <entry><methodname>setDescription()</methodname></entry>
-
-                        <entry>Set the text description of the feed.</entry>
+                        <entry>Setzt die textuelle Beschreibung des Feeds.</entry>
                     </row>
                     </row>
 
 
                     <row>
                     <row>
                         <entry><methodname>setLink()</methodname></entry>
                         <entry><methodname>setLink()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -431,15 +447,16 @@ $out = $feed->export('atom');
                         <entry><methodname>setFeedLinks()</methodname></entry>
                         <entry><methodname>setFeedLinks()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -447,13 +464,13 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthors()</methodname></entry>
                         <entry><methodname>setAuthors()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -461,8 +478,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setAuthor()</methodname></entry>
                         <entry><methodname>setAuthor()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -470,10 +487,11 @@ $out = $feed->export('atom');
                         <entry><methodname>setDateCreated()</methodname></entry>
                         <entry><methodname>setDateCreated()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -481,8 +499,9 @@ $out = $feed->export('atom');
                         <entry><methodname>getDateModified()</methodname></entry>
                         <entry><methodname>getDateModified()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -490,7 +509,8 @@ $out = $feed->export('atom');
                         <entry><methodname>setLanguage()</methodname></entry>
                         <entry><methodname>setLanguage()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -498,11 +518,11 @@ $out = $feed->export('atom');
                         <entry><methodname>getGenerator()</methodname></entry>
                         <entry><methodname>getGenerator()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -510,7 +530,7 @@ $out = $feed->export('atom');
                         <entry><methodname>setCopyright()</methodname></entry>
                         <entry><methodname>setCopyright()</methodname></entry>
 
 
                         <entry>
                         <entry>
-                            Sets a copyright notice associated with the feed.
+                            Setzt eine Copyright Notiz die mit dem Feed assoziiert ist.
                         </entry>
                         </entry>
                     </row>
                     </row>
 
 
@@ -518,11 +538,12 @@ $out = $feed->export('atom');
                         <entry><methodname>setHubs()</methodname></entry>
                         <entry><methodname>setHubs()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
 
 
@@ -530,12 +551,14 @@ $out = $feed->export('atom');
                         <entry><methodname>setCategories()</methodname></entry>
                         <entry><methodname>setCategories()</methodname></entry>
 
 
                         <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>
                         </entry>
                     </row>
                     </row>
                 </tbody>
                 </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"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19738 -->
+<!-- EN-Revision: 19778 -->
 <!-- Reviewed: no -->
 <!-- Reviewed: no -->
 <sect1 id="zend.tool.extending">
 <sect1 id="zend.tool.extending">
     <title>Extending Zend_Tool</title>
     <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"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19748 -->
+<!-- EN-Revision: 19777 -->
 <!-- Reviewed: no -->
 <!-- Reviewed: no -->
 <sect1 id="zend.tool.usage.cli">
 <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>
     <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>
     </para>
 
 
     <!--
     <!--
     <sect2 id="zend.tool.usage.cli.introduction">
     <sect2 id="zend.tool.usage.cli.introduction">
-        <title>Introduction</title>
+        <title>Einführung</title>
     </sect2>
     </sect2>
     -->
     -->
 
 
@@ -23,31 +23,29 @@
         <title>Installation</title>
         <title>Installation</title>
 
 
         <sect3 id="zend.tool.usage.cli.installation.download-and-go">
         <sect3 id="zend.tool.usage.cli.installation.download-and-go">
-            <title>Download And Go</title>
+            <title>Herunterladen und anfangen</title>
 
 
             <para>
             <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>
             </para>
-
-
-
         </sect3>
         </sect3>
 
 
         <sect3 id="zend.tool.usage.cli.installation.pear">
         <sect3 id="zend.tool.usage.cli.installation.pear">
-            <title>Installing Via Pear</title>
+            <title>Installation über Pear</title>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
@@ -56,68 +54,67 @@ pear install zfcampus/zf
 ]]></programlisting>
 ]]></programlisting>
 
 
             <para>
             <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>
             </para>
-
         </sect3>
         </sect3>
 
 
         <sect3 id="zend.tool.usage.cli.installation.install-by-hand">
         <sect3 id="zend.tool.usage.cli.installation.install-by-hand">
-            <title>Installing by Hand</title>
+            <title>Installation von Hand</title>
 
 
             <para>
             <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>
 
 
             <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>
 
 
             <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>
             </para>
-
         </sect3>
         </sect3>
-
     </sect2>
     </sect2>
 
 
     <sect2 id="zend.tool.usage.cli.general-purpose-commands">
     <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">
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.version">
             <title>Version</title>
             <title>Version</title>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
 zf show version
 zf show version
 ]]></programlisting>
 ]]></programlisting>
-
         </sect3>
         </sect3>
 
 
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.built-in-help">
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.built-in-help">
-            <title>Built-in Help</title>
+            <title>Eingebaute Hilfe</title>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
@@ -125,11 +122,13 @@ zf --help
 ]]></programlisting>
 ]]></programlisting>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
@@ -137,7 +136,8 @@ zf ? controller
 ]]></programlisting>
 ]]></programlisting>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
@@ -145,44 +145,40 @@ zf show ?
 ]]></programlisting>
 ]]></programlisting>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <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>
 ]]></programlisting>
-
         </sect3>
         </sect3>
 
 
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.manifest">
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.manifest">
             <title>Manifest</title>
             <title>Manifest</title>
 
 
             <para>
             <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>
             </para>
 
 
             <programlisting language="text"><![CDATA[
             <programlisting language="text"><![CDATA[
 zf show manifest
 zf show manifest
 ]]></programlisting>
 ]]></programlisting>
-
         </sect3>
         </sect3>
 
 
         <!--
         <!--
         <sect3 id="zend.tool.usage.cli.general-purpose-commands.tool-configuration">
         <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>
         </sect3>
         -->
         -->
-
     </sect2>
     </sect2>
 
 
     <sect2 id="zend.tool.usage.cli.project-specific-commands">
     <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">
         <sect3 id="zend.tool.usage.cli.project-specific-commands.project">
             <title>Project</title>
             <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"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19436 -->
+<!-- EN-Revision: 19771 -->
 <!-- Reviewed: no -->
 <!-- Reviewed: no -->
 <sect3 id="zend.view.helpers.initial.doctype">
 <sect3 id="zend.view.helpers.initial.doctype">
     <title>Doctype Helfer</title>
     <title>Doctype Helfer</title>
@@ -84,6 +84,16 @@ if ($view->doctype()->isXhtml()) {
     // etwas anderes machen
     // etwas anderes machen
 }
 }
 ]]></programlisting>
 ]]></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>
     </example>
 </sect3>
 </sect3>
 <!--
 <!--

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

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- EN-Revision: 19438 -->
+<!-- EN-Revision: 19771 -->
 <!-- Reviewed: no -->
 <!-- Reviewed: no -->
 <sect3 id="zend.view.helpers.initial.headmeta">
 <sect3 id="zend.view.helpers.initial.headmeta">
     <title>HeadMeta Helfer</title>
     <title>HeadMeta Helfer</title>
@@ -66,6 +66,12 @@
                 <command>setHttpEquiv($keyValue, $content, $modifiers)</command>
                 <command>setHttpEquiv($keyValue, $content, $modifiers)</command>
             </para>
             </para>
         </listitem>
         </listitem>
+
+        <listitem>
+            <para>
+                <command>setCharset($charset)</command>
+            </para>
+        </listitem>
     </itemizedlist>
     </itemizedlist>
 
 
     <para>
     <para>
@@ -146,6 +152,15 @@ $this->headMeta()->appendHttpEquiv('Content-Type',
 ]]></programlisting>
 ]]></programlisting>
 
 
         <para>
         <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
             Als letztes Beispiel, ein einfacher Weg um eine kurze Nachricht anzuzeigen bevor mit
             Hilfe eines "Meta Refreshes" weitergeleitet wird:
             Hilfe eines "Meta Refreshes" weitergeleitet wird:
         </para>
         </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>