Development

Documentation/it_IT/book/1.0/04-The-Basics-of-Page-Creation

You must first sign up to be able to contribute.

Version 3 (modified by gscaglia, 10 years ago)
--

Capitolo 4 - Le basi per la creazione di pagine ===============================================

Curiosamente, il primo tutorial che i programmatori seguono per imparare un nuovo linguaggio o framework, è quello che visualizza sullo schermo "Ciao, mondo". E' strano pensare ad un computer come a qualcosa che possa salutare il mondo intero, in quanto ogni tentativo nel campo dell'intelligenza artificiale è finora sfociato solo in povere capacità di conversazione. Ma symfony non è più stupido di qualsiasi altro programma, e ne è la prova il fatto che puoi creare una pagina con scritto "Ciao, <il tuo nome>".

Questo capitolo ti insegnerà a creare un modulo, che è l'elemento strutturale che raggruppa le pagine. Imparerai anche come creare una pagina, che grazie al pattern MVC è diviso in azione e template. I link e le form sono le interazioni base del web; vedrai come inserirle in una template e gestirle in un'azione.

Creare lo scheletro di un modulo


Come spiegato nel Capitolo 2, symfony divide le pagine in moduli. Prima di creare una pagina, occorre creare un modulo, che inizialmente è una shell vuota con una struttura di file riconoscibile da symfony.

La linea di comando di symfony automatizza la creazione di moduli. Hai solo bisogno di chiamare il comando init-module con il nome dell'applicazione ed il nome del modulo come argomenti. Nel capitolo precedente, hai creato l'applicazione myapp. Per poter aggiungere il modulo mymodule, scrivi i seguenti comandi:

> cd ~/myproject > symfony init-module myapp mymodule

>> dir+ ~/myproject/apps/myapp/modules/mymodule >> dir+ ~/myproject/apps/myapp/modules/mymodule/actions >> file+ ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php >> dir+ ~/myproject/apps/myapp/modules/mymodule/config >> dir+ ~/myproject/apps/myapp/modules/mymodule/lib >> dir+ ~/myproject/apps/myapp/modules/mymodule/templates >> file+ ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php >> dir+ ~/myproject/apps/myapp/modules/mymodule/validate >> file+ ~/myproject/test/functional/myapp/mymoduleActionsTest.php >> tokens ~/myproject/test/functional/myapp/mymoduleActionsTest.php >> tokens ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php >> tokens ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

A parte le cartelle actions/, config/, lib/, templates/, e validate/, questo comando crea solo tre file. Quello nella cartella test/ riguarda le unità di test, e non hai bisogno di preoccupartene fino al Capitolo 15. Il file actions.class.php (mostrato nel Listato 4-1) redirige al modulo di congratulazioni di default. Il file templates/indexSuccess.php è vuoto.

Listato 4-1 - Azione di default generata automaticamente, in actions/actions.class.php

[php] <?php

class mymoduleActions extends sfActions {

public function executeIndex() {

$this->forward('default', 'module');

}

}

**NOTE** Se dai un'occhiata ad un effettivo actions.class.php, troverai molte più di queste poche linee, inclusi molti commenti. Questo perchè symfony raccomanda di utilizzare commenti PHP per la documentazione del tuo progetto, e di preparare ogni classe per essere compatibile con phpDocumentor (http://www.phpdoc.org/(http://www.phpdoc.org/)).

Per ogni modulo, symfony crea un'azione index di default. Essa è composta da un metodo chiamato executeIndex e da una template chiamata indexSuccess.php. Il significato del prefisso execute e del suffisso Success verrà spiegato rispettivamente nei Capitoli 6 e 7. Per il momento puoi considerare come una convenzione questo modo di chiamare metodi e file. Puoi vedere la pagina corrispondente (mostrata in Figura 4-1) navigando al seguente indirizzo:

http://localhost/myapp_dev.php/mymodule/index

L'azione di default index non sarà utilizzata in questo capitolo, per cui puoi rimuovere il metodo executeIndex() dalla classe actions.class.php, e cancellare il file indexSuccess.php dalla cartella templates/.

