PageRenderTime 109ms CodeModel.GetById 3ms app.highlight 96ms RepoModel.GetById 1ms app.codeStats 0ms

/gentle-introduction/it/07-Inside-the-View-Layer.markdown

https://gitlab.com/intelij/symfony1-docs
Markdown | 1005 lines | 703 code | 302 blank | 0 comment | 0 complexity | 29713901d2c33667fcbce7fc0c940639 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1Capitolo 7 - All'interno del livello della vista
  2================================================
  3
  4La vista è la responsabile per la visualizzazione dell'output relativo a una particolare azione. In symfony, la vista è costituita da più parti, di cui ogni singolo elemento è stato progettato per essere facilmente modificato da chi di solito lavora con esso.
  5
  6* I web designer in genere lavorano sui template (la presentazione dei dati dell'azione corrente) e sul layout (che contiene il codice comune a tutte le pagine). Questi sono scritti in HTML con l'inclusione di piccoli pezzi in PHP, che sono per lo più chiamate a helper.
  7* Gli sviluppatori, avendo in mente la riusabilità, di solito inseriscono i frammenti di codice in partial o component. Usano gli slot per agire su più di una zona del layout. Anche i web designer possono lavorare su questi frammenti di template.
  8* L'attenzione degli sviluppatori va anche sul file di configurazione view in YAML (impostando le proprietà della risposta e degli altri elementi dell'interfaccia) e sull'oggetto response. Quando si ha a che fare con variabili nei template, i rischi di cross-site scripting non devono essere ignorati e una buona comprensione delle tecniche di escape dell'output è richiesta per trattare in modo sicuro i dati dell'utente.
  9
 10Ma qualunque sia il proprio ruolo, si troveranno utili strumenti per accelerare il noioso lavoro della visualizzazione dei risultati dell'azione. Questo capitolo comprende tutti questi strumenti.
 11
 12
 13I template
 14----------
 15
 16Il listato 7-1 mostra un classico template di symfony. Contiene del codice HTML e un po' di codice PHP semplice, generalmente chiamate a variabili definite nell'azione (attraverso `$this->nome = 'foo';`) ed helper.
 17
 18Listato 7-1 - Un template di esempio indexSuccess.php
 19
 20    [php]
 21    <h1>Benvenuto</h1>
 22    <p>Bentornato, <?php echo $nome ?>!</p>
 23    <h2>Cosa ti piacerebbe fare?</h2>
 24    <ul>
 25      <li><?php echo link_to('Leggere gli ultimi articoli', 'articolo/read') ?></li>
 26      <li><?php echo link_to('Iniziare a scriverne uno nuovo', 'articolo/write') ?></li>
 27    </ul>
 28
 29Come spiegato nel capitolo 4, nei template è preferibile la sintassi alternativa di PHP, in modo da renderli più leggibili anche per chi non è uno sviluppatore di PHP. Nei template si consiglia di utilizzare il minimo indispensabile di codice PHP, poiché questi file sono quelli usati per progettare la grafica dell'applicazione e spesso sono creati e mantenuti da un altro gruppo, specializzato nella presentazione, ma non nella logica dell'applicazione. Mantenere la logica all'interno dell'azione rende anche più facile avere template diversi per una singola azione, senza alcuna duplicazione del codice.
 30
 31### Gli helper
 32
 33Gli helper sono funzioni PHP che restituiscono codice HTML e possono essere utilizzate nei template. Nel listato 7-1, la funzione `link_to()` è un helper. A volte gli helper servono solo per risparmiare tempo, impacchettando frammenti di codice utilizzati frequentemente nei template. Per esempio, si può facilmente immaginare la definizione della funzione di questo helper:
 34
 35    [php]
 36    <?php echo image_tag('photo.jpg') ?>
 37     => <img src="/images/photo.jpg" />
 38
 39Dovrebbe essere simile a quella del listato 7-2.
 40
 41Listato 7-2 - Esempio di definizione di un helper
 42
 43    [php]
 44    function image_tag($source)
 45    {
 46      return '<img src="/images/'.$source.'" />';
 47    }
 48
 49In realtà la funzione `image_tag()` presente in symfony è un po' più complicata d iqeusta, dal momento che accetta un secondo parametro per aggiungere altri attributi al tag `<img>`. Si può vedere la sintassi completa e le opzioni nella [Documentazione con le API](http://www.symfony-project.org/api/1_4/) presente online.
 50
 51Molte volte, gli helper sono intelligenti e fanno risparmiare codice:
 52
 53    [php]
 54    <?php echo auto_link_text('Visitate il nostro sito web www.example.com') ?>
 55     => Visitate il nostro sito web <a href="http://www.example.com">www.example.com</a>
 56
 57Gli helper facilitano il processo di scrittura dei template e generano il miglior codice HTML possibile in quanto a prestazioni e accessibilità. Si può sempre utilizzare il semplice HTML, ma gli helper in genere sono più veloci da scrivere.
 58
 59>**TIP**
 60>Ci si potrebbe chiedere perché gli helper sono nominati utilizzando la convenzione del trattino basso piuttosto che quella camelCase, utilizzata ovunque in symfony. Il motivo è che gli helper sono funzioni e tutte le funzioni native di PHP usano la convenzione del trattino basso.
 61
 62#### Dichiarare gli helper
 63
 64I file di symfony contenenti le dichiarazioni degli helper non sono caricati in automatico (questo perché contengono funzioni, non classi). Gli helper sono raggruppati per scopo. Ad esempio, tutte le funzioni degli helper inerenti i testi sono definite in un file chiamato `TextHelper.php` che contiene il gruppo di helper chiamato `Text`. Se si ha bisogno di usare un helper in un template, bisogna prima caricare il relativo gruppo di helper tramite la funzione `use_helper()`. Il listato 7-3 mostra un template usando l'helper `auto_link_text()` che fa parte del gruppo di helper `Text`.
 65
 66Listato 7-3 - Dichiarare l'utilizzo di un helper
 67
 68    [php]
 69    // Usare uno specifico gruppo di helper in questo template
 70    <?php use_helper('Text') ?>
 71    ...
 72    <h1>Descrizione</h1>
 73    <p><?php echo auto_link_text($description) ?></p>
 74
 75>**TIP**
 76>Quando si ha necessità di dichiarare più di un gruppo di helper, aggiungere più parametri alla chiamata `use_helper()`. Ad esempio, per caricare entrambi i gruppi di helper `Text` e `Javascript` in un template, chiamare `<?php use_helper('Text', 'Javascript') ?>`.
 77
 78Alcuni helper sono disponibili per impostazione predefinita su ogni template, senza la necessità di dichiararli. Sono quelli che appartengono ai seguenti gruppi di helper:
 79
 80  * `Helper`: Richiesto dall'helper di inclusione (infatti la funzione `use_helper()` è a sua volta un helper)
 81  * `Tag`: Helper di base per i tag, usato in quasi tutti gli helper
 82  * `Url`: Helper per i link e la gestione degli URL
 83  * `Asset`: Helper per popolare la sezione HTML `<head>` e fornire facilmente link a risorse esterne (file di immagini, JavaScript e fogli di stile)
 84  * `Partial`: Helper che permettono l'inclusione di frammenti di template
 85  * `Cache`: Manipolazione di frammenti di codice presenti nella cache
 86
 87L'elenco degli helper standard, caricato in modalità predefinita per ogni template, è configurabile nel file `settings.yml`. Quindi, ad esempio se non si dovessero utilizzare gli helper del gruppo `Cache`, o se si dovessero sempre utilizzare quelli del gruppo `Text`, si può modificare di conseguenza l'impostazione `standard_helpers`. Ciò permetterà di accelerare leggermente l'applicazione. Non è possibile rimuovere i primi quattro gruppi di helper della lista precedente (`Helper`, `Tag`, `Url` e `Asset`), perché essi sono obbligatori affiché il motore di template funzioni correttamente. Di conseguenza, essi non compaiono neppure nella lista degli helper standard. 
 88
 89>**TIP**
 90>Se si dovesse utilizzare un helper fuori dal template, è possibile caricare un gruppo di helper da qualsiasi parte chiamando `sfProjectConfiguration::getActive()->loadHelpers($helpers)`, dove `$helpers` è il nome del gruppo di helper o un di nomi di gruppi di helper. Ad esempio, se si vuole usare `auto_link_text()` in una azione, bisogna prima chiamare `sfProjectConfiguration::getActive()->loadHelpers('Text')`.
 91
 92#### Helper utilizzati frequentemente
 93
 94Nei capitoli successivi verranno mostrati in dettaglio alcuni helper, in relazione con le caratteristiche prese in esame. Il listato 7-4 dà un breve elenco degli helper predefiniti che vengono utilizzati di frequente, assieme al codice HTML che restituiscono.
 95
 96Listato 7-4 - Gli helper predefiniti più comuni
 97
 98    [php]
 99    // Gruppo Helper
