- Mon
- 2
- Feb
- 09
Zend Framework: gestione dei moduli ed esempio modulo di amministrazione
Di in Php, Zend Framework Controls: +-close
Come usare Zend_Layout per la gestione dei moduli
In quest’articolo vedremo come gestire differenti moduli con Zend Framework oltre a quello di default per creare, per esempio, un modulo di amministrazione.
A titolo riassuntivo, ecco un elenco di cosa abbiamo già visto di Zend Framework:
- Introduzione a Zend Framework con esempio pratico minimalista di utilizzo
- Configurazione Avanzata
- Two Step View per la gestione dei layouts
- Implementazione di un layout complesso per la gestione dei layouts
- Gestione dei modelli ed interazione con database
- Gestione delle richieste asincrone ( Ajax ) aiutandoci con l’utilizzo di jQuery
- Gestione del database
- Database e reference map
- Autenticazione con Zend_Auth
- Autorizzazione con Zend_Acl con esempio integrato al database
- Zend Framework e Zend_Search_Lucene motore di ricerca interno
- Zend Framework e Zend_Mail con esempio di invio email
- Zend Lucene e UTF8 con esempio di applicazione scaricabile
- Zend_Log e gestione errore 404
- Zend Framework Bootstrap Object Oriented
- Form Con Zend_Form
- Il componente Recapcha per la sicurezza dei form
Per la comprensione di questo articolo consiglio prima di leggere gli articoli a proposito della gestione di un bootstrap object oriented ma ancora prima della gestione dei layouts con Zend_Layout e two step view.
Il modulo default
Per convenzione, il modulo di default utilizzato dalla vostra applicazione sviluppata con Zend Framework si chiama, non a caso, default. Che significa questo? Immaginiamo che voi abbiate un controller chiamato ’search’ all’interno della vostra applicazione, una chiamata al suddetto controller potrebbe essere effettuata tramite la url ‘http://www.miosito.xx/search’. Non abbiamo specificato nessun modulo, quindi, per convenzione, è come se avessimo chiamato default. Infatti, possiamo ottenere lo stesso risultato richiamando la url ‘http://www.miosito.xx/default/search’.
Allo stesso modo, creando una directory chiamata ‘default’ all’interno della directory ‘application’ ed inserendo tutto il contenuto della seconda nella prima ( tranne che il file bootstrap.php ) tutto continuerebbe a funzionare.
Creiamo il modulo di amministrazione
Non è strettamente necessario, ma siccome non ho scoperto nessun genere di controindicazione ed aiuta a dare all’albero dell’applicazione quel pizzico di ordine aggiuntivo, creiamo all’interno di ‘application’ la directory ‘default’ ed inseriamo ‘controllers’, ‘models’ e ‘views’ all’interno di essa. Creiamo all’interno di ‘application’ la directory ‘admin’ ed al suo interno le 3 directories ‘controllers’, ‘models’ e ‘views’.
Il nuovo albero dell’applicazione dovrebbe risultare quindi come il seguente:
- la_mia_applicazione
- application
- default
- controllers
- models
- views
- scripts
- index
- error
- layouts
- filters
- helpers
- scripts
- admin
- controllers
- models
- views
- scripts
- index
- layouts
- filters
- helpers
- scripts
- default
- db
- library
- Zend
- tests
- controllers
- models
- application
- web_root (www)
- css
- img
- js
Rendere operativo il nuovo modulo
Attualmente il nostro modulo di amministrazione non è nient’altro che una directory all’interno del nostro albero dell’applicazione, e non abbiamo ancora provveduto ad effettuare nessuna modifica al codice per ‘dire’ a Zend Framework che, quando il modulo richiamato è ‘admin’, di andarsi a leggere il contenuto di admin e non di default.
Questo è proprio il nostro problema attuale: dobbiamo riuscire a recuperare il nome del modulo richiesto prima che Zend_Layout lo renderizzi. Per questo scopo creeremo il plugin library/MiaApplicazione/Layout/Controller/Plugin/Layout.php
class MiaApplicazione_Layout_Controller_Plugin_Layout extends Zend_Layout_Controller_Plugin_Layout
{
public function preDispatch(Zend_Controller_Request_Abstract $request){
switch ($request->getModuleName()){
case 'admin':
$this->_moduleChange('admin');
}
}
protected function _moduleChange($moduleName){
$basePath = dirname(dirname(dirname($this->getLayout()->getLayoutPath())));
$this->getLayout()->setLayoutPath($basePath.DIRECTORY_SEPARATOR.$moduleName.'/views/layout');
$this->getLayout()->setLayout($moduleName);
}
}
Il passo successivo è rendere operativo questo plugin. Per far ciò dobbiamo modificare il bootstrap modificando l’array passato ad argomento alla chiamata di Zend_Layout::startMvc.
public static function setupView(){
$view = new Zend_View;
$view->setEncoding('UTF-8');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
Zend_Layout::startMvc(
array(
'layoutPath' => ROOT_DIR.'/application/default/views/layouts',
'layout' => 'layout',
'pluginClass' => 'MiaApplicazione_Layout_Controller_Plugin_Layout'
)
);
}
Inoltre dovremo apportare la seguente modifica al metodo setupFrontController per quanto riguarda l’assegnazione della directory dei controllers:
public static function setupFrontController(){
self::$frontController = Zend_Controller_Front::getInstance();
self::$frontController->throwExceptions((bool)self::$registry->config->front->throwExceptions);
self::$frontController->returnResponse((bool)self::$registry->config->front->returnResponse);
self::$frontController->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
self::$frontController->setControllerDirectory(
array(
'default' => ROOT_DIR.'/application/default/controllers',
'admin' => ROOT_DIR.'/application/admin/controllers'
)
);
}
Il layout di amministrazione
Creiamo il file admin.phtml, che sarà il layout del modulo di amministrazione. Questo file dovrà trovarsi all’interno di application/admin/views/layout.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Amministrazione <?php echo $this->escape($this->pageTitle); ?></title>
</head>
<body>
<!-- start container -->
<div id="container">
<!-- start subContainer -->
<div id="subContainer">
<!-- start header -->
<div id="header"><?php //echo $this->layout()->header;?></div>
<!-- end header -->
<!-- start content -->
<div id="content"><?php echo $this->layout()->content;?></div>
<!-- end content -->
<!-- start footer -->
<div id="footer"><?php //echo $this->layout()->footer;?></div>
<!-- end footer -->
</div>
<!-- end subContainer -->
</div>
<!-- end container -->
</body>
</html>
Infine avremo bisogno del file della view index.phtml che dovrà trovarsi all’interno di admin/views/script/index.
<h2>Modulo di amministrazione</h2>
Fatto ciò siete pronti per richiamare la url ‘http://www.miosito.xx/admin/’ e contemplare il risultato del vostro lavoro.
Riferimenti
Related posts:
- Neobazaar annunci gratuiti: esempio di una applicazione sviluppata con Zend Framework Nasce Neobazaar.com, annunci gratuiti in Italia: interamente sviluppato con Zend...
- Zend Framework 1.8.2 disponibile La notizia è di 2 giorni fa, in ogni caso...
- Zend Framework: Zend_Form con ReCaptcha Utilizzare il webservice ReCaptcha per validare i form ReCaptcha è...
- Zend Framework 1.8.1 disponibile Lo Zend Framework Team annuncia l'immediata disponibilità della nuova versione...
- Zend Framework: introduzione al componente Zend_Form Creare form web con Zend Form Con Zend Framework possiamo...
Related posts brought to you by Yet Another Related Posts Plugin.