**NOTE** Symfony offre altri metodi oltre alla linea di comando per inizializzare un modulo. Uno di questi è creare a mano file e cartelle. In molti casi, le azioni e le template di un modulo servono a gestire i dati di una data tabella. Dato che il codice per creare, selezionare, aggiornare e cancellare record da una tabella spesso è lo stesso, symfony fornisce un meccanismo chiamato scaffolding per generare questo codice automaticamente. Controlla il Capitolo 14 per maggiori informazioni su questa tecnica.

Figura 4-1 - Pagina di default generata automaticamente

![Pagina di default generata automaticamente](/images/book/F0401.jpg "Pagina di default generata automaticamente")

Aggiungere una pagina


In symfony, la logica di una pagina è memorizzata nelle azioni, mentre la presentazione in template. Le pagine senza una logica avranno bisogno comunque di un'azione vuota.

### Aggiungere un'azione

La pagina "Ciao, mondo!" sarà accessibile tramite l'azione myAction. Per crearla, inserisci semplicemente un metodo chiamato executeMyAction alla classe mymoduleActions, come mostrato nel Listato 4-2.

Listato 4-2 - Aggiungere un'azione significa aggiungere un metodo execute alla classe

[php] <?php

class mymoduleActions extends sfActions {

public function executeMyAction() { }

}

Il nome del metodo da aggiungere è sempre executeXxx(), dove Xxx è il nome dell'azione con la prima lettera maiuscola.

Ora, se navighi all'indirizzo:

http://localhost/myapp_dev.php/mymodule/myAction

symfony si arrabbierà dicendoti che manca la template myActionSuccess.php. Questo è normale; in symfony una pagina è sempre composta da un'azione e da una template.

**CAUTION** Le URL (non i nomi a dominio) sono case-sensitive, è così è symfony (anche se i nomi dei metodi non lo sono, in PHP). Questo significa che se aggiungi un metodo chiamato executemyaction(), oppure executeMyaction(), e poi chiami l'azione myAction con il browser, symfony restituirà un errore 404.

-

**SIDEBAR** Le URL sono parte della risposta Symfony possiede un sistema di routing che ti permette di avere una separazione completa fra il nome effettivo dell'azione e l'URL necessaria a chiamarlo. Questo permette la personalizzazione delle URL come se fossero parte della risposta. Non sei più limitato né dalla struttura di file né dai parametri di richiesta; le URL per una azione possono essere la frase che preferisci. Ad esempio, la chiamata all'azione index di un modulo normalmente è tipo: http://localhost/myapp_dev.php/article/index?id=123 Questa URL recupera un articolo da un database. In questo esempio, recupera un articolo (con id=123) nella sezione Europa e che parla di finanza in Francia. Ma l'URL può essere riscritta in modo completamente differente modificando il file di configurazione routing.yml: http://localhost/articles/europe/france/finance.html Non solo la URL che ne risulta è motore di ricerca-friendly, ma ha anche un significato per l'utente, il quale può utilizzare la barra degli indirizzi come una pseudo linea di comando per eseguire delle ricerche personalizzate, come la seguente: http://localhost/articles/tagged/finance+france+euro Symfony sa come fare il parsing e generare URL intelligenti per l'utente. Il sistema di routing estrae automaticamente i parametri dalla URL intelligente e li rende disponibili all'azione. Esso si occupa anche di formattare gli hyperlink inclusi nella risposta, in modo da farli sembrare "intelligenti". Il Capitolo 9 illustra questa funzione. In generale, questo significa che il modo in cui si chiamano le azioni della tua applicazione non dovrebbe essere influenzato dal modo in cui dovrebbero apparire le URL che le chiamano, ma piuttosto secondo le loro funzioni nel contesto dell'applicazione. Il nome di un'azione spiega quello che l'azione fa effettivamente, e spesso è un verbo nella forma infinita (come show, list, edit, e così via). I nomi delle azioni possono essere totalmente invisibili all'utente, per cui non esitare ad usare nomi espliciti (come listByName o showWithComments). Risparmierai sui commenti del codice per spiegare ciò che fa la funzione, inoltre il codice sarà molto più leggibile.

### Aggiungere una template

L'azione si aspetta una template che la renderizzi. Una template è un file all'interno della cartella templates/ di un modulo, chiamato come l'azione e come il suo termine. Il termine di default per un'azione è un "successo", per cui la template da creare per l'azione myAction si deve chiamare myActionSuccess.php.

