Development

Documentation/de_DE/book/1.0/07-Inside-the-View-Layer (diff)

You must first sign up to be able to contribute.

Changes between Version 42 and Version 43 of Documentation/de_DE/book/1.0/07-Inside-the-View-Layer

Show
Ignore:
Author:
Jan.Kunzmann (IP: 84.190.19.106)
Timestamp:
03/20/08 16:18:43 (10 years ago)
Comment:

switched to 1.1 branch + small corrections

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/de_DE/book/1.0/07-Inside-the-View-Layer

    v42 v43  
    11'''ARBEITSENTWURF ROHÜBERSETZUNG / TRANSLATION WORKING DRAFT'''[[BR]] 
    2 Originaldokument: http://svn.symfony-project.com/doc/trunk/book/07-Inside-the-View-Layer.txt, Version 3526 vom 2007-02-21[[BR]] 
     2Originaldokument: http://svn.symfony-project.com/doc/branches/1.1/book/07-Inside-the-View-Layer.txt, Version 7705 vom 2008-03-01[[BR]] 
    33Übersetzungsfortschritt: 100%[[BR]] 
    4 Übersetzung: SK[[BR]] 
    5 Korrekturfortschritt: 0%[[BR]] 
     4Übersetzung: SK, JK[[BR]] 
     5Korrekturfortschritt: 5%[[BR]] 
    66 
    77{{{ 
    1010========================== 
    1111 
    12 Die Sicht (View) ist dafür verantwortlich, den korrekten Output einer bestimmten Aktion anzuzeigen. In symfony besteht die Sicht aus mehreren Teilen, wobei jeder Teil so konzipiert wurde, dass er sich möglichst einfach verändern lässt von den Personen, die ihn normalerweise benutzen. 
     12Die Sicht (View) ist dafür verantwortlich, den korrekten Output einer bestimmten Aktion anzuzeigen. In Symfony besteht die Sicht aus mehreren Teilen, wobei jeder Teil so konzipiert wurde, dass er sich möglichst einfach verändern lässt von den Personen, die ihn normalerweise benutzen. 
    1313 
    1414  * Webdesigner arbeiten normalerweise mit den Templates (die Präsentation der Daten der aktuellen Aktion) und mit dem Layout (das den gemeinsamen Code aller Seiten enthält). Diese sind in HTML geschrieben, das kleine PHP-Snippets enthält (meistens Helfer-Aufrufe). 
    1515  * Um der Wiederbenutzbarkeit willen stecken Entwickler normalerweise Templatecodefragmente in sogenannte Partials oder Komponenten. Sie benutzen Slots und Komponentenslots, um mehrere Bereiche des Layouts abzudecken. Webdesigner können ebenfalls an diesen Templatefragmenten arbeiten. 
    16   * Entwickler konzentrieren sich auf die YAML-Sicht-Konfigurations-Datei (um die Eigenschaften der Antwort und anderer Interface-Elemente zu bearbeiten) und auf das Antwortobject. Beim Arbeiten mit Variablen in einem Template darf das Risiko von Cross-Site-Scripting (XSS) nicht ausser Acht gelasen werden – um für die Sicherheit der Benutzerdaten garantieren zu können, ist ein gutes Verständnis von Escaping-Verfahren nötig. 
     16  * Entwickler konzentrieren sich auf die YAML-Sicht-Konfigurations-Datei (um die Eigenschaften der Antwort und anderer Interface-Elemente zu bearbeiten) und auf das Antwortobject. Beim Arbeiten mit Variablen in einem Template darf das Risiko von Cross-Site-Scripting (XSS) nicht außer Acht gelasen werden – um für die Sicherheit der Benutzerdaten garantieren zu können, ist ein gutes Verständnis von Escaping-Verfahren nötig. 
    1717 
    1818Aber welche Rolle auch immer Sie dabei spielen, Sie werden hilfreiche Werkzeuge finden, die Ihnen bei der mühsamen Präsentation der Resultate einer Aktion behilflich sein können. Dieses Kapitel erläutert all diese Werkzeuge. 
    2121--------- 
    2222 
    23 Codeabschnitt 7-1 zeigt ein typisches symfony-Template. Es enthält HTML-Code und ein wenig PHP-Code, normalerweise, um auf Variablen zuzugreifen, die in der Aktion definiert wurden (mit `$this->name = 'foo';`) und auf Helfer. 
     23Codeabschnitt 7-1 zeigt ein typisches Symfony-Template. Es enthält HTML-Code und ein wenig PHP-Code, normalerweise, um auf Variablen zuzugreifen, die in der Aktion definiert wurden (mit `$this->name = 'foo';`) und auf Helfer. 
    2424 
    2525Codeabschnitt 7-1 - Ein beispielhaftes indexSuccess.php-Template 
    4848 
    4949    [php] 
    50     <?php 
    5150    function input_tag($name, $value = null) 
    5251    { 
    5352      return '<input type="text" name="'.$name.'" id="'.$name.'"value="'.$value.'" />'; 
    5453    } 
    55     ?> 
    56  
    57 In Wirklichkeit ist die `input_tag()`-Funktion von symfony etwas komplizierter, da sie einen dritten Parameter akzeptiert, um dem `<input>`-Tag weitere Attribute hinzuzufügen. Sie können die komplette Syntax und alle Möglichkeiten in der Online-API-Dokumentation (http://www.symfony-project.com/api/symfony.html) einsehen. 
     54 
     55In Wirklichkeit ist die `input_tag()`-Funktion von Symfony etwas komplizierter, da sie einen dritten Parameter akzeptiert, um dem `<input>`-Tag weitere Attribute hinzuzufügen. Sie können die komplette Syntax und alle Möglichkeiten in der Online-API-Dokumentation ([http://www.symfony-project.org/api/symfony.html](http://www.symfony-project.org/api/symfony.html)) einsehen. 
    5856 
    5957Meistens beinhalten Helfer aber eine gewisse Intelligenz und ersparen es Ihnen somit, langen und komplizierten Code zu tippen: 
    6563Helfer vereinfachen das Schreiben von Templates und produzieren den bestmöglichen HTML-Code hinsichtlich Performance und Zugänglichkeit. Sie können immer noch reines HTML verwenden, aber mit Helfern geht es normalerweise schneller. 
    6664 
    67 >**TIP** 
    68 >Möglicherweise wundern Sie sich darüber, dass die Helfer nach der Unterstrich-Syntax benannt sind und nicht nach der camelCase-Konvention, die sonst überall in symfony verwendet wird. Das ist deshalb so, weil Helfer Funktionen sind, und alle Kern-PHP-Funktionen benutzen die Unterstrich-Syntaxkonvention. 
     65>**TIPP** 
     66>Möglicherweise wundern Sie sich darüber, dass die Helfer nach der Unterstrich-Syntax benannt sind und nicht nach der camelCase-Konvention, die sonst überall in Symfony verwendet wird. Das ist deshalb so, weil Helfer Funktionen sind, und alle Kern-PHP-Funktionen benutzen die Unterstrich-Syntaxkonvention. 
    6967 
    7068#### Helfer deklarieren 
    7169 
    72 Die symfony-Dateien mit den Helferdefinitionen werden nicht automatisch geladen (weil sie Funktionen enthalten, und keine Klassen). Helfer sind nach Einsatzzweck sortiert. Beispielsweise sind alle Helferfunktionen, die mit Text zu tun haben, in einer Datei `TextHelper.php` enthalten, die `Text`-Helfergruppe. Wenn Sie also in einem Template einen Helfer benötigen, müssen Sie zuvor im Template die entsprechende Helfergruppe laden mit der `use_helper()`-Funktion. Codeabschnitt 7-3 zeigt ein Template, das den `auto_link_text()`-Helfer benutzt, der Teil der Texthelfer-Gruppe ist. 
     70Die Symfony-Dateien mit den Helferdefinitionen werden nicht automatisch geladen (weil sie Funktionen enthalten, und keine Klassen). Helfer sind nach Einsatzzweck sortiert. Beispielsweise sind alle Helferfunktionen, die mit Text zu tun haben, in einer Datei `TextHelper.php` enthalten, die `Text`-Helfergruppe. Wenn Sie also in einem Template einen Helfer benötigen, müssen Sie zuvor im Template die entsprechende Helfergruppe laden mit der `use_helper()`-Funktion. Codeabschnitt 7-3 zeigt ein Template, das den `auto_link_text()`-Helfer benutzt, der Teil der Texthelfer-Gruppe ist. 
    7371 
    7472Codeabschnitt 7-3 - Die Benutzung eines Helfers deklarieren 
    7674    [php] 
    7775    // Benutze eine bestimmte Helfergruppe in diesem Template 
    78     <?php echo use_helper('Text') ?> 
     76    <?php use_helper('Text') ?> 
    7977    ... 
    8078    <h1>Beschreibung</h1> 
    8179    <p><?php echo auto_link_text($description) ?></p> 
    8280 
    83     Wenn Sie mehr als eine Helfergruppe deklarieren müssen, fügen Sie entsprechend mehr Argumente zum `use_helper()`-Funktionsaufruf hinzu. Um etwa die `Text`- und die `Javascript`-Helfergruppen in einem Template zu laden, rufen Sie `<?php echo use_helper('Text', 'Javascript') ?>` auf. 
    84  
    85 Einige Helfer sind standardmässig in jedem Template verfügbar, ohne entsprechende Deklaration. Es sind dies die Helfer der folgenden Gruppen: 
     81>**TIPP** 
     82>Wenn Sie mehr als eine Helfergruppe deklarieren müssen, fügen Sie entsprechend mehr Argumente zum `use_helper()`-Funktionsaufruf hinzu. Um etwa die `Text`- und die `Javascript`-Helfergruppen in einem Template zu laden, rufen Sie `<?php echo use_helper('Text', 'Javascript') ?>` auf. 
     83 
     84Einige Helfer sind standardmäßig in jedem Template verfügbar, ohne entsprechende Deklaration. Es sind dies die Helfer der folgenden Gruppen: 
    8685 
    8786  * `Helfer`: Benötigt für das Einbinden anderer Helfer (die `use_helper()`-Funktion ist selbst auch ein Helfer) 
    9392  * `Form`: Formularhelfer 
    9493 
    95 Die Liste der standardmässig geladenen Helfer kann in der `settings.yml`-Datei eingestellt werden. Wenn Sie also wissen, dass Sie die Helfer der Gruppe `Cache` nicht benötigen oder dass Sie immer diejenigen der Textgruppe benötigen, verändern sie die `standard_helpers`-Einstellung entsprechend. Das wird Ihre Applikation etwas beschleunigen. Die ersten vier Helfer in der obigen Liste (`Helper`, `Tag`, `Url` und `Asset`) können Sie nicht entfernen, da Sie zwingend notwendig sind für das Funktionieren der Templateengine. Deshalb erscheinen sie auch nicht in der Liste der Standardhelfer. 
    96  
    97 >**TIP** 
    98 >Sollten Sie einmal einen Helfer ausserhalb eines Templates benötigen, können Sie eine Helfergruppe von überall aus mit `sfLoader::loadHelpers($helpers)` laden, wobei `$helpers` ein Helfergruppenname oder ein Array aus Helfergruppennamen ist. Wenn Sie etwa den `auto_link_text()`-Helfer in einer Aktion benutzen wollen, müssen Sie zuerst `sfLoader::loadHelpers('Text')` aufrufen. 
     94Die Liste der standardmäßig geladenen Helfer kann in der `settings.yml`-Datei eingestellt werden. Wenn Sie also wissen, dass Sie die Helfer der Gruppe `Cache` nicht benötigen oder dass Sie immer diejenigen der Textgruppe benötigen, verändern sie die `standard_helpers`-Einstellung entsprechend. Das wird Ihre Applikation etwas beschleunigen. Die ersten vier Helfer in der obigen Liste (`Helper`, `Tag`, `Url` und `Asset`) können Sie nicht entfernen, da Sie zwingend notwendig sind für das Funktionieren der Templateengine. Deshalb erscheinen sie auch nicht in der Liste der Standardhelfer. 
     95 
     96>**TIPP** 
     97>Sollten Sie einmal einen Helfer außerhalb eines Templates benötigen, können Sie eine Helfergruppe von überall aus mit `sfLoader::loadHelpers($helpers)` laden, wobei `$helpers` ein Helfergruppenname oder ein Array aus Helfergruppennamen ist. Wenn Sie etwa den `auto_link_text()`-Helfer in einer Aktion benutzen wollen, müssen Sie zuerst `sfLoader::loadHelpers('Text')` aufrufen. 
    9998 
    10099#### Häufig benutzte Helfer 
    106105    [php] 
    107106    // Helper-Gruppe 
    108     <?php echo use_helper('Helfername') ?> 
    109     <?php echo use_helper('Helfername1', 'Helfername2', 'Helfername3') ?> 
    110      
     107    <?php use_helper('Helfername') ?> 
     108    <?php use_helper('Helfername1', 'Helfername2', 'Helfername3') ?> 
     109 
    111110    // Tag-Gruppe 
    112111    <?php echo tag('input', array('name' => 'foo', 'type' => 'text')) ?> 
    115114    <?php echo content_tag('textarea', 'Beispieltext', 'name=foo') ?> 
    116115     => <textarea name="foo">Beispieltext</textarea> 
    117      
     116 
    118117    // Url-Gruppe 
    119118    <?php echo link_to('klick mich', 'modul/aktion') ?> 
    120119    => <a href="/pfad/zur/aktion">klick mich</a>  // hängt von den Routing-Einstellungen ab 
    121      
     120 
    122121    // Asset-Gruppe 
    123122    <?php echo image_tag('bild', 'alt=foo size=200x100') ?> 
    128127     => <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" /> 
    129128 
    130 Es gibt viele weitere Helfer in symfony, und es bräuchte eine ganzes Buch, um sie alle zu beschreiben. Die beste Referenz für die Helfer ist die Online-API-Dokumentation (http://www.symfony-project.com/api/symfony.html), wo für alle Helfer ausführlich Syntax, Optionen und Beispiele dokumentiert sind. 
     129Es gibt viele weitere Helfer in Symfony, und es bräuchte eine ganzes Buch, um sie alle zu beschreiben. Die beste Referenz für die Helfer ist die Online-API-Dokumentation ([http:// www.symfony-project.org/api/symfony.html](http://www.symfony-project.org/api/symfony.html)), wo für alle Helfer ausführlich Syntax, Optionen und Beispiele dokumentiert sind. 
    131130 
    132131#### Eigene Helfer hinzufügen 
    133132 
    134 symfony bringt viele Helfer für verschiedenste Zwecke mit, aber wenn Sie in der API-Dokumentation nicht das finden, was Sie benötigen, wollen Sie möglicherweise einen neuen Helfer erstellen. Das ist wirklich sehr einfach. 
    135  
    136 Helferfunktionen (normale PHP-Funktionen, die HTML-Code zurückgeben) sollten in einer Datei `FoobarHelper.php` gespeichert werden, wobei `Foobar` der Name der Helfergruppe ist. Speichern Sie die Datei im `apps/meineapp/lib/helper/`-Verzeichnis (oder in irgendeinem `helper/`-Verzeichnis erstellt in einem der `lib/`-Verzeichnisse Ihres Projekts), und es kann automatisch mit `use_helper('Foobar')` eingebunden werden. 
    137  
    138 >**TIP** 
    139 >Das System erlaubt Ihnen sogar, die existierenden symfony-Helfer zu überschreiben. Um etwa alle Helfer aus der Helfergruppe `Text` neu zu definieren, erzeugen Sie einfach eine Datei `TextHelper.php` in Ihrem `apps/meineapp/lib/helper/`-Verzeichnis. Jedesmal, wenn Sie `use_helper('Text')` aufrufen, wird symfony Ihre `Text`-Helfergruppe statt seine eigene benutzen. Aber Vorsicht: Da die Originaldatei gar nicht mehr beachtet wird, müssen Sie alle Funktionen der Helfergruppe neu definieren; andernfalls werden einige der Originalhelfer nicht mehr verfügbar sein. 
     133Symfony bringt viele Helfer für verschiedenste Zwecke mit, aber wenn Sie in der API-Dokumentation nicht das finden, was Sie benötigen, wollen Sie möglicherweise einen neuen Helfer erstellen. Das ist wirklich sehr einfach. 
     134 
     135Helferfunktionen (normale PHP-Funktionen, die HTML-Code zurückgeben) sollten in einer Datei `FoobarHelper.php` gespeichert werden, wobei `Foobar` der Name der Helfergruppe ist. Speichern Sie die Datei im `apps/frontend/lib/helper/`-Verzeichnis (oder in irgendeinem `helper/`-Verzeichnis erstellt in einem der `lib/`-Verzeichnisse Ihres Projekts), und es kann automatisch mit `use_helper('Foobar')` eingebunden werden. 
     136 
     137>**TIPP** 
     138>Das System erlaubt Ihnen sogar, die existierenden Symfony-Helfer zu überschreiben. Um etwa alle Helfer aus der Helfergruppe `Text` neu zu definieren, erzeugen Sie einfach eine Datei `TextHelper.php` in Ihrem `apps/frontend/lib/helper/`-Verzeichnis. Jedesmal, wenn Sie `use_helper('Text')` aufrufen, wird Symfony Ihre `Text`-Helfergruppe statt seine eigene benutzen. Aber Vorsicht: Da die Originaldatei gar nicht mehr beachtet wird, müssen Sie alle Funktionen der Helfergruppe neu definieren; andernfalls werden einige der Originalhelfer nicht mehr verfügbar sein. 
    140139 
    141140### Seitenlayout 
    143142Das Template in Codeabschnitt 7-1 ist kein gültiges XHTML-Dokument. Die `DOCTYPE`-Definition und die `<html>`- und `<body>`-Tags fehlen. Das liegt darain, dass sie anderswo in der Applikation gespeichert sind, in einer Datei `layout.php`, die das Seitenlayout enthält. Diese Datei, das globale Template, speichert den HTML-Code, der allen Seiten der Applikation gemeinsam ist, um zu verhindern, dass er in jedem Template wiederholt werden muss. Der Inhalt eines Templates wird ins Layout eingebettet oder, andersherum betrachtet, das Layout "dekoriert" das Template. Das ist eine Anwendung des Decorator-Design-Patterns, zu sehen in Abbildung 7-1. 
    144143 
    145 >**TIP** 
     144>**TIPP** 
    146145>Für weitere Informationen über das Decorator- und anderen Design-Pattern, siehe *Patterns of Enterprise Application Architecture* von Martin Fowler (Addison-Wesley, ISBN: 0-32112-742-0). 
    147146 
    152151Codeabschnitt 7-5 zeigt das Standard-Seitenlayout, zu finden im `templates/`-Verzeichnis der Applikation. 
    153152 
    154 Codeabschnitt 7-5 - Standardlayout in `meinprojekt/apps/meineapp/templates/layout.php` 
     153Codeabschnitt 7-5 - Standardlayout in `meinprojekt/apps/frontend/templates/layout.php` 
    155154 
    156155    [php] 
    203202### Template-Shortcuts 
    204203 
    205 In den Templates sind einige symfony-Variablen immer verfügbar. Diese Shortcuts ermöglichen den Zugriff auf die wichtigsten Informationen über die symfony-Kern-Objekte: 
     204In den Templates sind einige Symfony-Variablen immer verfügbar. Diese Shortcuts ermöglichen den Zugriff auf die wichtigsten Informationen über die Symfony-Kern-Objekte: 
    206205 
    207206  * `$sf_context`: Das Context-Object (Instanz von `sfContext`) 
    210209  * `$sf_user`: Das aktuelle User-Session-Objekt (Instanz von `sfUser`) 
    211210 
    212 Das vorherige Kapitel hat hilfreiche Methoden des `sfRequest`- und des `sfUser`-Objekts beschrieben. Sie können diese Methoden in Templates durch die `$sf_request`- und `$sf_user`-Variablen aufrufen. Wenn zum Beispiel der Request einen `total`-Parameter enthält, ist sein Wert im Template folgendermassen verfügbar: 
     211Das vorherige Kapitel hat hilfreiche Methoden des `sfRequest`- und des `sfUser`-Objekts beschrieben. Sie können diese Methoden in Templates durch die `$sf_request`- und `$sf_user`-Variablen aufrufen. Wenn zum Beispiel der Request einen `total`-Parameter enthält, ist sein Wert im Template folgendermaßen verfügbar: 
    213212 
    214213    [php] 
    227226Oft müssen Sie HTML- oder PHP-Code in mehrere Seiten einbinden. Die PHP-`include()`-Funktion hilft Ihnen dabei, dass Sie den Code nicht jedesmal wiederholen müssen. 
    228227 
    229 Wenn zum Beispiel viele Templates Ihrer Applikation das gleiche Codefragment benötigen, speichern Sie es in einer Datei `meinFragment.php` im globalen Template-Verzeichns (`meinprojekt/apps/meineapp/templates/`) und binden es in Ihr Template wie folgt ein: 
     228Wenn zum Beispiel viele Templates Ihrer Applikation das gleiche Codefragment benötigen, speichern Sie es in einer Datei `meinFragment.php` im globalen Template-Verzeichns (`meinprojekt/apps/frontend/templates/`) und binden es in Ihr Template wie folgt ein: 
    230229 
    231230    [php] 
    232231    <?php include(sfConfig::get('sf_app_template_dir').'/meinFragment.php') ?> 
    233232 
    234 Aber das ist keine sehr saubere Art, ein Fragment zu verpacken, vor allem deshalb, weil sie verschiedene Variablennamen im Fragment und den verschiedenen Templates haben können, die es einbinden. Ausserdem hat das symfony-Cachesystem (näheres dazu in Kapitel 12) keine Möglichkeit, includes zu erkennen, das Codefragment kann also nicht uanbhängig vom Template im Cache abgelegt werden. symfony bietet drei Alternativen zu gewöhnlichen `include`s: 
     233Aber das ist keine sehr saubere Art, ein Fragment zu verpacken, vor allem deshalb, weil sie verschiedene Variablennamen im Fragment und den verschiedenen Templates haben können, die es einbinden. Außerdem hat das Symfony-Cachesystem (näheres dazu in Kapitel 12) keine Möglichkeit, includes zu erkennen, das Codefragment kann also nicht uanbhängig vom Template im Cache abgelegt werden. Symfony bietet drei Alternativen zu gewöhnlichen `include`s: 
    235234 
    236235  * Wenn die Logik simpel ist, können Sie einfach eine Templatedatei nehmen, der Sie einige Daten übergeben. Dazu verwenden Sie ein Partial. 
    238237  * Wenn das Fragment einen bestimmten Teil des Layouts ersetzen soll, für den möglicherweise bereits Standardinhalt definiert wurde, brauchen Sie ein Slot. 
    239238 
    240     Ein weiterer Codefragment-Typ, ein Component Slot, wird benutzt, wenn der Inhalt des Fragments vom Kontext abhäng (z.B. wenn das Fragment für verschiedene Aktionen eines Moduls unterschiedlichen Inhalt hat). Component Slots werden später in diesem Kapitel noch genauer beschrieben. 
    241  
    242 Die Einbindung dieser Fragmente geschieht durch Helfer der Partial-Gruppe. Diese Helfer sind in jedem symfony-Template ohne Deklaration verfügbar. 
     239>**NOTE** 
     240>Ein weiterer Codefragment-Typ, ein Component Slot, wird benutzt, wenn der Inhalt des Fragments vom Kontext abhäng (z.B. wenn das Fragment für verschiedene Aktionen eines Moduls unterschiedlichen Inhalt hat). Component Slots werden später in diesem Kapitel noch genauer beschrieben. 
     241 
     242Die Einbindung dieser Fragmente geschieht durch Helfer der Partial-Gruppe. Diese Helfer sind in jedem Symfony-Template ohne Deklaration verfügbar. 
    243243 
    244244### Partials 
    257257 
    258258    [php] 
    259     // Binde das meineapp/modules/meinmodul/templates/_meinpartial1.php-Partial ein 
     259    // Binde das Partial frontend/modules/meinmodul/templates/_meinpartial1.php ein 
    260260    // Da das Template und das Partial im gleichen Modul sind, 
    261261    // können Sie den Modulnamen weglassen 
    262262    <?php include_partial('meinpartial1') ?> 
    263263     
    264     // Binde das meineapp/modules/foobar/templates/_meinpartial2.php-Partial ein 
     264    // Binde das Partial frontend/modules/foobar/templates/_meinpartial2.php ein 
    265265    // Hier muss der Modulname angegeben werden 
    266266    <?php include_partial('foobar/meinpartial2') ?> 
    267267     
    268     // Binde das meineapp/templates/_meinpartial3.php-Partial ein 
     268    // Binde das Partial frontend/templates/_meinpartial3.php ein 
    269269    // Es wird als Teil des 'global'-Moduls betrachtet 
    270270    <?php include_partial('global/meinpartial3') ?> 
    271271 
    272 Partials haben Zugriff auf die üblichen symfony-Helfer und Template-Shortcuts. Aber weil Partials überall in der Applikation aufgerufen werden können, haben sie nicht automatisch Zugriff auf die Variablen der Aktion, die das Template aufruft, in dem sie sich befinden - ausser, wenn die Variablen explizit als Argument übergeben werden. Wenn etwa ein Partial Zugriff auf eine Variable `$total` haben soll, muss die Aktion diese dem Template übergeben und das Template sie dann dem Helfer als zweites Argument des `include_partial()`-Aufrufs, siehe Codeabschnitte 7-8, 7-9 und 7-10. 
     272Partials haben Zugriff auf die üblichen Symfony-Helfer und Template-Shortcuts. Aber weil Partials überall in der Applikation aufgerufen werden können, haben sie nicht automatisch Zugriff auf die Variablen der Aktion, die das Template aufruft, in dem sie sich befinden - außer, wenn die Variablen explizit als Argument übergeben werden. Wenn etwa ein Partial Zugriff auf eine Variable `$total` haben soll, muss die Aktion diese dem Template übergeben und das Template sie dann dem Helfer als zweites Argument des `include_partial()`-Aufrufs, siehe Codeabschnitte 7-8, 7-9 und 7-10. 
    273273 
    274274Codeabschnitt 7-8 - Die Aktion definiert eine Variable in `meinmodul/actions/actions.class.php` 
    296296    <p>Total: <?php echo $meintotal ?></p> 
    297297 
    298 >**TIP** 
     298>**TIPP** 
    299299>Bisher wurden alle Helfer mit `<?php echo functionName() ?>` aufgerufen. Der Partial-Helper hingegen wird einfach nur mit `<?php include_partial() ?>` aufgerufen - ohne `echo`, so verhält es sich ähnlich dem normalen PHP-`include()`-Befehl. Sollten Sie jemals eine Funktion benötigen, die den Inhalt eines Partials zurückgibt ohne ihn anzuzeigen, verwenden Sie `get_partial()`. Alle in diesem Kapitel beschriebenen `include_`-Helfer haben ein `get_`-Pendant, das zusammen mit einem `echo` verwendet werden kann. 
     300 
     301>**TIPP** 
     302>**Neu in Symfony 1.1**: Anstelle eines Templates kann eine Aktion auch ein Partial zurückgeben. Die Methode `renderPartial()` in der Aktion fördert die Wiederverwendbarkeit von Code und nutzt die Cache-Fähigkeiten der Partials (siehe Kapitel 12). Die Variablen, die in der Aktion definiert sind, werden dem Partial automatisch übergeben. 
     303> 
     304>     [php] 
     305>     public function executeIndex() 
     306>     { 
     307>       // Dinge tun 
     308>       $this->mytotal = 1234; 
     309> 
     310>       return $this->renderPartial('meinmodul/meinpartial'); 
     311>     } 
     312> 
     313 
    300314 
    301315### Komponenten 
    314328Präsentationsdatei    | `meineAktionSuccess.php` | `_meineKomponente.php` 
    315329 
    316 >**TIP** 
     330>**TIPP** 
    317331>Genau wie Sie Sie Aktionsdateien aufspalten können, hat die `sfComponents`-Klasse ein `sfComponent`-Pendant, das einzelne Komponentendateien mit der gleichen Syntax erlaubt. 
    318332 
    329343    [php] 
    330344    <?php 
    331      
     345 
    332346    class newsKomponenten extends sfComponents 
    333347    { 
    368382    // Komponente einbinden 
    369383    <?php include_component('news', 'headlines', array('foo' => 'bar')) ?> 
    370      
     384 
    371385    // In der Komponente selbst 
    372386    echo $this->foo; 
    373387     => 'bar' 
    374      
     388 
    375389    // Im _headlines.php-Partial 
    376390    echo $foo; 
    381395### Slots 
    382396 
    383 Partials und Komponenten dienen der Wiederbenutzbarkeit. Aber oft sollen Codefragmente ein Layout mit verschiedenen dynamischen Bereichen ausfüllen. Beispielsweise möchten Sie einige individuelle Tags in den `<head>`-Bereich Ihres Layouts einbinden, abhängig von der aufgerufenen Aktion. Oder die Aktion füllt verschiedene grössere dynamische Bereiche auf der Seite und zusätzlich viele kleinere, für die ein Standardinhalt im Layout festgelegt ist, der aber von Templates überschrieben werden kann. 
     397Partials und Komponenten dienen der Wiederbenutzbarkeit. Aber oft sollen Codefragmente ein Layout mit verschiedenen dynamischen Bereichen ausfüllen. Beispielsweise möchten Sie einige individuelle Tags in den `<head>`-Bereich Ihres Layouts einbinden, abhängig von der aufgerufenen Aktion. Oder die Aktion füllt verschiedene größere dynamische Bereiche auf der Seite und zusätzlich viele kleinere, für die ein Standardinhalt im Layout festgelegt ist, der aber von Templates überschrieben werden kann. 
    384398 
    385399In solchen Situationen ist die Lösung ein Slot. Ein Slot ist ein Platzhalter, den man in einem beliebigen View-Element einsetzen kann. (Layout, Template, Partial) Diesen Platzhalter ausfüllen ist genau wie eine Variable setzen. Der Code, mit dem der Slot gefüllt wird, wird im Response-Objekt gespeichert, Sie können es also in jedem View-Element definieren. Nur sollten Sie sicherstellen, dass ein Slot definiert ist, bevor er eingebunden wird; und denken Sie daran: Das Layout wird nach dem Template gerendert (das ist der Dekorationsprozess), und die Partials werden dann gerendert, wenn sie von einem Template aus aufgerufen werden. Klingt zu kompliziert? Sehen wir uns ein Beispiel an. 
    407421    </div> 
    408422 
    409 Jedes Template kann die Inhalt eines Slots definieren (sogar Partials können das). Da Slots dazu gedacht sind, HTML-Code zu beinhalten, bietet symfony einen komfortablen Weg, sie zu definieren: Schreiben Sie den Slot-Code einfach zwischen einen Aufruf des `slot()`- und des `end_slot()`-Helfer, so wie in Codeabschnitt 7-15. 
     423Jedes Template kann die Inhalt eines Slots definieren (sogar Partials können das). Da Slots dazu gedacht sind, HTML-Code zu beinhalten, bietet Symfony einen komfortablen Weg, sie zu definieren: Schreiben Sie den Slot-Code einfach zwischen einen Aufruf des `slot()`- und des `end_slot()`-Helfer, so wie in Codeabschnitt 7-15. 
    410424 
    411425Codeabschnitt 7-15 - Den Inhalt von Slot `'sidebar'` in einem Template überschreiben 
    420434    <?php end_slot() ?> 
    421435 
    422 Der Code zwischen den Slothelfern wird im Kontext des Templates ausgeführt, es hat also keinen Zugriff auf die Variablen der Aktion. symfony fügt diesen Code automatisch dem Response-Objekt hinzu. Es wird nicht im Template angezeigt, aber ist für künftige `include_slot()`-Aufrufe verfügbar, wie in Codeabschnitt 7-14  zu sehen. 
     436Der Code zwischen den Slothelfern wird im Kontext des Templates ausgeführt, es hat also keinen Zugriff auf die Variablen der Aktion. Symfony fügt diesen Code automatisch dem Response-Objekt hinzu. Es wird nicht im Template angezeigt, aber ist für künftige `include_slot()`-Aufrufe verfügbar, wie in Codeabschnitt 7-14  zu sehen. 
    423437 
    424438Slots sind sehr nützlich für Bereiche mit individuellem Inhalt. Sie können auch benutzt werden, wenn HTML-Code nur von gewissen Aktionen angezeigt werden soll. Zum Beispiel hat es in einem Template, das die Liste der neusten Nachrichten anzeigt, im `<head>`-Bereich des Layouts einen Link zu einem RSS-Feed. Das kann man mit einem `'feed'`-Slot im Layout lösen, den man dann im Template der Liste setzt. 
    427441>Wo die Templatefragmente zu finden sind 
    428442> 
    429 >Leute, die mit Templates arbeiten, sind normalerweise Webdesigner, die symfony möglicherweise nicht gut kennen und Schiwerigkeiten haben, Templatefragmente zu finden, da diese überall in der Applikation verteilt sein können. Diese Richtlinien wird ihnen die Arbeit mit dem symfony-Templatingsystem erleichtern. 
     443>Leute, die mit Templates arbeiten, sind normalerweise Webdesigner, die Symfony möglicherweise nicht gut kennen und Schiwerigkeiten haben, Templatefragmente zu finden, da diese überall in der Applikation verteilt sein können. Diese Richtlinien wird ihnen die Arbeit mit dem Symfony-Templatingsystem erleichtern. 
    430444> 
    431 >Obwohl ein symfony-Projekt viele Verzeichnisse enthält, befinden sich alle Layouts, Templates und Templatefragmente in Verzeichnissen mit dem Namen `templates/`. Was also den Webdesigner angeht, kann eine Projektstruktur auf das folgende vereinfacht werden: 
     445>Obwohl ein Symfony-Projekt viele Verzeichnisse enthält, befinden sich alle Layouts, Templates und Templatefragmente in Verzeichnissen mit dem Namen `templates/`. Was also den Webdesigner angeht, kann eine Projektstruktur auf das folgende vereinfacht werden: 
     446
    432447> 
    433448>    meinproject/ 
    443458>              templates/   # Templates und Partials für Modul 3 
    444459> 
     460> 
    445461>Alle anderen Verzeichnisse können ignoriert werden. 
    446462> 
    447 >Wenn sie auf ein `include_partial()` treffen, müssen Webdesigner lediglich verstehen, dass nur das erste Argument wichtig ist. Dieses Argument ist immer von der Form `modul_name/partial_name`, und das heisst, dass sich der Präsentationscode in `modules/modul_name/templates/_partial_name.php` befindet. 
     463>Wenn sie auf ein `include_partial()` treffen, müssen Webdesigner lediglich verstehen, dass nur das erste Argument wichtig ist. Dieses Argument ist immer von der Form `modul_name/partial_name`, und das heißt, dass sich der Präsentationscode in `modules/modul_name/templates/_partial_name.php` befindet. 
    448464> 
    449465>Beim `include_component()`-Helfer ist es so, dass Modulname und Partialname die ersten beiden Argumente sind. Für den Rest genügt es eigentlich, eine grundsätzliche Idee davon zu haben, was Helfer sind und welche Helfer am häufigsten in Templates verwendet werden. 
    452468------------------ 
    453469 
    454 In symfony besteht eine View aus zwei unabhängigen Teilen: 
     470In Symfony besteht eine View aus zwei unabhängigen Teilen: 
    455471 
    456472  * Die HTML-Darstellung des Ergebnisses einer Aktion (gespeichert in einem Template, im Layout und in den verschiedenen Templatefragmenten) 
    457473  * Der ganze Rest, darunter folgendes: 
     474 
    458475    * Metadeklarationen: Stichwörter, Beschreibung, Cache-Dauer usw. 
    459476    * Seitentitel: Hilft nicht nur beim Tabbed Browsing, Ihre Seite zu finden, sondern ist auch für Suchmaschinen sehr wichtig. 
    461478    * Layout: Gewisse Aktionen benötigen ein individuelles Layout (Pop-Ups, Werbungen usw.) oder überhaupt kein Layout (z.B. Ajax-Aktionen). 
    462479 
    463 In der View wird alles, das nicht HTML ist, als View-Konfiguration bezeichnet, und symfony bietet zwei Möglichkeiten, diese zu bearbeiten. Der normale Weg geht über die `view.yml`-Konfigurationsdatei. Sie kann immer dann benutzt werden, wenn Werte nicht vom Kontext oder von Datenbank-Querys abhängen. Wenn Sie jedoch dynamische Werte setzen müssen, sollten Sie die alternative Möglichkeit verwenden und die Konfiguration direkt über das `sfResponse`-Objekt in der Aktion selbst bearbeiten. 
     480In der View wird alles, das nicht HTML ist, als View-Konfiguration bezeichnet, und Symfony bietet zwei Möglichkeiten, diese zu bearbeiten. Der normale Weg geht über die `view.yml`-Konfigurationsdatei. Sie kann immer dann benutzt werden, wenn Werte nicht vom Kontext oder von Datenbank-Querys abhängen. Wenn Sie jedoch dynamische Werte setzen müssen, sollten Sie die alternative Möglichkeit verwenden und die Konfiguration direkt über das `sfResponse`-Objekt in der Aktion selbst bearbeiten. 
    464481 
    465482>**NOTE** 
    475492      metas: 
    476493        title: Bearbeiten Sie ihr Profil 
    477      
     494 
    478495    editError: 
    479496      metas: 
    480497        title: Fehler bei der Bearbeitung des Profils 
    481      
     498 
    482499    all: 
    483500      stylesheets: [mein_style] 
    486503 
    487504>**ACHTUNG** 
    488 >Achten Sie darauf, dass die Hauptschlüssel in der `view.yml` Viewnamen sind und keine Aktionsnamen. Zur Erinnerung: Ein Viewname setzt sich zusammen aus einem Aktionsnamen und einem Aktions-Beende-Namen. Wenn die `edit`-Aktion `sfView::SUCCESS` zurückgibt (oder gar nichts, da dies die standardmässige Rückgabe ist), dann ist der Viewname `editSuccess`. 
     505>Achten Sie darauf, dass die Hauptschlüssel in der `view.yml` Viewnamen sind und keine Aktionsnamen. Zur Erinnerung: Ein Viewname setzt sich zusammen aus einem Aktionsnamen und einem Aktions-Beende-Namen. Wenn die `edit`-Aktion `sfView::SUCCESS` zurückgibt (oder gar nichts, da dies die standardmäßige Rückgabe ist), dann ist der Viewname `editSuccess`. 
    489506 
    490507Die Standardeinstellungen für ein Modul sind unter dem `all:`-Schlüssel in der Modul-`view.yml` definiert. Die Standardeinstellungen für alle Applilkationsviews befinden sich in der Applikations-`view.yml`. Wieder einmal erkennen Sie hier die Verschachtelung der Konfiguration: 
    491508 
    492   * In `apps/meineapp/modules/meinmodul/config/view.yml` können Sie Definitionen für einzelne Views festlegen, die die modulweiten Definitionen überschreiben 
    493   * In `apps/meineapp/modules/meinmodul/config/view.yml` können Sie unter dem `all:`-Schlüssel Viewdefinitionen für alle Aktionen des Moduls festlegen, die die applikationsweiten Definitionen überschreiben. 
    494   * In `apps/meineapp/config/view.yml` können Sie applikationsweite Definitionen festlegen, die für alle Module und alle Aktionen der Applikation gelten. 
    495  
    496 Modulweite `view.yml`-Dateien existieren standardmässig überhaupt nicht. Sie müssen also, wenn Sie das erste Mal eine Viewkonfiguration für ein bestimmtes Modul anpassen wollen, eine `view.yml` im `config/`-Verzeichnis dieses Moduls anlegen. 
     509  * In `apps/frontend/modules/meinmodul/config/view.yml` können Sie Definitionen für einzelne Views festlegen, die die modulweiten Definitionen überschreiben 
     510  * In `apps/frontend/modules/meinmodul/config/view.yml` können Sie unter dem `all:`-Schlüssel Viewdefinitionen für alle Aktionen des Moduls festlegen, die die applikationsweiten Definitionen überschreiben. 
     511  * In `apps/frontend/config/view.yml` können Sie applikationsweite Definitionen festlegen, die für alle Module und alle Aktionen der Applikation gelten. 
     512 
     513>**TIPP** 
     514>Modulweite `view.yml`-Dateien existieren standardmäßig überhaupt nicht. Sie müssen also, wenn Sie das erste Mal eine Viewkonfiguration für ein bestimmtes Modul anpassen wollen, eine `view.yml` im `config/`-Verzeichnis dieses Moduls anlegen. 
    497515 
    498516Nachdem Sie das Standardtemplate in Codeabschnitt 7-5 und ein Beispiel der fertigen Antwort in Codeabschnitt 7-6 gesehen haben, fragen Sie sich vielleicht, wo die Header-Werte herkommen. Die kommen schlicht und einfach aus den Standard-Vieweinstellungen, definiert in der Applikations-`view.yml`, zu sehen in Codeabschnitt 7-17. 
    499517 
    500 Codeabschnitt 7-17 - Standard-Applikations-Viewkonfiguration in `apps/meineapp/config/view.yml` 
     518Codeabschnitt 7-17 - Standard-Applikations-Viewkonfiguration in `apps/frontend/config/view.yml` 
    501519 
    502520    default: 
    503521      http_metas: 
    504522        content-type: text/html 
    505      
     523 
    506524      metas: 
    507525        title:        Symfony-Projekt 
    510528        keywords:     symfony, projekt 
    511529        language:     de 
    512      
     530 
    513531      stylesheets:    [main] 
    514      
     532 
    515533      javascripts:    [ ] 
    516      
     534 
    517535      has_layout:     on 
    518536      layout:         layout 
    522540### Das Response-Objekt 
    523541 
    524 Obwohl es eigentlich Bestandteil der View-Ebene ist, wird das Response-Objekt oft von der Aktion selbst verändert. Aktionen können auf das symfony-Response-Objekt, `sfResponse`, mittels der `getResponse()`-Methode zugreifen. Codeabschnitt 7-18 zeigt einige der häufig verwendeten `sfResponse`-Methoden. 
     542Obwohl es eigentlich Bestandteil der View-Ebene ist, wird das Response-Objekt oft von der Aktion selbst verändert. Aktionen können auf das Symfony-Response-Objekt, `sfResponse`, mittels der `getResponse()`-Methode zugreifen. Codeabschnitt 7-18 zeigt einige der häufig verwendeten `sfResponse`-Methoden. 
    525543 
    526544Codeabschnitt 7-18 - Aktionen haben Zugriff auf die `sfResponse`-Objektmethoden 
    527545 
    528546    [php] 
    529     <?php 
    530547    class meinmodulActions extends sfActions 
    531548    { 
    533550      { 
    534551        $response = $this->getResponse(); 
    535      
     552 
    536553        // HTTP-Header 
    537554        $response->setContentType('text/xml'); 
    540557        $response->addVaryHttpHeader('Accept-Language'); 
    541558        $response->addCacheControlHttpHeader('no-cache'); 
    542      
     559 
    543560        // Cookies 
    544561        $response->setCookie($name, $content, $expire, $path, $domain); 
    545      
     562 
    546563        // Metadaten und Titel 
    547564        $response->addMeta('robots', 'NONE'); 
    552569      } 
    553570    } 
    554     ?> 
    555571 
    556572Zusätzlich zu den setter-Methoden, die Sie hier sehen können, hat die `sfResponse`-Klasse auch getter, die den aktuellen Wert eines Response-Attributes zurückgeben. 
    557573 
    558 Die Header-Setter in symfony sind sehr hilfreich. Header werden erst so spät wie möglich geschickt (im `sfRenderingFilter`), Sie können Sie also so oft und so stark ändern, wie Sie wollen. Die Setter bieten Ihnen auch sehr nützliche Shortcuts. Wenn Sie beispielsweise keinen Zeichensatz spezifizieren beim Aufruf von `setContentType()`, dann fügt symfony automatisch den Standard-Zeichensatz aus der `settings.yml` hinzu. 
     574Die Header-Setter in Symfony sind sehr hilfreich. Header werden erst so spät wie möglich geschickt (im `sfRenderingFilter`), Sie können Sie also so oft und so stark ändern, wie Sie wollen. Die Setter bieten Ihnen auch sehr nützliche Shortcuts. Wenn Sie beispielsweise keinen Zeichensatz spezifizieren beim Aufruf von `setContentType()`, dann fügt Symfony automatisch den Standard-Zeichensatz aus der `settings.yml` hinzu. 
    559575 
    560576    [php] 
    563579     => 'text/xml; charset=utf-8' 
    564580 
    565 Der Statuscode von Antworten in symfony entspricht der HTTP-Spezifikation. Exceptions liefern einen Status 500, nicht gefundene Seiten 404, normale Seiten 200, nicht veränderte Seiten können Status 304 zurückgeben (siehe Kapitel 12 für Details) usw. Aber Sie können diese Standards überschreiben, indem Sie Ihren eigenen Statuscode in der Aktion mit der `setStatusCode()`-Response-Methode definieren. Sie können Ihren eigenen Code und Ihre eigene Nachricht definieren, oder auch nur Ihren eigenen Code -- in diesem Fall wird symfony die passende Nachricht zu diesem Code automatisch hinzufügen. 
    566  
    567     [php] 
    568     $response->setStatusCode(404, 'This page no longer exists'); 
    569  
    570 >**TIP** 
    571 >Bevor die Header geschickt werden, normalisiert symfony ihre Namen. Sie müssen sich also nicht darum kümmern, ob Sie in einem `setHttpHeader()`-Aufruf `content-language` anstatt `Content-Language` schreiben, symfony versteht auch ersteres und wandelt es automatisch in die korrekte Schreibweise um. 
     581Der Statuscode von Antworten in Symfony entspricht der HTTP-Spezifikation. Exceptions liefern einen Status 500, nicht gefundene Seiten 404, normale Seiten 200, nicht veränderte Seiten können Status 304 zurückgeben (siehe Kapitel 12 für Details) usw. Aber Sie können diese Standards überschreiben, indem Sie Ihren eigenen Statuscode in der Aktion mit der `setStatusCode()`-Response-Methode definieren. Sie können Ihren eigenen Code und Ihre eigene Nachricht definieren, oder auch nur Ihren eigenen Code -- in diesem Fall wird Symfony die passende Nachricht zu diesem Code automatisch hinzufügen. 
     582 
     583    [php] 
     584    $response->setStatusCode(404, 'Diese Seite existiert nicht mehr'); 
     585 
     586>**TIPP** 
     587>Bevor die Header geschickt werden, normalisiert Symfony ihre Namen. Sie müssen sich also nicht darum kümmern, ob Sie in einem `setHttpHeader()`-Aufruf `content-language` anstatt `Content-Language` schreiben, Symfony versteht auch ersteres und wandelt es automatisch in die korrekte Schreibweise um. 
    572588 
    573589### View-Konfigurationseinstellungen 
    588604    http_metas: 
    589605      cache-control: public 
    590      
     606 
    591607    metas: 
    592608      description:   Finanzen in Frankreich 
    600616    $this->getResponse()->addMeta('keywords', 'finanzen, frankreich'); 
    601617 
    602 Einen existierenden Schlüssel hinzufügen ersetzt standardmässig seinen aktuellen Inhalt. Für HTTP-Meta-Tags können Sie einen dritten Parameter übergeben – ist dieser auf `false` gesetzt, hängt die `addHttpMeta()`-Methode (genau wie die `setHttpHeader()`-Methode) den Wert an den existierenden an, statt ihn zu ersetzen. 
     618Einen existierenden Schlüssel hinzufügen ersetzt standardmäßig seinen aktuellen Inhalt. Für HTTP-Meta-Tags können Sie einen dritten Parameter übergeben – ist dieser auf `false` gesetzt, hängt die `addHttpMeta()`-Methode (genau wie die `setHttpHeader()`-Methode) den Wert an den existierenden an, statt ihn zu ersetzen. 
    603619 
    604620    [php] 
    608624     => 'en, fr' 
    609625 
    610 Damit diese Metatags im fertigen Dokument erscheinen, müssen der `include_http_metas()`- und der `include_metas()`-Helfer im `<head>`-Bereich aufgerufen werden. (Das wird im Standardlayout automatisch gemacht; siehe Codeabschnitt 7-5.) symfony sammelt automatisch die Einstellungen aus allen `view.yml`-Dateien (inklusive derjenigen in Codeabschnitt 7-17) und wandelt sie in `meta`-Tags um. Das Beispiel aus Codeabschnitt 7-19 verwandelt sich also in Codeabschnitt 7-21. 
     626Damit diese Metatags im fertigen Dokument erscheinen, müssen der `include_http_metas()`- und der `include_metas()`-Helfer im `<head>`-Bereich aufgerufen werden. (Das wird im Standardlayout automatisch gemacht; siehe Codeabschnitt 7-5.) Symfony sammelt automatisch die Einstellungen aus allen `view.yml`-Dateien (inklusive derjenigen in Codeabschnitt 7-17) und wandelt sie in `meta`-Tags um. Das Beispiel aus Codeabschnitt 7-19 verwandelt sich also in Codeabschnitt 7-21. 
    611627 
    612628Codeabschnitt 7-21 - Ausgegebene Metatags auf der fertigen Seite 
    623639    http_metas: 
    624640      content-type: text/plain 
    625      
     641 
    626642    has_layout: false 
    627643 
    638654Codeabschnitt 7-23 - Titeldefinition in der Aktion – ermöglicht dynamische Titel 
    639655 
     656    [php] 
    640657    $this->getResponse()->setTitle(sprintf('%d kleine Ferkel', $anzahl)); 
    641658 
    644661#### Konfigurieren der einzubindenden Dateien 
    645662 
    646 Eine CSS- oder JavaScript-Datei zu einer View hinzufügen ist sehr einfach, wie in Codeabschnitt 7-24 und 7-25 zu sehen. 
    647  
    648 Codeabschnitt 7-24 - Dateieinbindung in `view.yml` 
    649  
     663Eine CSS- oder JavaScript-Datei zu einer View hinzufügen ist sehr einfach, wie in Codeabschnitt 7-24 zu sehen. 
     664 
     665Codeabschnitt 7-24 - Dateieinbindung 
     666 
     667    // In der view.yml 
    650668    indexSuccess: 
    651669      stylesheets: [meinstyle1, meinstyle2] 
    652670      javascripts: [meinscript] 
    653671 
    654 Codeabschnitt 7-25 - Dateieinbindung in der Aktion 
    655  
    656     [php] 
    657     <?php 
     672    [php] 
     673    // In der Aktion 
    658674    $this->getResponse()->addStylesheet('meinstyle1'); 
    659675    $this->getResponse()->addStylesheet('meinstyle2'); 
    660676    $this->getResponse()->addJavascript('meinscript'); 
    661     ?> 
    662  
    663 In jedem Fall ist das Argument ein Dateiname. Wenn die Datei eine logische Endung hat (`.css` für ein Stylesheet und `.js` für ein JavaScript), können Sie es auch weglassen. Wenn die Datei in einem logischen Verzeichnis liegt (`/css/` für ein Stylesheet, `/js/` für ein JavaScript), können Sie das ebenfalls weglassen. symfony ist so schlau und findet die korrekte Dateiendung und das korrekte Verzeichnis selbst heraus. 
    664  
    665 Anders als die Meta- und Titel-Definitionen benötigen die Datei-Einbindungen keine Helfer im Template oder Layout. Das heisst, die obigen Einstellungen geben den HTML-Code aus Codeabschnittt 7-26 zurück, egal, was im Template und/Oder im Layout steht. 
    666  
    667 Codeabschnitt 7-26 - Datei-Einbindung – Im Layout wird kein Helfer benötigt 
     677 
     678    // Im Template 
     679    <?php use_stylesheet('mystyle1') ?> 
     680    <?php use_stylesheet('mystyle2') ?> 
     681    <?php use_javascript('myscript') ?> 
     682 
     683In jedem Fall ist das Argument ein Dateiname. Wenn die Datei eine logische Endung hat (`.css` für ein Stylesheet und `.js` für ein JavaScript), können Sie es auch weglassen. Wenn die Datei in einem logischen Verzeichnis liegt (`/css/` für ein Stylesheet, `/js/` für ein JavaScript), können Sie das ebenfalls weglassen. Symfony ist so schlau und findet die korrekte Dateiendung und das korrekte Verzeichnis selbst heraus. 
     684 
     685Anders als die Meta- und Titel-Definitionen benötigen die Datei-Einbindungen keine Helfer im Template oder Layout. Das heißt, die obigen Einstellungen geben den HTML-Code aus Codeabschnittt 7-25 zurück, egal, was im Template und/Oder im Layout steht. 
     686 
     687Codeabschnitt 7-25 - Datei-Einbindung – Im Layout wird kein Helfer benötigt 
     688 
    668689    [php] 
    669690    <head> 
    676697 
    677698>**NOTE** 
    678 >Die Einbindung von CSS und JavaScript in der Antwort wird vom Filter `sfCommonFilter` übernommen. Dieser sucht in der Antwort nach einem `<head>`-Tag und fügt die `<link>`s und `<script>`s direkt vor dem schliessenden `</head>` ein. Wenn kein `<head>`-Tag vorhanden ist, funktioniert die Einbindung nicht. 
    679  
    680 Denken Sie daran: Auch hier findet die Konfigurationskaskade wieder Anwendung: Jede Datei, die in der Applikations-`view.yml` definiert wurde, wird in jeder Seite der Applikation eingebunden. Die Codeabschnitte 7-27, 7-28 und 7-29 demonstrieren dies. 
    681  
    682 Codeabschnitt 7-27 - Beispiel-Applikations-`view.yml` 
     699>Die Einbindung von CSS und JavaScript in der Antwort wird vom Filter `sfCommonFilter` übernommen. Dieser sucht in der Antwort nach einem `<head>`-Tag und fügt die `<link>`s und `<script>`s direkt vor dem schließenden `</head>` ein. Dies bedeutet jedoch auch, dass die Einbindung nicht funktioniert, wenn in Ihrem Layout oder Template kein `<head>`-Tag vorhanden ist. 
     700 
     701Denken Sie daran: Auch hier findet die Konfigurationskaskade wieder Anwendung: Jede Datei, die in der Applikations-`view.yml` definiert wurde, wird in jeder Seite der Applikation eingebunden. Die Codeabschnitte 7-26, 7-27 und 7-28 demonstrieren dies. 
     702 
     703Codeabschnitt 7-26 - Beispiel-Applikations-`view.yml` 
    683704 
    684705    default: 
    685706      stylesheets: [main] 
    686707 
    687 Codeabschnitt 7-28 - Beispiel-Modul-`view.yml` 
     708Codeabschnitt 7-27 - Beispiel-Modul-`view.yml` 
    688709 
    689710    indexSuccess: 
    690711      stylesheets: [special] 
    691      
     712 
    692713    all: 
    693714      stylesheets: [additional] 
    694715 
    695 Codeabschnitt 7-29 - Der View `indexSuccess` als Ergebnis 
     716Codeabschnitt 7-28 - Der View `indexSuccess` als Ergebnis 
    696717 
    697718    [php] 
    700721    <link rel="stylesheet" type="text/css" media="screen" href="/css/special.css" /> 
    701722 
    702 Wenn Sie eine Datei entfernen möchten, die auf einer höheren Stufe definiert wurde, häängen Sie einfach ein Minuszeichen (`-`) vor dem Dateinamen, wie in Codeabschnitt 7-30
    703  
    704 Codeabschnitt 7-30 - Beispiel-Modul-`view.yml`, die eine Datei entfernt, die auf der Applikationsstufe definiert wurde 
     723Wenn Sie eine Datei entfernen möchten, die auf einer höheren Stufe definiert wurde, stellen Sie einfach ein Minuszeichen (`-`) vor den Dateinamen, wie in Codeabschnitt 7-29
     724 
     725Codeabschnitt 7-29 - Beispiel-Modul-`view.yml`, die eine Datei entfernt, die auf der Applikationsstufe definiert wurde 
    705726 
    706727    indexSuccess: 
    707728      stylesheets: [-main, special] 
    708      
     729 
    709730    all: 
    710731      stylesheets: [additional] 
    711732 
    712 Um alle CSS- oder JavaScript-Dateien zu entfernen, verwenden Sie folgende Syntax: 
     733Um alle CSS- oder JavaScript-Dateien zu entfernen, verwenden Sie `-*` als Dateinamen, wie in Codeabschnitt 7-30. 
     734 
     735Codeabschnitt 7-30 - Beispiel-Modul-`view.yml`, die alle Dateien entfernt, die auf der Applikationsstufe definiert wurden 
    713736 
    714737    indexSuccess: 
    716739      javascripts: [-*] 
    717740 
    718 Sie können auch weiter ins Detail gehen und in einem zusätzlichen Parameter angeben, wo genau die Datei eingebunden werden soll (an der ersten oder letzten Stelle): 
     741Sie können auch weiter ins Detail gehen und in einem zusätzlichen Parameter angeben, wo genau die Datei eingebunden werden soll (an der ersten oder letzten Stelle), wie in Codeabschnitt 7-31. Dies funktioniert sowohl für Stylesheets als auch für Javascript-Dateien. 
     742 
     743Codeabschnitt 7-31 - Angabe der Position der einzubindenden Datei 
    719744 
    720745    // In der view.yml 
    726751    $this->getResponse()->addStylesheet('special', 'first'); 
    727752 
    728 Um Medientypen für CSS-Dateien hinzuzufügen, können Sie die Standard-CSS-Tag-Optionen ändern, zu sehen in den Codeabschnitten 7-31, 7-32 und 7-33. 
    729  
    730 Codeabschnitt 7-31 - CSS-Einbindung mit Medientyp in der `view.yml` 
    731  
     753    // Im Template 
     754    <?php use_stylesheet('special', 'first') ?> 
     755 
     756**Neu in Symfony 1.1**: Sie können sich auch dazu entschließen, die Transformation des einzubindenden Dateinamens zu umgehen, so dass die resultierenden `<link>`- bzw. `<script>`-Tags direkt auf den übergebenen Dateiort verweisen, wie in Codeabschnitt 7-32 gezeigt. 
     757 
     758Codeabschnitt 7-32 - CSS-Einbindung mit nicht-transformiertem Dateinamen 
     759 
     760    // In der view.yml 
     761    indexSuccess: 
     762      stylesheets: [main, paper: { raw_name: true }] 
     763 
     764    [php] 
     765    // In der Aktion 
     766    $this->getResponse()->addStylesheet('paper', '', array('raw_name' => true)); 
     767 
     768    // Im Template 
     769    <?php use_stylesheet('paper', '', array('raw_name' => true)) ?> 
     770 
     771    // Resultierender View 
     772    <link rel="stylesheet" type="text/css" media="print" href="paper" /> 
     773 
     774Um Medientypen für CSS-Dateien hinzuzufügen, können Sie die Standard-CSS-Tag-Optionen ändern, zu sehen in den Codeabschnitten 7-33. 
     775 
     776Codeabschnitt 7-33 - CSS-Einbindung mit Medientyp 
     777 
     778    // In der view.yml 
    732779    indexSuccess: 
    733780      stylesheets: [main, paper: { media: print }] 
    734781 
    735 Codeabschnitt 7-32 - CSS-Einbindung mit Medientyp in der Aktion 
    736  
    737     [php] 
    738     <?php 
     782    [php] 
     783    // In der Aktion 
    739784    $this->getResponse()->addStylesheet('paper', '', array('media' => 'print')); 
    740     ?> 
    741  
    742 Codeabschnitt 7-33 - Das Ergebnis 
    743  
    744     [php] 
     785 
     786    // Im Template 
     787    <?php use_stylesheet('paper', '', array('media' => 'print')) ?> 
     788 
     789    // Resultierender View 
    745790    <link rel="stylesheet" type="text/css" media="print" href="/css/paper.css" /> 
    746791 
    749794Abhängig vom gestalterischen Aufbau Ihrer Website haben Sie möglicherweise mehrere Layouts. Klassische Websites haben mindestens zwei: Das Standardlayout und das Pop-up-Layout. 
    750795 
    751 Sie wissen bereits, dass das Standardlayout sich in `meinprojekt/apps/meineapp/templates/layout.php` befindet. Zusätzliche Layouts müssen im gleichen globalen `templates/`-Verzeichnis hinzugefügt werden. Wenn Sie möchten, dass eine View die Datei `meineapp/templates/mein_layout.php` verwendet, benutzen Sie die Syntax aus Codeabschnitt 7-34 in der `view.yml` oder den Code aus Codeabschnitt 7-35 in der Aktion. 
    752  
    753 Codeabschnitt 7-34 - Layoutdefinition in `view.yml` 
    754  
     796Sie wissen bereits, dass das Standardlayout sich in `frontend/apps/meineapp/templates/layout.php` befindet. Zusätzliche Layouts müssen im gleichen globalen `templates/`-Verzeichnis hinzugefügt werden. Wenn Sie möchten, dass eine View die Datei `meineapp/templates/mein_layout.php` verwendet, benutzen Sie die Syntax aus Codeabschnitt 7-34. 
     797 
     798Codeabschnitt 7-34 - Layoutdefinition 
     799 
     800    // In der view.yml 
    755801    indexSuccess: 
    756802      layout: my_layout 
    757803 
    758 Codeabschnitt 7-35 - Layoutdefinition in der Aktion 
    759  
    760     [php] 
    761     <?php 
     804    [php] 
     805    // In der Aktion 
    762806    $this->setLayout('my_layout'); 
    763     ?> 
    764  
    765 Einige Views benötigen überhaupt kein Layout (z.B. Plain-Text-Seiten oder RSS-Feeds). In diesem Fall setzen Sie `has_layout` auf `false` wie in den Codeabschnitten 7-36 und 7-37. 
    766  
    767 Codeabschnitt 7-36 - Layout-Entfernung in `view.yml` 
    768  
     807 
     808    // Im Template 
     809    <?php decorate_with('my_layout') ?> 
     810 
     811Einige Views benötigen überhaupt kein Layout (z.B. Plain-Text-Seiten oder RSS-Feeds). In diesem Fall setzen Sie `has_layout` auf `false`, wie im Codeabschnitt 7-35. 
     812 
     813Codeabschnitt 7-35 - Layout-Entfernung 
     814 
     815    // In der view.yml 
    769816    indexSuccess: 
    770817      has_layout: false 
    771818 
    772 Codeabschnitt 7-37 - Layoutentfernung in der Aktion 
    773     [php] 
    774     <?php 
     819    [php] 
     820    // In der Aktion 
    775821    $this->setLayout(false); 
    776     ?> 
     822 
     823    // Im Template 
     824    <?php decorate_with(false) ?> 
    777825 
    778826>**NOTE** 
    779 >Ajax-Aktions-Views haben standardmässig kein Layout. 
     827>Ajax-Aktions-Views haben standardmäßig kein Layout. 
    780828 
    781829Komponentenslots 
    786834Genau wie Slots sind auch Komponentenslots benannte Platzhalter, die Sie in den View-Elementen definieren können. Der Unterschied besteht darin, wie der ersetzende Code bestimmt wird. Bei einem Slot befindet sich der Code in einem anderen View-Element; bei einem Komponentenslot ist der Code das Ergebnis der Ausführung einer Komponente, und der Name dieser Komponente kommt aus der Viewkonfiguration. Sie werden Komponentenslots besser verstehen, wenn Sie sie erst einmal in Aktion erlebt haben. 
    787835 
    788 Um einen Komponentenslot-Platzhalter zu setzen, verwenden Sie den `include_component_slot()`-Helfer. Diese Funktion erwartet ein Label als Parameter. Nehmen Sie an, die `layout.php` Ihrer Applikation enthält eine kontextabhängige Sidebar. Codeabschnitt 7-38 zeigt, wie der Komponentslot-HElfer eingebunden wird. 
    789  
    790 Codeabschnitt 7-38 - Einen Komponentenslot mit dem Namen `'sidebar'` einbinden 
     836Um einen Komponentenslot-Platzhalter zu setzen, verwenden Sie den `include_component_slot()`-Helfer. Diese Funktion erwartet ein Label als Parameter. Nehmen Sie an, die `layout.php` Ihrer Applikation enthält eine kontextabhängige Sidebar. Codeabschnitt 7-36 zeigt, wie der Komponentslot-Helfer eingebunden wird. 
     837 
     838Codeabschnitt 7-36 - Einen Komponentenslot mit dem Namen `'sidebar'` einbinden 
    791839 
    792840    [php] 
    796844    </div> 
    797845 
    798 Definieren Sie die Verbindung von Komponentenslot-Labe und Komponentenname in der Viewkonfiguration. Setzen Sie die Standardkomponente für den Komponentenslot `'sidebar'` in der Applikations-`view.yml`, unter dem `components`-Header. Der Schlüssel ist das Komponentenslot-Label; der Wert muss ein Array sein, der ein Modul und einen Komponentennamen beinhaltet. Ein Beispiel ist in Codeabschnitt 7-39 zu sehen. 
    799  
    800 Codeabschnitt 7-39 - Den Standard-`'Sidebar'`-Komponentenslot in der `meineapp/config/view.yml` definieren 
     846Definieren Sie die Verbindung von Komponentenslot-Labe und Komponentenname in der Viewkonfiguration. Setzen Sie die Standardkomponente für den Komponentenslot `'sidebar'` in der Applikations-`view.yml`, unter dem `components`-Header. Der Schlüssel ist das Komponentenslot-Label; der Wert muss ein Array sein, der ein Modul und einen Komponentennamen beinhaltet. Ein Beispiel ist in Codeabschnitt 7-37 zu sehen. 
     847 
     848Codeabschnitt 7-37 - Den Standard-`'Sidebar'`-Komponentenslot in der `meineapp/config/view.yml` definieren 
    801849 
    802850    default: 
    806854Wenn das Layout ausgeführt wird, wird der Komponentenslot `'sidebar'` mit dem Ergebnis der `executeDefault()`-Methode der `barComponents`-Klasse innerhalb des `bar`-Moduls gefüllt, und diese Methode wird das `_default.php`-Partial anzeigen, das sich in `modules/bar/templates/` befindet. 
    807855 
    808 Die Konfigurationskaskade ermöglicht Ihnen, diese Einstellung für ein bestimmtes Modul zu überschreiben. In einem Benutzermodul möchten Sie vielleicht, dass in der Sidebar der Benutzername und die Anzahl Artikel stehen, die dieser Benutzer veröffentlicht hat. In diesem Fall können Sie die Sidebar-Slot-Einstellung in der Modul-`view.yml` ändern wie in Codeabschnitt 7-40
    809  
    810 Codeabschnitt 7-40 - Den Komponentenslot `'sidebar'` spezialisieren in `meineapp/modules/user/config/view.yml` 
     856Die Konfigurationskaskade ermöglicht Ihnen, diese Einstellung für ein bestimmtes Modul zu überschreiben. In einem Benutzermodul möchten Sie vielleicht, dass in der Sidebar der Benutzername und die Anzahl Artikel stehen, die dieser Benutzer veröffentlicht hat. In diesem Fall können Sie die Sidebar-Slot-Einstellung in der Modul-`view.yml` ändern wie in Codeabschnitt 7-38
     857 
     858Codeabschnitt 7-38 - Den Komponentenslot `'sidebar'` spezialisieren in `meineapp/modules/user/config/view.yml` 
    811859 
    812860    all: 
    814862        sidebar:  [bar, user] 
    815863 
    816 Die Komponentendefinitionen, die diesen Slot behandeln sollen, sehen so aus wie in Codeabschnitt 7-41. 
    817  
    818 Codeabschnitt 7-41 - Vom Slot `'sidebar'` verwendete Komponenten in `modules/bar/actions/components.class.php` 
    819  
    820     [php] 
    821     <?php 
     864Die Komponentendefinitionen, die diesen Slot behandeln sollen, sehen so aus wie in Codeabschnitt 7-39. 
     865 
     866Codeabschnitt 7-39 - Vom Slot `'sidebar'` verwendete Komponenten in `modules/bar/actions/components.class.php` 
     867 
     868    [php] 
    822869    class barComponents extends sfComponents 
    823870    { 
    825872      { 
    826873      } 
    827      
     874 
    828875      public function executeUser() 
    829876      { 
    830         $current_user = $this->getUser()->getCurrentUser(); 
     877        $this->current_user = $this->getUser()->getCurrentUser(); 
    831878        $c = new Criteria(); 
    832         $c->add(ArticlePeer::AUTHOR_ID, $current_user->getId()); 
     879        $c->add(ArticlePeer::AUTHOR_ID, $this->current_user->getId()); 
    833880        $this->nb_articles = ArticlePeer::doCount($c); 
    834         $this->current_user = $current_user; 
    835881      } 
    836882    } 
    837     ?> 
    838  
    839 Codeabschnitt 7-42 zeigt die Views für diese zwei Komponenten. 
    840  
    841 Codeabschnitt 7-42 - Vom Komponentenslot `'sidebar'` verwendete Partials in `modules/bar/templates/` 
     883 
     884Codeabschnitt 7-40 zeigt die Views für diese zwei Komponenten. 
     885 
     886Codeabschnitt 7-40 - Von den Komponenten des Slots `'sidebar'` verwendete Partials in `modules/bar/templates/` 
    842887 
    843888    [php] 
    851896Komponentenslots können Sie unter anderem einsezten für: Breadcrumb-Navigationen, kontextsensitive Navigationen sowie dynamische Einbindungen aller Art. Sie können im globalen Layout und in Templates verwendet werden, und sogar in anderen Komponenten. Die Konfigurationseinstellung eines Komponentenslots ist immer diejenige der Konfiguration der letzten aufgerufenen Aktion. 
    852897 
    853 Wenn der Komponentenslot für ein bestimmtes Modul leer bleiben soll, definieren Sie ihn einfach als leer, wie in Codeabschnitt 7-43
    854  
    855 Codeabschnitt 7-43 - Einen Komponentenslot in der `view.yml` deaktivieren 
     898Wenn der Komponentenslot für ein bestimmtes Modul leer bleiben soll, definieren Sie ihn einfach als leer, wie in Codeabschnitt 7-41
     899 
     900Codeabschnitt 7-41 - Einen Komponentenslot in der `view.yml` deaktivieren 
    856901 
    857902    all: 
    874919    &lt;script&gt;alert(document.cookie)&lt;/script&gt; 
    875920 
    876 Sie könnten den Output manuell maskieren, indem Sie ihn jedesmal mit `htmlentities()` umschliessen, aber das wäre sehr fehleranfällig. Symfony bietet stattdessen ein spezielles System, genannt Output Escaping, das automatisch jeden dynamischen Output in einem Template maskiert. Es wird durch einen einfachen Parameter in der Applikations-`settings.yml` aktiviert. 
     921Sie könnten den Output manuell maskieren, indem Sie ihn jedesmal mit `htmlentities()` umschließen, aber das wäre sehr fehleranfällig. Symfony bietet stattdessen ein spezielles System, genannt Output Escaping, das automatisch jeden dynamischen Output in einem Template maskiert. Es wird durch einen einfachen Parameter in der Applikations-`settings.yml` aktiviert. 
    877922 
    878923### Output Escaping aktivieren 
    880925Output Escaping wird global für eine Applikation in der `settings.yml` konfiguriert. Zwei Parameter bestimmen, wie Output Escaping arbeitet: Die Strategie bestimmt, wie die Variablen der View zur Verfügung gestellt werden, und die Methode ist die Standard-Maskierfunktion, die auf die Daten angewendet wird. 
    881926 
    882 Die nächsten Abschnitte beschreiben diese Einstellungen detailliert, aber grundsätzlich ist das einzige, was Sie tun müssen, um Output Escaping zu aktivieren, den `escaping_strategy`-Parameter von seinem Standardwert `bc` auf `both` zu ändern wie in Codeabschnitt 7-44
    883  
    884 Codeabschnitt 7-44 - Output Escaping aktivieren in `meineapp/config/settings.yml` 
     927Die nächsten Abschnitte beschreiben diese Einstellungen detailliert, aber grundsätzlich ist das einzige, was Sie tun müssen, um Output Escaping zu aktivieren, den `escaping_strategy`-Parameter von seinem Standardwert `bc` auf `both` zu ändern wie in Codeabschnitt 7-42
     928 
     929Codeabschnitt 7-42 - Output Escaping aktivieren in `frontend/config/settings.yml` 
    885930 
    886931    all: 
    889934        escaping_method:   ESC_ENTITIES 
    890935 
    891 Jetzt wird `htmlentities()` standardmässig auf alle Ausgabevariablen angewandt. Wenn Sie in einer Aktion eine `test`-Variable wie folgt definieren: 
    892  
    893     [php] 
    894     <?php 
     936Jetzt wird `htmlentities()` standardmäßig auf alle Ausgabevariablen angewandt. Wenn Sie in einer Aktion eine `test`-Variable wie folgt definieren: 
     937 
     938    [php] 
    895939    $this->test = '<script>alert(document.cookie)</script>'; 
    896     ?> 
    897940 
    898941Dann wird diese Variable im Template wie folgt ausgegeben: 
    908951    => &gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt; 
    909952 
    910 >**TIP** 
     953>**TIPP** 
    911954>Das `$sf_data`-Objekt verwendet Array-Syntax, Sie können also anstatt `$sf_data->get('meinevariable')` die maskierten Parameter über `$sf_data['meinevariable']` erreichen. Es handelt sich aber eigentlich nicht um ein Array, weshalb Funktionen wie `print_r()` nicht funktionieren werden. 
    912955 
    921964### Escaping-Strategie 
    922965 
    923 Die `escaping_strategy`-Einstellung bestimmt, wie Variablen standardmässig ausgegeben werden. Die folgenden Werte sind möglich: 
    924  
    925   * `bc` (backward compatible, rückwärts-kompatibel): Variablen werden nicht maskiert, aber eine maskierte Version jeder Variablen ist im `$sf_data`-Container verfügbar. Die Daten sind also standardmässig im Rohformat, ausser wenn Sie über das `$sf_data`-Objekt auf die maskierten Daten zugreifen. `bc` ist die Standardeinstellung und Sie sollten sich bewusst sein, dass mit dieser Strategie Ihre Seite anfällig für XSS-Attacken ist. 
    926   * `both`: Alle Variablen werden standardmässig maskiert. Die Werte sind auch im `$sf_data`-Container verfügbar. Das ist die empfohlene Strategie, da Sie nur ein Risiko eingehen, wenn Sie absichtlich die Rohdaten ausgeben. Manchmal werden Sie unmaskierte Daten verwenden müssen – beispielsweise, wenn eine Variable HTML-Code enthält, der gerendert werden soll. Passen Sie also auf: Wenn Sie während der Entwicklung einer Applikation zu dieser Strategie wechseln, funktionieren gewisse Dinge womöglich nicht mehr. Die beste Idee ist es daher, diese Einstellung gleich von Beginn an zu verwenden. 
     966Die `escaping_strategy`-Einstellung bestimmt, wie Variablen standardmäßig ausgegeben werden. Die folgenden Werte sind möglich: 
     967 
     968  * `bc` (backward compatible, rückwärts-kompatibel): Variablen werden nicht maskiert, aber eine maskierte Version jeder Variablen ist im `$sf_data`-Container verfügbar. Die Daten sind also standardmäßig im Rohformat, außer wenn Sie über das `$sf_data`-Objekt auf die maskierten Daten zugreifen. `bc` ist die Standardeinstellung und Sie sollten sich bewusst sein, dass mit dieser Strategie Ihre Seite anfällig für XSS-Attacken ist. 
     969  * `both`: Alle Variablen werden standardmäßig maskiert. Die Werte sind auch im `$sf_data`-Container verfügbar. Das ist die empfohlene Strategie, da Sie nur ein Risiko eingehen, wenn Sie absichtlich die Rohdaten ausgeben. Manchmal werden Sie unmaskierte Daten verwenden müssen – beispielsweise, wenn eine Variable HTML-Code enthält, der gerendert werden soll. Passen Sie also auf: Wenn Sie während der Entwicklung einer Applikation zu dieser Strategie wechseln, funktionieren gewisse Dinge womöglich nicht mehr. Die beste Idee ist es daher, diese Einstellung gleich von Beginn an zu verwenden. 
    927970  * `on`: Werte sind nur im `$sf_data`-Container verfügbar. Das ist der sicherste und schnellste Weg, da Sie bei jedem Ausgeben einer Variablen auswählen müssen, ob Sie die maskierte Version mit `get()` oder die Rohdaten mit `getRaw()` ausgeben. Sie sind sich also jederzeit der Möglichkeit bewusst, dass die Daten korrumpiert sein könnten. 
    928971  * `off`: Schaltet Output Escaping vollständig ab. Der `$sf_data`-Container ist in den Templates nicht verfügbar. Sie können diese Strategie anstelle von `bc` verwenden, um Ihre Applikation zu beschleunigen, wenn Sie sich sicher sind, dass Sie niemals maskierte Daten benötigen. 
    939982### Arrays und Objekte maskieren 
    940983 
    941 Output Escaping funktioniert nicht nur bei Strings, sondern auch bei Arrays und Objekten. Jeder Wert in einem Objekt oder Array wird seinen maskierten Zustand an seine Kinder weitergeben. Nehmen wir an, Ihre Strategie sei `both`. Dann zeigt Codeabschnitt 7-45 die Maskierungskaskade. 
    942  
    943 Codeabschnitt 7-45 - Escaping funktioniert auch bei Arrays und Objekten 
    944  
    945     [php] 
    946     <?php 
     984Output Escaping funktioniert nicht nur bei Strings, sondern auch bei Arrays und Objekten. Jeder Wert in einem Objekt oder Array wird seinen maskierten Zustand an seine Kinder weitergeben. Nehmen wir an, Ihre Strategie sei `both`. Dann zeigt Codeabschnitt 7-43 die Maskierungskaskade. 
     985 
     986Codeabschnitt 7-43 - Escaping funktioniert auch bei Arrays und Objekten 
     987 
     988    [php] 
    947989    // Klassendefinition 
    948990    class meineKlasse 
    953995      } 
    954996    } 
    955      
     997 
    956998    // In der Aktion 
    957999    $this->test_array = array('&', '<', '>'); 
    9581000    $this->test_array_of_arrays = array(array('&')); 
    9591001    $this->test_objekt = new meineKlasse(); 
    960      
     1002 
    9611003    // Im Template 
    9621004    <?php foreach($test_array as $wert): ?> 
    9791021Das erklärt auch, warum einige Standard-PHP-Funktionen (wie `array_shift()`, `print_r()` usw.) bei maskierten Arrays nicht mehr funktionieren. Aber Sie können darauf immer noch mit `[]` zugreifen, sie mit `foreach` traversieren, und die Anzahl mit `count()` zurückgeben (wobei letzteres nur mit PHP 5.2 oder neuer funktioniert). Und in Templates sollten die Daten ohnehin schreibgeschützt sein, die meisten Zugriffe werden also auf Arten geschehen, die funktionieren. 
    9801022 
    981 Sie haben immer noch eine Möglichkeit, über das `$sf_data`-Objekt an die Rohdaten zu gelangen. Zusätzlich werden Methoden von maskierten Objekten so verändert, dass sie einen zusätzlichen Parameter akzeptieren: Eine Maskierungsmethode. Sie können also eine andere Maskierungsmethode wählen jedesmal, wenn Sie eine Variable in einem Template anzeigen, oder Sie können mit dem `ESC_RAW`-Helfer die Maskierung komplett abschalten. Codeabschnitt 7-46 zeigt ein Beispiel. 
    982  
    983 Codeabschnitt 7-46 - Methoden von maskierten Objekten akzeptieren einen zusätzlichen Parameter 
     1023Sie haben immer noch eine Möglichkeit, über das `$sf_data`-Objekt an die Rohdaten zu gelangen. Zusätzlich werden Methoden von maskierten Objekten so verändert, dass sie einen zusätzlichen Parameter akzeptieren: Eine Maskierungsmethode. Sie können also eine andere Maskierungsmethode wählen jedesmal, wenn Sie eine Variable in einem Template anzeigen, oder Sie können mit dem `ESC_RAW`-Helfer die Maskierung komplett abschalten. Codeabschnitt 7-44 zeigt ein Beispiel. 
     1024 
     1025Codeabschnitt 7-44 - Methoden von maskierten Objekten akzeptieren einen zusätzlichen Parameter 
    9841026 
    9851027    [php] 
    9951037 
    9961038>**ACHTUNG** 
    997 >Die üblichen symfony-Variablen werden ebenfalls maskiert, wenn Sie Output Escaping aktivieren. Achten Sie also darauf: `$sf_user`, `$sf_request`, `$sf_param` und `$sf_context` funktionieren immer noch, aber ihre Methoden geben maskierte Daten zurück – es sei denn, Sie geben `ESC_RAW` als letzten Parameter bei den Methodenaufrufen an. 
     1039>Die üblichen Symfony-Variablen werden ebenfalls maskiert, wenn Sie Output Escaping aktivieren. Achten Sie also darauf: `$sf_user`, `$sf_request`, `$sf_param` und `$sf_context` funktionieren immer noch, aber ihre Methoden geben maskierte Daten zurück – es sei denn, Sie geben `ESC_RAW` als letzten Parameter bei den Methodenaufrufen an. 
     1040 
     1041>**TIPP** 
     1042>**Neu in Symfony 1.1**: Auch wenn XSS der häufigste Exploit bei Webseiten ist, ist es bei weitem nicht der einzige. CSRF ist ebenfalls weit verbreitet, und Symfony ermöglicht es Ihnen auf einfache Art, Ihre Anwendung zu schützen. Lesen Sie die Sidebar "Die CSRF-Filter" in Kapitel 6 für weitere Informationen. 
    9981043 
    9991044Zusammenfassung