100    <?php use_helper('NomeHelper') ?>
101    <?php use_helper('NomeHelper1', 'NomeHelper2', 'NomeHelper3') ?>
102
103    // Gruppo Url
104    <?php echo link_to('clicca', 'miomodulo/miaazione') ?>
105    => <a href="/rotta/alla/miaazione">clicca</a>  // Dipende dalla configurazione delle rotte
106
107    // Gruppo Asset
108    <?php echo image_tag('miaimmagine', 'alt=foo size=200x100') ?>
109     => <img src="/images/miaimmagine.png" alt="foo" width="200" height="100"/>
110    <?php echo javascript_include_tag('mioscript') ?>
111     => <script language="JavaScript" type="text/javascript" src="/js/mioscript.js"></script>
112    <?php echo stylesheet_tag('style') ?>
113     => <link href="/stylesheets/style.css" media="screen" rel="stylesheet"type="text/css" />
114
115Ci sono molti altri helper in symfony, ci vorrebbe un libro intero per descriverli tutti. Il migliore riferimento per gli helper è la [documentazione delle API](http:// www.symfony-project.org/api/1_4/) online, dove sono ben documentati tutti gli helper, con la loro sintassi, le opzioni e gli esempi.
116
117#### Aggiungere i propri helper
118
119Symfony ha molti helper per vari diversi utilizzi, ma se non si trova quello di cui si ha bisogno nella documentazione delle API, probabilmente si vorrà crearne uno nuovo. Questo è un compito molto semplice.
120
121Le funzioni per gli helper (normali funzioni PHP che restituiscono codice HTML) devono essere salvate in un file chiamato `FooBarHelper.php`, dove `FooBar` è il nome del gruppo di helper. Salvare il file nella cartella `apps/frontend/lib/helper/` (o in qualunque cartella `helper/`  creata dentro una delle cartelle `lib/` del progetto) in modo che possa essere trovata automaticamente dall'helper per l'inclusione `use_helper('FooBar')`.
122
123>**TIP**
124>Questo sistema permette anche di sovrascrivere gli helper esistenti di symfony. Ad esempio, per ridefinire tutti gli helper del gruppo `Text`, basta creare un file `TextHelper.php` nella cartella `apps/frontend/lib/helper/`. Ogni volta che verrà chiamato `use_helper('Text')`, symfony userà il vostro gruppo di helper al posto del suo. Ma attenzione: poiché il file originale non viene caricato, è necessario ridefinire tutte le funzioni di un gruppo di helper per sovrascriverlo; in caso contrario, alcuni degli helper originali non saranno disponibili.
125
126### Layout della pagina
127
128Il template mostrato nel listato 7-1 non è un documento XHTML valido. Mancano la definizione del `DOCTYPE` e i tag `<html>` e `<body>`. Questo perché vengono memorizzati in un'altra parte dell'applicazione, in un file chiamato `layout.php`, che contiene il layout della pagina. Questo file, chiamato anche template globale, memorizza il codice HTML che è comune a tutte le pagine dell'applicazione per evitare di ripeterlo per ciascun template. Il contenuto del template è integrato nel layout o, cambiando il punto di vista, il layout "decora" il template. Questa è una applicazione del pattern decorator design, mostrata in figura 7-1.
129
130>**TIP**
131>Per maggiori informazioni sul decorator e gli altri design pattern, vedere *Patterns of Enterprise Application Architecture* di Martin Fowler (Addison-Wesley, ISBN: 0-32112-742-0).
132
133Figura 7-1 - Decorare un template con un layout
134
135![Decorare un template con un layout](http://www.symfony-project.org/images/book/1_4/F0701.png "Decorare un template con un layout")
136
137Listato 7-5 mostra la pagina predefinita del layout, presente nella cartella dell'applicazione `templates/`.
138
139Listatog 7-5 - Layout predefinito, in `myproject/apps/frontend/templates/layout.php`
140
141    [php]
142    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
143    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
144      <head>
145        <?php include_javascripts() ?>
146        <?php include_stylesheets() ?>
147        <?php include_http_metas() ?>
148        <?php include_metas() ?>
149        <?php include_title() ?>
150        <link rel="shortcut icon" href="/favicon.ico" />
151      </head>
152      <body>
153        <?php echo $sf_content ?>
154      </body>
155    </html>
156
157Gli helper chiamati nella sezione `<head>` recuperano le informazioni dall'oggetto response e dalla configurazione view. Il tag `<body>` mostra il risultato del template. Con questo layout, la configurazione predefinita e il template di esempio nel listato 7-1 la vista elaborata è simile a quanto si vede nel listato 7-6.
158
159Listato 7-6 - Il Layout, la configurazione View e il template assemblato.
160
161    [php]
162    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
163    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
164      <head>
165        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
166        <meta name="title" content="symfony project" />
167        <meta name="robots" content="index, follow" />
168        <meta name="description" content="symfony project" />
169        <meta name="keywords" content="symfony, project" />
170        <title>symfony project</title>
171        <link rel="stylesheet" type="text/css" href="/css/main.css" />
172        <link rel="shortcut icon" href="/favicon.ico">
173      </head>
174      <body>
175        <h1>Benvenuto</h1>
176        <p>Bentornato, <?php echo $nome ?>!</p>
177        <h2>Cosa vuoi fare?</h2>
178        <ul>
179          <li><?php echo link_to('Leggere gli ultimi articoli', 'articolo/read') ?></li>
180          <li><?php echo link_to('Scriverne uno nuovo', 'articolo/write') ?></li>
181        </ul>
182      </body>
183    </html>
184
185Il template globale può essere completamente personalizzato per ciascuna applicazione. Aggiungerlo in ogni codice HTML in cui se ne ha bisogno. Questo layout spesso è usato per mantenere la navigazione del sito, i logo e altro. Si può anche avere più di un layout e decidere quale layout dovrebbe essere usato per ciascuna azione. Per ora non preoccuparsi delle inclusioni di JavaScript e fogli di stile; La sezione "Configurazione della vista" mostrerà più avanti come ottenere ciò.
186
187### Scorciatoie nei template
188
189Nei template, alcune variabili symfony sono sempre disponibili. Queste scorciatoie forniscono l'accesso alla maggior parte delle informazioni necessarie nei template, attraverso oggetti del nucleo di symfony:
190
191  * `$sf_context`: L'intero oggetto context (`istanza di sfContext`)
192  * `$sf_request`: L'oggetto request(`istanza di sfRequest`)
193  * `$sf_params` : I parametri dell'oggetto request
194  * `$sf_user`   : L'oggetto corrente di sessione utente (`istanza di sfUser`)
195
196Il capitolo precedente ha mostrato utili metodi per gli oggetti `sfRequest` e `sfUser`. Si possono chiamare questi metodi nei template attraverso le variabili `$sf_request` e `$sf_user`. Ad esempio, se la request include un parametro `total`, il suo valore è disponibile nel template tramite:
197
198    [php]
199    // Versione lunga
200    <?php echo $sf_request->getParameter('total') ?>
201
202    // Versione breve
203    <?php echo $sf_params->get('total') ?>
204
205    // Equivalente al seguente codice dell'azione
206    echo $request->getParameter('total')
207
208Frammenti di codice
209-------------------
210
211Spesso c'è la necessità di includere del codice HTML o PHP su più pagine. Per evitare la ripetizione del codice, la maggior parte delle volte è sufficiente il comando `include()`.
212
213Per esempio, se molti template dell'applicazione hanno bisogno di utilizzare lo stesso frammento di codice, salvarlo in un file chiamato `mioFrammento.php` nella cartella globale dei template (`mioprogetto/apps/frontend/templates/`) e includerlo nei template come segue:
214
215    [php]
216    <?php include(sfConfig::get('sf_app_template_dir').'/mioFrammento.php') ?>
217
218Ma questo non è un modo molto pulito per gestire un frammento, soprattutto perché possono esserci nomi di variabili differenti tra il frammento e i vari template che lo includono. Inoltre, il sistema per la cache di symfony (descritto nel capitolo 12) non ha modo di rilevare un include, quindi il frammento non può essere messo in cache indipendentemente dal template. Symfony fornisce tre tipi alternativi di frammenti di codice per sostituire gli `include`:
219
220  * Se la logica è leggera, basterà includere un file template che ha accesso ad alcuni dati che gli vengono passati. Per questo si userà un partial.
221  * Se la logica è più pesante (ad esempio, se è necessario accedere al modello dei dati e/o modificare il contenuto in base alla sessione), è preferibile separare la presentazione dalla logica. Per questo, si userà un component.
222  * Se il frammento ha lo scopo di sostituire una parte specifica del layout, per il quale può già esistere un contenuto predefinito, si userà uno slot.
223	
224L'inserimento di questi frammenti si ottiene con gli helper del gruppo `Partial`. Questi helper sono disponibili da ogni template symfony, senza aver bisogno della dichiarazione iniziale.
225
226### Partial
227
228Un partial è un pezzo di codice del template riutilizzabile. Ad esempio, in una applicazione per pubblicare articoli, il codice del template che mostra un articolo è usato nella pagina con l'articolo completo, nell'elenco dei migliori articoli e nell'elenco degli ultimi articoli. Questo codice è un candidato perfetto per un partial, come mostrato nella figura 7-2.
229
230Figura 7-2 - Il riutilizzo dei partial nei template
231
232![Il riutilizzo dei partial nei template](http://www.symfony-project.org/images/book/1_4/F0702.png "Il riutilizzo dei partial nei template")
233
234Proprio come i template, i partial sono file che si trovano nella cartella `templates/` e contengono codice HTML con del codice PHP. Il nome file di un partial inizia sempre con un carattere di sottolineatura (`_`) e questo aiuta a distinguere i partial dai template, poiché sono situati nelle stesse cartelle `templates/`.
235
236Un template può includere partial se è nello stesso modulo, in un altro modulo, o nella cartella `templates/` globale. Includere un partial usando un helper `include_partial()` e specificare il nome del modulo e del partial come parametro (omettendo la sottolineatura e il `.php` finale), come descritto nel listato 7-7.
237
238Listato 7-7 - Includere un partial in un template del modulo `miomodulo`
239
240    [php]
241    // Include il partial frontend/modules/miomodulo/templates/_miopartial1.php 
242    // Poiché il template e il partial sono nello stesso modulo,
243    // si può omettere il nome del modulo
244    <?php include_partial('miopartial1') ?>
245
246    // Include il partial frontend/modules/pippo/templates/_mypartial2.php
247    // In questo caso il nome del modulo è obbligatorio
248    <?php include_partial('pippo/miopartial2') ?>
249
250    // Include il partial frontend/templates/_mypartial3.php
251    // È considerato parte del modulo 'global'
252    <?php include_partial('global/miopartial3') ?>
253
254I partial hanno accesso ai normali helper di symfony e alle scorciatoie dei template. Ma poiché i partial possono essere chiamati da qualsiasi punto dell'applicazione, non hanno accesso automatico alle variabili definite nelle azioni che chiamano i template stessi, a meno che non siano esplicitamente passate come parametro. Ad esempio, se si vuole che un partial abbia accesso a una variabile `$totale`, l'azione deve passarla ai template e poi il template  all'helper come secondo parametro della chiamata `include_partial()`, come mostrato nei listati 7-8, 7-9 e 7-10.
255
256Listato 7-8 - L'azione definisce una variabile, in `miomodulo/actions/actions.class.php`
257
258    [php]
259    class mymoduleActions extends sfActions
260    {
261      public function executeIndex()
262      {
263        $this->totale = 100;
264      }
265    }
266
267Listato 7-9 - Il template passa la variabile al partial, in `miomodulo/templates/indexSuccess.php`
268
269    [php]
270    <p>Buongiorno, mondo!</p>
271    <?php include_partial('miopartial', array('miototale' => $totale)) ?>
272
273Listato 7-10 - Il partial ora può usare la variabile, in `miomodulo/templates/_miopartial.php`
274
275    [php]
276    <p>Totale: <?php echo $miototale ?></p>
277
278>**TIP**
279>Tutti gli helper fin'ora sono stati chiamati da `<?php echo nomeFunzione() ?>`. L'helper partial, però, è chiamato semplicemente da `<?php include_partial() ?>`, senza `echo`, in modo che abbia un comportamento simile al normale comando PHP `include()`. Se si ha bisogno di una funzione che restituisca il contenuto di un partial senza visualizzarlo, utilizzare `get_partial()`. Tutti gli helper `include_` descritti in questo capitolo hanno una controparte `get_` che può essere chiamata insieme al comando `echo`.
280
281>**TIP**
282>Invece di visualizzare un template, una azione può restituire un partial o un component. I metodi `renderPartial()` e `renderComponent()` della classe dell'azione promuovono la riusabilità del codice. Inoltre sfruttano la possibilità dei partial di essere messi in cache (vedere il capitolo 12). Le variabili definite nell'azione verranno passate automaticamente al partial/component, a meno che non si definisca un array associativo di varibili come secondo paramentro del metodo.
283>
284>     [php]
285>     public function executeFoo()
286>     {
287>       // do things
288>       $this->foo = 1234;
289>       $this->bar = 4567;
290>
291>       return $this->renderPartial('miomodulo/miopartial');
292>     }
293>
294>In questo esempio, il partial avrà accesso a `$foo` e `$bar`. Se l'azione termina con le seguenti righe:
295>
296>       return $this->renderPartial('miomodulo/miopartial', array('foo' => $this->foo));
297>
298>allora il partial ha solo accesso a `$foo`.
299
300### Component
301
302Nel capitolo 2, il primo script di esempio è stato spezzato in due parti per separare la logica dalla presentazione. Proprio come il pattern MVC si applica alle azioni e ai template, può essere necessario dividere un partial in una parte di logica e in una parte di presentazione. In tal caso, è necessario utilizzare un componente. 
303
304Un componente è come una azione, salvo il fatto che è molto più veloce. La logica di un componente è all'interno di una classe che eredita da `sfComponents`, situata in un file `actions/components.class.php`.  La sua presentazione è è messa in un partial. I metodi di una classe `sfComponents` iniziano con la parola `execute`, proprio come le azioni e possono passare variabili ai loro controparti della presentazione nello stesso modo con cui le azioni passano variabili. I partial che vengono utilizzati come presentazione per componenti sono nominati con lo stesso nome del componente (senza l'`execute`, ma con una sottolineatura iniziale). La Tabella 7-1 compara le convenzioni per i nomi per azioni e componenti.
305
306Table 7-1 - Convenzioni per i nomi di azioni e componenti
307
308Convenzione                          |  Azioni                |  Componenti
309------------------------------------ | ---------------------- | ----------------------
310File con la logica                   | `actions.class.php`    | `components.class.php`
311La classe con la logica estende      | `sfActions`            | `sfComponents`
312Nomi per i metodi                    | `executeMiaAzione()`   | `executeMioComponente()`
313Nomi dei file con la presentazione   | `miaAzioneSuccess.php` | `_mioComponente.php`
314
315>**TIP**
316>Così come è possibile separare i file delle azioni, la classe `sfComponents` ha una controparte `sfComponent` che permette ai singoli file dei componenti lo stesso tipo di sintassi. 
317
318Per esempio, supponiamo di avere una barra laterale che mostra le ultime notizie di un dato soggetto, a seconda del profilo dell'utente, che viene riutilizzato in diverse pagine. Le query necessarie a ottenere le notizie sono troppo complesse per apparire in una semplice partial, quindi hanno bisogno di essere spostate in un qualcosa simile a una azione, un componente. La figura 7-3 mostra questo esempio
319
320Per questo esempio, mostrato nei listati 7-11 e 7-12, il componente verrà tenuto nel proprio modulo (chiamato `novita`), ma si possono mischiare componenti e azioni in un singolo modulo se questo ha senso da un punto di vista funzionale.
321
322Figura 7-3 - Usare i componenti nei template
323
324![Usare i componenti nei template](http://www.symfony-project.org/images/book/1_4/F0703.png "Usare i componenti nei template")
325
326Listato 7-11 - La classe Components, in `modules/novita/actions/components.class.php`
327
328    [php]
329    <?php
330
331    class novitaComponents extends sfComponents
332    {
333      public function executeHeadlines()
334      {
335        // Propel
336        $c = new Criteria();
337        $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
338        $c->setLimit(5);
339        $this->novita = NewsPeer::doSelect($c);
340
341        // Doctrine
342        $query = Doctrine::getTable('Novita')
343                  ->createQuery()
344                  ->orderBy('pubblicato_il DESC')
345                  ->limit(5);
346
347        $this->novita = $query->execute();
348      }
349    }
350
351Listato 7-12 - Il partial, in `modules/novita/templates/_headlines.php`
352
353    [php]
354    <div>
355      <h1>Latest news</h1>
356      <ul>
357      <?php foreach($news as $headline): ?>
358        <li>
359          <?php echo $headline->getPublishedAt() ?>
360          <?php echo link_to($headline->getTitle(),'news/show?id='.$headline->getId()) ?>
361        </li>
362      <?php endforeach ?>
363      </ul>
364    </div>
365
366Ora ogni volta che si avrà bisogno del componente in un template, basterà chiamare:
367
368    [php]
369    <?php include_component('novita', 'headlines') ?>
370
371Come i partial, i componenti accettano parametri aggiuntivi nella forma di un array associativo. I parametri sono disponibili al partial con il loro nome e nel componente attraverso l'oggetto `$this`. Per un esempio, vedere il listato 7-13.
372
373Listato 7-13 - Passare i parametri a un componente e ai suoi template
374
375    [php]
376    // Chiamare il componente
377    <?php include_component('novita', 'headlines', array('foo' => 'bar')) ?>
378
379    // Nel componente stesso
380    echo $this->foo;
381     => 'bar'
382
383    // Nel partial _headlines.php
384    echo $foo;
385     => 'bar'
386
387Si possono includere componenti in componenti, o nel layout globale, così come in ogni normale template. Come nelle azioni, i metodi `execute` dei componenti possono passare variabili ai relativi partial e avere accesso alle stesse scorciatoie. Ma le similitudini si fermano qui. Un componente non gestisce la sicurezza o la validazione, non può essere chiamato da Internet (solo dall'applicazione stessa) e non ha le varie possibilità di return. Questo è il motivo per cui un componente nell'esecuzione è più veloce di un'azione. 
388
389### Gli slot
390
391I partial e i componenti sono ottimi per la riusabilità. Ma in molti casi i frammenti di codice devono andare a comporre un layout con più di una zona dinamica. Ad esempio, supponiamo che si desideri aggiungere alcuni tag personalizzati nella sezione `<head>` del layout, in base al contenuto di una azione. Oppure supponiamo che il layout abbia una zona dinamica principale, composta dal risultato di una azione, più numerose altre azioni più piccole, con un contenuto che è predefinito nel layout, ma che può essere sovrascritto a livello di template.
392
393Per queste situazioni, la soluzione è uno slot. In sostanza, uno slot è un segnaposto che si può mettere in qualsiasi degli elementi della vista (layout, template o partial). Riempire questo segnaposto è come impostare una variabile. Il codice di riempimento è memorizzato nella risposta a livello globale, in modo da poterlo definire ovunque (nel layout, template o partial). Basta fare in modo di definire uno slot prima di includerlo e ricordare che il layout viene eseguito dopo il template (processo di decorazione) e che i partial vengono eseguiti quando sono chiamati in un template. Il tutto sembra un po' troppo astratto? Vediamo un esempio.
394
395Immaginiamo un layout con una zona per il template e due slot: uno per la barra laterale e l'altro per il piè di pagina. I valori per lo slot sono definiti nel template. Durante il processo di decorazione, il codice del layout avvolge il codice del template e gli slot sono riempiti con i valori definiti precedentemente, così come illustrato in figura 7-4. La barra laterale e il piè di pagina possono essere contestuali all'azione principale. È come avere un layout con più di un "buco".
396
397Figura 7-4 - Slot layout definiti in un template
398
399![Slot layout definiti in un template](http://www.symfony-project.org/images/book/1_4/F0704.png "Slot layout definiti in un template")
400
401Vedere un po' di codice chiarirà ulteriormente le cose. Per includere uno slot, usare l'helper `include_slot()`. L'helper `has_slot()` restituisce `true` se lo slot è stato definito in precedenza, fornendo come bonus un meccanismo di fallback. Ad esempio, definire un segnaposto per uno slot `'sidebar'` nel layout e i suoi contenuti predefiniti, come mostrato nel listato 7-14.
402
403Listato 7-14 - Inclusione di uno slot `'sidebar'` nel layout
404
405    [php]
406    <div id="sidebar">
407    <?php if (has_slot('sidebar')): ?>
408      <?php include_slot('sidebar') ?>
409    <?php else: ?>
410      <!-- codice predefinito della barra laterale -->
411      <h1>Zona contestuale</h1>
412      <p>Questa zona contiene link e informazioni
413      relative al contenuto principale della pagina.</p>
414    <?php endif; ?>
415    </div>
416
417Capita abbastanza frequentemente di dover mostrare dei contenuti predefiniti se uno slot non è definito e per questo scopo l'helper `include_slot` restituisce un valore booleano, che indica se lo slot è stato definito. Il listato 7-15 mostra come utilizzare questo valore in modo da semplificare il codice.
418
419Listato 7-15 - Inclusione di uno slot `'sidebar'` nel layout
420
421    [php]
422    <div id="sidebar">
423    <?php if (!include_slot('sidebar')): ?>
424      <!-- codice predefinito della barra laterale -->
425      <h1>Zona contestuale</h1>
426      <p>Questa zona contiene link e informazioni
427      relative al contenuto principale della pagina.</p>
428    <?php endif; ?>
429    </div>
430
431Ciascun template ha la possibilità di definire i contenuti di uno slot (in realtà anche i partial sono in grado di farlo). Essendo gli slot destinati a contenere codice HTML, symfony offre un modo conveniente per definirli: basta scrivere il codice dello slot tra gli helper `slot()` e `end_slot()`, come mostrato nel listato 7-16.
432
433Listato 7-16 - Sovrascrivere il contenuto dello slot `'sidebar'` in un template
434
435    [php]
436    // ...
437
438    <?php slot('sidebar') ?>
439      <!-- codice per la barra laterale personalizzata per il template corrente -->
440      <h1>Dettagli dell'utente</h1>
441      <p>nome:  <?php echo $user->getNome() ?></p>
442      <p>email: <?php echo $user->getEmail() ?></p>
443    <?php end_slot() ?>
444
445Il codice tra gli helper degli slot è eseguito nel contesto del template, quindi ha accesso a tutte le variabili che sono state definite nell'azione. Symfony metterà automaticamente il risultato dell'esecuzione del codice nell'oggetto response. Non verrà visualizzato nel template, ma reso disponibile per future chiamate `include_slot()`, come quella mostrata nel listato 7-14.
446
447Gli slot sono molto utili per definire zone che devono mostrare dei contenuti contestuali. Possono anche essere usati per aggiungere codice HTML al layout solo per certe azioni. Ad esempio, un template che mostra l'elenco delle ultime news potrebbe volere aggiungere un link a un feed RSS nella zona `<head>` del layout. Lo si può fare semplicemente aggiungendo uno slot 'feed'` nel layout e sovrascrivendolo nel template dell'elenco.
448
449Se il contenuto dello slot è breve, per esempio come nel caso di uno slot `titolo`, si può semplicemente passare il contenuto come secondo parametro del metodo `slot()`, come mostrato nel listato 7-17.
450
451Listato 7-17 - Usare lo `slot()` per definire un contenuto breve
452
453    [php]
454    <?php slot('titolo', 'Il contenuto del titolo') ?>
455
456>**SIDEBAR**
457>Dove cercare i frammenti dei template
458>
459>Chi lavora sui template è in genere un web designer, che potrebbe non conoscere symfony molto bene e avere difficoltà a trovare i frammenti dei template, dal momento che possono essere sparsi in tutta l'applicazione. Queste brevi linee guida renderanno più comodo il dover lavorare con il sistema dei template di symfony.
460>
461>Prima di tutto, anche se un progetto symfony contiene molte cartelle, tutti i file dei layout, dei template e dei frammenti di template risiedono in cartelle chiamate `templates/`. Quindi, per quello che può interessare a un web designer, la struttura di un progetto può essere ridotta a qualcosa di questo tipo:
462>
463>
464>     mioprogetto/
465>       apps/
466>         applicazione1/
467>           templates/       # Layout per l'applicazione 1
468>           modules/
469>             modulo1/
470>               templates/   # Template e partial per il modulo 1
471>             modulo2/
472>               templates/   # Template e partial per il modulo 2
473>             modulo3/
474>               templates/   # Template e partial per il modulo 3
475>
476>
477>Tutte le altre cartelle possono essere ignorate.
478>
479>Quando si trova un `include_partial()`, i web designer devono sapere che solo il primo parametro è importante. Lo schema di questo parametro è `nome_modulo/nome_partial` e ciò significa che il codice di presentazione si trova in `modules/nome_modulo/templates/_nome_partial.php`.
480>
481>Per l'helper `include_component()`, il nome del modulo e il nome del partial sono i primi due parametri. Per il resto, un'idea generale su cosa sono gli helper e su quali helper sono più utili nei template dovrebbe essere sufficiente per iniziare a progettare template per le applicazioni symfony.
482
483Configurazione della vista
484--------------------------
485
486In symfony, una vista consiste di due parti distinte:
487
488  * La presentazione HTML del risultato dell'azione (memorizzata nel template, nel layout e nei frammenti di template)
489  * Tutto il resto, comprese le seguenti cose:
490
491    * Meta dichiarazioni: keywords, description o durata della cache.
492    * Tag `title` della pagina: non solo aiuta gli utenti con numerose finestre aperte del browser a trovare quella giusta, ma è anche molto importante per l'indicizzazione nei motori di ricerca.
493    * Inclusione di file: JavaScript e fogli di stile.
494    * Layout: alcune azioni richiedono un layout personalizzato (popup, banner, ecc.) oppure anche nessun layout (ad esempio le azioni Ajax).
495
496Nella vista, tutto quello che non è HTML è chiamato configurazione della vista e symfony fornisce due modi per gestirla. Il modo principale è attraverso il file di configurazione `view.yml`. Può essere utilizzato ogni volta che i valori non dipendono dal contesto o per le query del database. Quando è necessario impostare valori dinamici, il metodo alternativo è quello di impostare la configurazione della vista attraverso gli attributi dell'oggetto `sfResponse`, direttamente nell'azione.
497
498>**NOTE**
499>Se si imposta un certo parametro della configurazione della vista sia attraverso l'oggetto `sfResponse` che attraverso il file `view.yml`, la definizione di `sfResponse` ha la precedenza.
500
501### Il file `view.yml`
502
503Ogni modulo può avere un file `view.yml`, per definire la configurazione delle sue viste. Questo permette di definire le impostazioni di visualizzazione per un intero modulo e vista per vista in un singolo file. Le chiavi di primo livello del file `view.yml` sono i nomi dei moduli della vista. Il listato 7-18 mostra un esempio della configurazione della vista
504
505Listato 7-18 - Esempio Livello-Modulo `view.yml`
506
507    editSuccess:
508      metas:
509        title: Modifica il tuo profilo
510
511    editError:
512      metas:
513        title: Errore nella modifica del profilo
514
515    all:
516      stylesheets: [mio_style]
517      metas:
518        title: Il mio sito web
519
520>**CAUTION**
521>Bisogna tenere presente che le chiavi principali del file `view.yml` sono nomi di viste, non nomi di azioni. Inoltre bisogna ricordarsi che il nome di una vista è composta dal nome di una azione e dalla terminazione dell'azione. Ad esempio, se l'azione `edit` restituisce `sfView::SUCCESS` (o non restituisce nulla, dal momento che è la terminazione predefinita in una azione), allora il nome della vista è `editSuccess`.
522
523Le impostazioni predefinite per il modulo sono definite sotto la chiave `all:` nel modulo `view.yml`. Le impostazioni predefinite per tutte le viste dell'applicazione sono definite in `view.yml`. Anche qua vale il principio della configurazione a cascata:
524
525  * In `apps/frontend/modules/miomodulo/config/view.yml`, le definizioni per vista si applicano solo a una vista e sovrascrivono le definizioni a livello di modulo.
526  * In `apps/frontend/modules/miomodulo/config/view.yml`, le definizioni `all:` si applicano a tutte le azioni del modulo e sovrascrivono le definizioni a livello di applicazione.
527  * In `apps/frontend/config/view.yml`, le definizioni `default:` si applicano a tutti i moduli e a tutte le azioni dell'applicazione.
528
529>**TIP**
530>I file `view.yml` a livello di modulo non esistono nella modalità predefinita. La prima volta che si ha necessità di modificare un parametro della configurazione della vista per un modulo, bisogna creare un file `view.yml` vuoto nella cartella `config/` del modulo stesso.
531
532Dopo aver visto il template predefinito nel listato 7-5 e un esempio di una response finale nel listato 7-6, ci si potrebbe chiedere da dove provengono i valori dell'header. La risposta è che sono le impostazioni predefinite per la vista, definite nel file `view.yml` dell'applicazione e mostrate nel listato 7-19.
533
534Listato 7-19 - Configurazione predefinita della vista a livello di applicazione, in `apps/frontend/config/view.yml`
535
536    default:
537      http_metas:
538        content-type: text/html
539
540      metas:
541        #title:        symfony project
542        #description:  symfony project
543        #keywords:     symfony, project
544        #language:     en
545        #robots:       index, follow
546
547      stylesheets:    [main]
548
549      javascripts:    []
550
551      has_layout:     true
552      layout:         layout
553
554Ciascuna di queste impostazioni verrà descritta in dettaglio nella sezione "Impostazione della configurazione della vista".
555
556### L'oggetto response
557
558Sebbene faccia parte del livello vista, l'oggetto response viene spesso modificato dall'azione. Le azioni possono accedere all'oggetto response di symfony, chiamato `sfResponse`, attraverso il metodo `getResponse()`. Il listato 7-20 elenca alcuni dei metodi di `sfResponse` spesso utilizzati all'interno di un'azione.
559
560Listato 7-20 - Le azioni hanno accesso ai metodi dell'oggetto `sfResponse`
561
562    [php]
563    class miomoduloActions extends sfActions
564    {
565      public function executeIndex()
566      {
567        $response = $this->getResponse();
568
569        // Header HTTP
570        $response->setContentType('text/xml');
571        $response->setHttpHeader('Content-Language', 'en');
572        $response->setStatusCode(403);
573        $response->addVaryHttpHeader('Accept-Language');
574        $response->addCacheControlHttpHeader('no-cache');
575
576        // Cookie
577        $response->setCookie($name, $content, $expire, $path, $domain);
578
579        // Meta e header della pagina
580        $response->addMeta('robots', 'NONE');
581        $response->addMeta('keywords', 'foo bar');
582        $response->setTitle('La mia pagina FooBar');
583        $response->addStyleSheet('custom_style');
584        $response->addJavaScript('custom_behavior');
585      }
586    }
587
588Oltre ai metodi setter che sono stati mostrati, la classe `sfResponse` ha getter che restituiscono il valore corrente degli attributi della response.
589
590I setter dell'header sono molto potenti in symfony. Gli header sono inviati il più tardi possibile (in `sfRenderingFilter`), in modo che possano venire modificati come si vuole. Forniscono anche utili scorciatoie. Ad esempio, se non si specifica un charset quando si chiama `setContentType()`, symfony aggiunge automaticamente il charset predefinito, definito nel file `settings.yml`.
591
592    [php]
593    $response->setContentType('text/xml');
594    echo $response->getContentType();
595     => 'text/xml; charset=utf-8'
596
597Il codice di stato delle risposte di symfony è compatibile con la specifica HTTP. Le eccezioni restituiscono uno stato 500, le pagine non trovate restituiscono 404, le pagine normali restituiscono uno stato 200, le pagine non modificate possono essere ridotte a un semplice header con il codice di stato 304 (vedere il capitolo 12 per maggiori dettagli) e così via. Ma è possibile sovrascrivere questi valori predefiniti impostando il proprio codice di stato nell'azione con il metodo response `setStatusCode()`.  È possibile specificare un codice personalizzato e un messaggio personalizzato, o semplicemente un codice personalizzato, nel qual caso, symfony aggiunge un messaggio generico per questo codice.
598
599    [php]
600    $response->setStatusCode(404, 'Questa pagina non esiste');
601
602>**TIP**
603>Prima di inviare gli header, symfony normalizza i loro nomi. Quindi non è il caso di preoccuparsi se si scrive `content-language` invece di `Content-Language` in una chiamata a `setHttpHeader()`, perché symfony coomprenderà il primo e l otrasformerà automaticamente nel secondo.
604
605### Impostare la configurazione per la vista
606
607Si sarà notato che ci sono due tipi di impostazioni per la configurazione della vista:
608
609  * Quella che ha un unico valore (il valore è una stringa nel file `view.yml` e la response usa un metodo `set` per qeusta)
610  * Quella con valori multipli (per le quali `view.yml` usa array e la response usa un metodo `add`)
611
612Ricordarsi che la configurazione a cascata cancella l'impostazione del valore unico ma mantiene le impostazioni con valori multipli. Questo diventerà più evidente proseguendo la lettura del capitolo.
613
614#### Configurare i meta tag
615
616Le informazioni scritte nei tag `<meta>` nella response non sono visualizzate nel browser ma sono utili per i robot e i motori di ricerca. Gestiscono anche le impostazioni della cache di tutte le pagine. Definire questi tag sotto le chiavi `http_metas:` e `metas:`, come mostrato nel listato 7-21, o con i metodi di response `addHttpMeta()` e `addMeta()` nell'azione, come mostrato nel listato 7-22.
617
618Listato 7-21 - Definizione meta come chiave: coppie di valori in `view.yml`
619
620    http_metas:
621      cache-control: public
622
623    metas:
624      description:   Finanza in Italia
625      keywords:      finanza, Italia
626
627Listato 7-22 - Definizione meta come impostazioni della Response nell'azione
628
629    [php]
630    $this->getResponse()->addHttpMeta('cache-control', 'public');
631    $this->getResponse()->addMeta('description', 'Finanza in Italia');
632    $this->getResponse()->addMeta('keywords', 'finanza, Italia');
633
634L'aggiunta di una chiave esistente sostituirà il contenuto corrente predefinito. Per i meta tag HTTP, si può aggiungere un terzo parametro e impostarlo a `false` per fare si che il metodo `addHttpMeta()` (oltre a `setHttpHeader()`) aggiunga il valore a quello esistente, invece che sostituirlo.
635
636    [php]
637    $this->getResponse()->addHttpMeta('accept-language', 'en');
638    $this->getResponse()->addHttpMeta('accept-language', 'fr', false);
639    echo $this->getResponse()->getHttpHeader('accept-language');
640     => 'en, fr'
641
642Al fine di far si che questi meta tag compaiano nella pagina finale, gli helper `include_http_metas()` e `include_metas()` devono essere chiamati nella sezione `<head>` (questo è il caso del layout predefinito; vedere il listato 7-5). Symfony aggrega automaticamente le impostazioni di tutti i file `view.yml` (compreso quello predefinito mostrato nel listato 7-18) e dell'attributo response per visualizzare i corretti `<meta>` tag. L'esempio del listato 7-21 finisce come mostrato nel listato 7-23.
643
644Listato 7-23 - Visualizzazione dei meta tag nella pagina finale
645
646    [php]
647    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
648    <meta http-equiv="cache-control" content="public" />
649    <meta name="robots" content="index, follow" />
650    <meta name="description" content="Finanza in Italia" />
651    <meta name="keywords" content="finanza, Italia" />
652
653Come bonus, l'header HTTP della response è anche gestito dall'impostazione `http-metas:` anche se non si hanno helper `include_http_metas()` nel layout, o se non esiste alcun layout. Ad esempio, se bisogna inviare una pagina come testo normale, definire il seguente `view.yml`:
654
655    http_metas:
656      content-type: text/plain
657
658    has_layout: false
659
660#### Configurazione del title
661
662Il titolo della pagina è una parte chiave per l'indicizzazione dei motori di ricerca. È anche molto utile con i moderni browser che forniscono la navigazione con i tab. In HTML, il titolo è sia un tag che una informazione meta della pagina, quindi il file `view.yml` vede la chiave `title:` come un figlio della chiave `metas:`. Il listato 7-24 mostra la definizione di title in `view.yml` e il listato 7-25 mostra la definizione nell'azione.
663
664Listato 7-24 - La definizione di title in `view.yml`
665
666    indexSuccess:
667      metas:
668        title: I tre porcellini
669
670Listato 7-25 - La definizione di title nell'azione (permette la creazione titoli dinamici)
671
672    [php]
673    $this->getResponse()->setTitle(sprintf('%d porcellini', $number));
674
675Nella sezione `<head>` della pagina finale, la definizione del title imposta il tag `<meta name="title">` se l'helper `include_metas()` è presente e il tag `<title>` se l'helper `include_title()` è presente. Se sono presenti entrambi (come nel layout predefinito del listato 7-5), il titolo compare due volte nel sorgente della pagina (vedere il listato 7-6), ma questo non crea nessun problema.
676
677>**TIP**
678>Un altro modo per gestire la definizione del title è usare gli slot, come discusso sopra. Questo metodo permette di mantenere una migliore separazione tra i controllori e i template : il titolo appartiene alla vista, non al controllore.
679
680#### Configurazione dell'inclusione dei file
681
682Aggiungere un certo foglio di stile o un file JavaScript alla vista è semplice, come mostrato nel listato 7-26.
683
684Listato 7-26 - Inclusione dei file
685
686    [yml]
687    // In view.yml
688    indexSuccess:
689      stylesheets: [mystyle1, mystyle2]
690      javascripts: [myscript]
691      
692-
693
694    [php]
695    // In una azione
696    $this->getResponse()->addStylesheet('miostile1');
697    $this->getResponse()->addStylesheet('miostile2');
698    $this->getResponse()->addJavascript('mioscript');
699
700    // In un template
701    <?php use_stylesheet('miostile1') ?>
702    <?php use_stylesheet('miostile2') ?>
703    <?php use_javascript('mioscript') ?>
704
705In ogni caso, il parametro è un nome di un file. Se il file ha una estensione logica ((`.css` per un foglio di stile e `.js` per un file JavaScript), si può ometterla. Se il file ha una collocazione logica (`/css/` per un foglio di stile e `/js/` per un file JavaScript), si può omettere anche quella. Symfony è abbastanza intelligente da aggiungere la corretta estensione o locazione.
706
707Come le definizioni di meta e title, le definizioni per includere i file richiedono l'utilizzo degli helper `include_javascripts()` e `include_stylesheets()` nel template o nel layout dove devono essere inclusi. Questo significa che le precedenti impostazioni visualizzeranno il codice HTML del listato 7-27.
708
709Listato 7-27 - Risultato dell'inclusione dei file
710
711    [php]
712    <head>
713    ...
714    <link rel="stylesheet" type="text/css" media="screen" href="/css/miostile1.css" />
715    <link rel="stylesheet" type="text/css" media="screen" href="/css/miostile2.css" />
716    <script language="javascript" type="text/javascript" src="/js/mioscript.js">
717    </script>
718    </head>
719
720Ricordarsi che vengono applicati i principi di configurazione a cascata, quindi qualunque inclusione di file definita nel `view.yml` dell'applicazione verrà applicata in ogni pagina dell'applicazione. I listati 7-28, 7-29 e 7-30 mostrano questo principio.
721
722Listato 7-28 - Esempio di `view.yml` nell'applicazione
723
724    default:
725      stylesheets: [main]
726
727Listato 7-29 - Sample Module `view.yml`
728
729    indexSuccess:
730      stylesheets: [special]
731
732    all:
733      stylesheets: [additional]
734
735Listato 7-30 - Visualizzazione della vista `indexSuccess`
736
737    [php]
738    <link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />
739    <link rel="stylesheet" type="text/css" media="screen" href="/css/additional.css" />
740    <link rel="stylesheet" type="text/css" media="screen" href="/css/special.css" />
741
742Quando si ha bisogno di rimuovere un file definito a un livello più alto, basta aggiungere un segno meno (`-`) davanti al nome del file nella definizione di livello inferiore, come mostrato nel listato 7-31.
743
744Listato 7-31 - Esempio con `view.yml` nel modulo. Viene rimossa un file definito nel livello applicazione
745
746    indexSuccess:
747      stylesheets: [-main, special]
748
749    all:
750      stylesheets: [additional]
751
752Per rimuovere tutti i fogli di stile o i file JavaScript ,usare `-*` come nome del file, come mostrato nel listato 7-32.
753
754Listato 7-32 - Esempio con `view.yml` nel modulo. Vengono rimossi tutti i file definiti nel livello applicazione
755
756    indexSuccess:
757      stylesheets: [-*]
758      javascripts: [-*]
759
760Si può lavorare con maggiore precisione e definire un parametro ulteriore per forzare  la posizione in cui includere il file (prima o ultima posizione), come mostrato nel listato 7-33. Questo funziona sia per i fogli di stile che per i JavaScript.
761
762Listato 7-33 - Definire la posizione di un file incluso
763
764    [yml]
765    // In view.yml
766    indexSuccess:
767      stylesheets: [special: { position: first }]
768
769-
770    
771    [php]
772    // In una azione
773    $this->getResponse()->addStylesheet('special', 'first');
774    
775    // In un template
776    <?php use_stylesheet('special', 'first') ?>
777
778Si può anche decidere di ignorare la trasformazione dei nomi dei file, in modo che i risultanti tag `<link>` o `<script>` vengano riferiti alla esatta locazione specificata, come mostrato nel listato 7-34.
779
780Listato 7-34 - Inclusione di un foglio di stile con Style Sheet con nome inalterato
781
782    [yml]
783    // In view.yml
784    indexSuccess:
785      stylesheets: [main, paper: { raw_name: true }]
786
787-
788    
789    [php]
790    // In una azione
791    $this->getResponse()->addStylesheet('main', '', array('raw_name' => true));
792    
793    // In un template
794    <?php use_stylesheet('main', '', array('raw_name' => true)) ?>
795    
796    // La vista risultante
797    <link rel="stylesheet" type="text/css" href="main" />
798
799Per specificare il media relativo a una inclusione di un f…

Large files files are truncated, but you can click here to view the full file