In teoria dentro una template ci dovrebbe essere solo codice di presentazione, per cui cerca di minimizzare il codice PHP al suo interno. In effetti, una pagina che visualizzi semplicemente "Ciao, mondo!" può avere una template come quella del Listato 4-3.

Listato 4-3 - La template mymodule/templates/myActionSuccess.php

[php] <p>Hello, world!</p>

Se tu avessi bisogno di utilizzare codice PHP nella template, dovresti evitare di usare la solita sintassi, come nel Listato 4-4. Invece, scrivi la tua template utilizzando una sintassi alternativa, come mostrato nel Listato 4-5, per mantenere il codice comprensibile per non-programmatori. Non solo il codice finale sarà indentato correttamente, ma ti aiuterà anche a mantenere del codice PHP complesso nell'azione, perchè solo gli statement di controllo (if, foreach, while, e così via) possiedono una sintassi alternativa.

Listato 4-4 - Sintassi PHP standard, corretta per le azioni ma non per le template

[php] <p>Hello, world!</p> <?php

if ($test) {

echo "<p>".time()."</p>";

}

?>

Listato 4-5 - Sintassi PHP alternativa, corretta per le template

[php] <p>Hello, world!</p> <?php if ($test): ?> <p><?php echo time(); ?></p> <?php endif; ?>

**TIP** Una buona regola per verificare che la template sia abbastanza leggibile, è controllare che non siano presenti parentesi graffe e che non ci sia codice HTML come output di PHP. E, la maggior parte delle volte, quando aprirai del codice PHP con <?php lo chiuderai sulla stessa linea con ?>.

### Passare informazioni dall'azione alla template

Il lavoro di un'azione è quello di eseguire tutti i calcoli complicati, recuperare dati e test, e settare variabili per poter essere testate o visualizzate da una template. Symfony rende possibile accedere direttamente agli attributi di una classe ($this->nomeVariabile) da una template nel namespace globale (tramite $nomeVariabile). I Listati 4-6 e 4-7 mostrano come passare informazioni da un'azione ad una template.

Listato 4-6 - Settare un attributo di un'azione per renderla disponibile ad una template

[php] <?php

class mymoduleActions extends sfActions {

public function executeMyAction() {

$today = getdate(); $this->hour = $todayhours?;

}

}

Listato 4-7 - La template ha accesso diretto all'attributo

[php] <p>Hello, world!</p> <?php if ($hour >= 18): ?> <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> <?php endif; ?>

**NOTE** Ogni template ha già accesso ad una piccola parte di dati senza settare alcuna variabile nell'azione. Ogni template può infatti chiamare i metodi degli oggetti $sf_context, $sf_request, $sf_params, e $sf_user. Essi contengono dati relativamente al contesto, richiesta, parametri di richiesta e sessioni correnti. Presto imparerai ad usarli efficientemente.

Raccogliere informazioni tramite form


Le form sono un buon metodo per raccogliere informazioni dall'utente. Scrivere a mano form HTML ed i suoi elementi a volte puo' risultare un po' fastidioso, specialmente si vuole aderire alle specifiche XHTML. In symfony puoi inserire elementi HTML nel solito modo, come puoi vedere dal Listato 4-8, ma il framework mette a disposizione degli helper che facilitano molto questo lavoro.

Listato 4-8 - Le template possono includere codice HTML

[php] <p>Hello, world!</p> <?php if ($hour >= 18): ?> <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> <?php endif; ?> <form method="post" target="/myapp_dev.php/mymodule/anotherAction">

<label for="name">What is your name?</label> <input type="text" name="name" id="name" value="" /> <input type="submit" value="Ok" />

</form>

Un helper non e' altro che una funzione PHP definita da symfony da utilizzare all'interno di template; scrive in output codice HTML ed e' piu' veloce da utilizzare piuttosto che scrivere lo stesso codice a mano. Utilizzando gli helper, puoi avere lo stesso risultato del Listato 4-8 tramite il Listato 4-9.

Listato 4-9 - E' piu' facile e veloce utilizzare gli helper

[php] <p>Hello, world!</p> <?php if ($hour >= 18): ?> <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> <?php endif; ?> <?php echo form_tag('mymodule/anotherAction') ?>

<?php echo label_for('name', 'What is your name?') ?> <?php echo input_tag('name') ?> <?php echo submit_tag('Ok') ?>