Ciao, trovo davvero ottimi i tuoi articoli su zend framework, al quale mi sto avvicinando ora… davvero esaudienti e migliori di molto materiale in inglese se si trova in giro, complimenti!
Ora la domanda:
ipotizziamo di avere un modulo news, come faccio se voglio comunque utilizzare il layout di default del sito (quindi header.phtml, footer.phtml ecc che trovo, nella directory /application/modules/default/views/scripts)?
Seguendo gli esempi di “Paesi nel mondo”, nell’init() del controller ho il seguente codice:
$response->insert(’header’, $this->view->render(’header.phtml’));
il file header.phtml però lo cerca nella directory /application/modules/admin/views/scripts e non in quella di default.
Ho provato anche a specificare il percorso completo del file ma l’errore restituito parla da solo:
Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ’script ‘C:\web\www/navis//application/modules/default/views/scripts/header.phtml’ not found in path (C:\web\www\navis\application\modules\news\views\scripts\)’
Cosa fare per avere un path unico in questi casi?
Grazie di tutto e scusa per la domanda forse da niubbo.
Forse mi rispondo da solo alla domanda posta in precedenza:
invece di chiamare nell’init di ogni controller
$response->insert(’header’, $this->view->render(’header.phtml’));
ho spostato i file headers.phtml nella directory modules/default/views/layout
ed all’interno del file layout.phtml li ho richiamati cosi:
$this->render(’header.phtml’);
Non so se sto prendendo la strada giusta, ma sembra funzionare…
Ciao,
appena mi è possibile lo provo e ti faccio sapere.
Grazie per i commenti!
Grazie mille sergio
Il tuo blog è diventato tappa fissa quotidiana, continua così!
Pare che non sia possibile utilizzare un controller di un certo modulo ed unirlo alla view di un altro, dopo vari test sono giunto a questa conclusione. Farò delle ricerche in merito. Però mi chiedo una cosa, hai proprio la necessità di creare un modulo aggiuntivo piuttosto che creare un nuovo controller per il modulo di default? Ciao
Ciao, no non è necessario, per ora sto solo studiando.
Pensavo però che per un’applicazione complessa, lavorare con i moduli sia più facile tenere ben organizzato il lavoro e magari i moduli potrebbero essere riutilizzati in altri progetti semplicemente copiando la directory.
Ma appunto perchè ora mi sto avvicinando a zend framework, magari sto dicendo idiozie
Cmq seguendo i passaggi che ho indicato nel messaggio numero 2 funziona!
Ciao e grazie di nuovo.
dimenticavo, con il metodo indicato nel messaggio 2, si evita anche di dover fare il render dei file phtml nell’init() di ogni singolo controller… quali potrebbero essere però le controindicazioni?
A dire il vero io non ho capito molto di cosa hai fatto nel passo 2, spiegati meglio.
In quanto alla ripetizione del metodo init per ogni controller è un problema che ho risolto diversi mesi fa ma che ancora non avevo avuto modo di scrivere, basta estendere Zend_Controller_Action nella propria libreria quindi creare i controller estendendo la nuova classe creata. Questa nuova classe conterrà il metodo init che sarà quindi richiamato in automatico per ogni singolo controller. Scriverò qualcosa a proposito prima o poi…
ciao, io ho creato una directory nel modulo di default:
application\modules\default\views\layouts\structure
al suo interno ho i file header.phtml, footer.phtml, menu, ecc.
Nel file application\modules\default\views\layouts\layout.phtml
li ho richiamiati così:
$this->render(’structure/header.phtml’);
in questo modo non ho nulla nell’init() dei controllers e tutti i moduli accedono al layout di default. Mi chiedevo prima quali potrebbero essere le controindicazioni rispetto anche alla tua ultima soluzione proposta… che è molto interessante perchè fa capire tutte le potenzialità della programmazione ad oggetti
Ciao e grazie.
Ciao!
anch’io penso che i tuoi tutorial sono grandi…
sto cercando di imparare ZF e mi sono molto utili..
Ho notato che è un pò che nojn ne posti. Hai interrotto la pubblicazione? o Sei molto impegnato?
Ciao,
grazie del commento.
In realtà ho visto diversi altri componenti di Zend Framework, come Zend_Translate, Zend_Cache, Zend_Route, una nuova implementazione di Zend_Acl… cercherò di scrivere al più presto qualcosa, anche se adesso la mia prorità sarebbe implementare l’inserimento dei dati con le transazioni e la gestione gerarchica delle tabelle ( fatta come si deve ).
Inoltre i commenti postati sono pochi, quindi non ho ben chiaro se l’argomento interessa o meno.
Stavo pensando di aprire un forum da collegare a questo blog, secondo voi sarebbe una buona idea?
Secondo me l’attuale seguito di ZF in italia non è tale da giustificare un forum. Forse è dovuto alla mancanza di documentazione adeguata nella nostra lingua.
io in pratica ho iniziato soltanto da qualche settimana, e di materiale recente e interessante in italiano ho trovato solo questo sito. i tutorials sono molto ben fatti e chiari.
Forse proprio perché il seguito di ZF in Italia non è molto sviluppato, sarebbe utile creare un forum su questo argomento in modo da “avvicinare” altre persone.
Ciao Sergio,
stavo mettendo in pratica il tuo tutorial(approposito, complimenti per l’ottimo lavoro fatto) e ricevo questo messaggio di errore:
exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller class (”Admin_IndexController”)’ in C:\xampp\htdocs\lavoro\MyProject\library\Zend\Controller\Dispatcher\Standard.php:345
Stack trace:
#0 C:\xampp\htdocs\lavoro\MyProject\library\Zend\Controller\Dispatcher\Standard.php(256): Zend_Controller_Dispatcher_Standard->loadClass(’IndexController’)
#1 C:\xampp\htdocs\lavoro\MyProject\library\Zend\Controller\Front.php(946): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#2 C:\xampp\htdocs\lavoro\MyProject\index.php(78): Zend_Controller_Front->dispatch()
#3 {main}
come mai secondo te ??
Ciao,
purtroppoo dalla versione 1.8 di Zend Framework, questo tutorial non è più valido ( che versione di zf usi? spero l’ultima disponibile.. ). Una soluzione comunque c’è, ancora io non ho scritto nulla a proposito ma se mastichi un po’ di inglese puoi capire come risolvere in questa discussione che iniziai nella mailing list di Zend Framework lo scorso 7 Maggio http://www.nabble.com/ZF1.8-Switching-layouts-between-modules.-td23433040.html ( guarda dove si scrive a proposito del ModuleLazyInit plugin ).
Fammi sapere se riesci, nel caso tu abbia problemi potrebbe darsi che finalmente mi decida a scrivere un nuovo tutorial
Ciao
Ciao,
hai detto bene, uso l’ultima versione di zend, ma ancora non ho adottato lo zend_application.
mi trovo con il semplice bootstrap, e da quello che ho letto sul sito che mi hai consigliato, si fa’ uso della nuova classe.
Per tale motivo, ho difficoltà a risolvere il problema.
Mi puoi dare un dritta ??’
Grazie
Carlo
Ciao,
scusa il ritardo nella risposta, al fine di poterti dare una mano, nel caso tu non abbia ancora risolto, potresti postare il tuo albero dell’applicazione ( se non tutto, almeno in quale locazione è salvato Admin_IndexController ).
Ciao
Ciao ho risolto il problema, scusami per il ritardo
Volevo chiederti un altra cosa.
Vorrei creare una cartella modules ed all’interno creare le cartelle blog/ news/ stats/ che utilizzano sempre il layput di default.
posso utilizzare il codice che hai realizzato, ho devo apportare delle modifiche ??
Grazie
Carlo