</form>

**SIDEBAR** Gli helper esistono per aiutarti Se per caso, nel Listato 4-9, non pensi che il codice tramite helper sia più veloce di quello scritto con HTML a mano, considera questo: [php] <?php $card_list = array( 'VISA' => 'Visa', 'MAST' => 'MasterCard?', 'AMEX' => 'American Express', 'DISC' => 'Discover'); echo select_tag('cc_type', options_for_select($card_list, 'AMEX')); ?> Che genera il seguente HTML: [php] <select name="cc_type" id="cc_type"> <option value="VISA">Visa</option> <option value="MAST">MasterCard?</option> <option value="AMEX" selected="selected">American Express</option> <option value="DISC">Discover</option> </select> Il beneficio derivante dall'utilizzo degli helper nelle template non è altro che pura velocità di coding, scrivere codice chiaro e conciso. L'unico prezzo da pagare è il tempo necessario ad imparare ad usarli, che si esaurirà quando avrai finito di leggere questo libro, ed il tempo di scriverli, per il quale dovresti già avere delle scorciatoie nel tuo editor di testo preferito. Quindi, potresti anche non usare gli helper di symfony nelle template, e scrivere codice HTML come hai sempre fatto, con una grande perdita di tempo e molto meno divertimento.

Nota che l'utilizzo di tag di apertura corti (<?=, equivalente a <?php echo) non è raccomandato in applicazioni web professionali, dato che il tuo web server potrebbe essere configurato per comprendere più linguaggi di scripting, e di conseguenza confondersi. Inoltre, i tag di apertura corti non sono abilitati nella configurazione di default di PHP, che quindi andrebbe modificata. Infine, quando si ha a che fare con la validazione e con XML, si generano errori in quanto <? ha un significato speciale in XML.

La gestione delle form merita un capitolo a parte, dato che symfony fornisce molti strumenti, molti dei quali helper, per facilitare lo sviluppo. Il Capitolo 10 è dedicato a tali helper.

Collegamento ad un'altra azione


Precedentemente hai imparato che c'è una totale separazione tra nome dell'azione e URL per chiamarla. Per cui se crei un collegamento a anotherAction come raffigurato nel Listato 4-10, esso funzionerà solamente con il routing di default. Se in un secondo momento decidi di cambiare il modo in cui le URL appaiono, dovrai rivedere tutte le template per cambiarne i link.

Listato 4-10 - Hyperlink, modo classico

[php] <a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">

I never say my name

</a>

Al fine di evitare questo inconveniente, dovresti sempre usare l'helper link_to() per creare link alle azioni della tua applicazione. Il Listato 4-11 mostra l'utilizzo di questo helper.

Listato 4-11 - L'helper link_to()

[php] <p>Hello, world!</p> <?php if ($hour >= 18): ?> <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> <?php endif; ?> <?php echo form_tag('mymodule/anotherAction') ?>

<?php echo label_for('name', 'What is your name?') ?> <?php echo input_tag('name') ?> <?php echo submit_tag('Ok') ?> <?php echo link_to('I never say my name','mymodule/anotherAction?name=anonymous') ?>

</form>

Il codice HTML risultante sarà lo stesso del Listato precedente, con la differenza che se cambi le regole di routing tutte le template continueranno a comportarsi correttamente, riformattando le URL di conseguenza.

L'helper link_to(), come molti altri, accetta un altro argomento per opzioni speciali e attributi aggiuntivi. Il Listato 4-12 mostra un esempio con un argomento opzionale ed il codice HTML che ne risulta. L'argomento aggiuntivo può essere sia un array associativo che una semplice stringa con coppie chiave=valore separate da uno spazio bianco.

Listato 4-12 - La maggior parte degli helper accettano un argomento opzionale

[php] // Option argument as an associative array <?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',

array(

'class' => 'special_link', 'confirm' => 'Are you sure?', 'absolute' => true

)) ?>

// Option argument as a string <?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',

'class=special_link confirm=Are you sure? absolute=true') ?>

// Both calls output the same

=> <a class="special_link" onclick="return confirm('Are you sure?');"

href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous"> I never say my name</a>

Ogni volta che usi un helper che genera un tag HTML, puoi sempre inserire attributi aggiuntivi (come la classe nell'esempio precedente) nel parametro opzionale. Potresti anche scrivere tali attributi nel modo "sporco e veloce" di HTML 4.0 (senza le doppie virgolette), e symfony si occuperà comunque di generarli nel corretto formato XHTML. Questa è un'altra ragione per cui l'utilizzo degli helper è più veloce di scrivere codice a mano.

**NOTE** Dato che richiede parsing e trasformazioni aggiuntive, la sintassi con la stringa è leggermente più lenta di quella con l'array.

Come per gli helpers, i link helpers sono numerosi ed hanno molte opzioni. Il Capitolo 9 li descriverà tutti nel dettaglio.

Raccogliere informazioni dalla richiesta


Sia che l'utente invii informazioni tramite una form (di solito richiesta in POST) che tramite URL (richiesta in GET), tu puoi ricevere i dati relativi nell'azione tramite il metodo getRequestParameter() dell'oggetto sfActions. Il Listato 4-13 mostra come, in anotherAction, puoi ricevere il valore del parametro name.

Lilstato 4-13 - Ricevere i dati dai parametri di richiesta nell'azione

[php] <?php

class mymoduleActions extends sfActions {

...

public function executeAnotherAction() {

$this->name = $this->getRequestParameter('name');

}

}

Se la gestione dei dati fosse semplice, non avresti neppure bisogno di utlizzare l'azione per ricever i dati. La template infatti ha accesso ad un oggetto chiamato $sf_params, che offre un metodo get() per ricevere i parametri di richiesta, esattamente come getRequestParameter nell'azione.

Se executeAnotherAction() fosse vuota, il Listato 4-14 mostra come la template anotherActionSuccess.php potrebbe ricevere lo stesso parametro.

Listato 4-14 - Ricevere i parametri direttamente nella template

[php] <p>Hello, <?php echo $sf_params->get('name') ?>!</p>

**NOTE** Perchè non usare invece le variabili $_POST, $_GET, o $_REQUEST? Perchè altrimenti le tue URL fossero formattate diversamente (come in http://localhost/articles/europe/france/finance.html, senza ? o =), le solite variabili PHP non funzionerebbero, e solo il sistema di routing sarebbe capace di ricevere i dati. E potresti voler aggiungere filtri in input, per evitare l'esecuzione di codice di injection maligno, cosa possibile esclusivamente utilizzando un sistema di gestione dei parametri pulito.

L'oggetto $sf_params è più potente di un semplice getter. Ad esempio, se tu volessi semplicemente testare l'esistenza di un parametro, potresti usare il metodo $sf_params->has() invece di testare l'effettivo valore con get(), come mostrato nel Listato 4-15.

Listato 4-15 - Testare l'esistenza di un parametro nella template

[php] <?php if ($sf_params->has('name')): ?>

<p>Hello, <?php echo $sf_params->get('name') ?>!</p>

<?php else: ?>

<p>Hello, John Doe!</p>

<?php endif; ?>

Forse hai già capito che questo può essere scritto in una sola linea. Come la maggior parte dei getter di symfony, sia il metodo getRequestParameter() nell'azione che il metodo $sf_params->get() nella template (che per la cronaca, chiamano lo stesso metodo dello stesso oggetto) accettano un secondo parametro: un valore di default se il primo non fosse disponibile.

[php] <p>Hello, <?php echo $sf_params->get('name', 'John Doe') ?>!</p>

Riepilogo


In symfony, le pagine sono composte da azioni (un metodo dentro il file actions/actions.class.php con il prefisso execute) e template (un file nella cartella templates/, il cui nome generalmente finisce con Success.php). Esse sono raggruppate in moduli, conformemente alla loro funzione nell'applicazione. Scrivere template è facilitato dagli helper, che sono funzioni fornite da symfony che generano codice HTML. E devi pensare alla URL come facente parte della risposta, che può essere formattata secondo i propri bisogni, per cui dovresti trattenerti dall'utilizzare qualsiasi riferimento diretto alle URL sia nei nomi delle azioni che nella gestione dei parametri.

Una volta imparati questi princìpi di base, puoi già scrivere un'applicazione intera con symfony. Ma richiederebbe troppo tempo, perchè quasi ogni operazione che devi svolgere durante lo sviluppo è facilitato in un modo o nell'altro da qualche caratteristica di symfony... motivo per il quale il libro non si ferma qui.