Il componente Zend_Translate fa proprio questo: permette di gestire facilmente le traduzioni prendendo le stringe da un adapter che può essere un semplice file csv oppure un file di tipo .mo (vedi gettext).
I problemi a cui sono giunto sono i seguenti:
- come mantenere lo stato della lingua dell'utente
- una volta definita la lingua come e dove inizializzare la classe Zend_Translate
- come permettere all'utente di cambiare lingua senza perdere il contesto
- La lingua dell'utente si tiene dentro la sessione in questo modo non si creano problemi di passaggio parametri negli URL. Inoltre la sessione è comunque già attiva per gestire le autenticazioni e quindi una variabile in più di 2 caratteri non fa troppo male.
- Quando un controller vede nell'url/get/post/cookie/env un parametro lang=xx si attiva per salvare il parametro nella sessione. In questo modo l'utente può cambiare la lingua senza perdere il contesto di quello che sta facendo
- L'inzializzazione della classe Zend_translate, così come la modifica della variabile di sessione, è fatto nel controller attivo.
OK. il posto giusto per non fare troppo lavoro e avere un oggetto facilmente manutenibile.
Perchè ho scartato i Front Controller Plugins invece...
In un primo tempo avevo pensato ai Plugin del Front Controller, però non si sono rivelati così flessibili.
Questo è un plugin, ad esempio, trovato sul blog di naneau.nl, che blocca l'accesso ad ogni pagina se non si è loggati:
class Plugins_CheckLogin extends Zend_Controller_Plugin_Abstract {
public function preDispatch() {
$login = false;
//you will probably want to implement this ;)
if (!$login) {
//no login
$request = $this->getRequest();
//the request
$request->setModuleName('default');
$request->setControllerName('login');
$request->setActionName('index');
//send to default/login/index
}
}
basta metterlo nella directory library/Plugins e richiamarlo nel bootstrap con
$frontController->registerPlugin(new Plugins_CheckLogin());
per vederlo funzionare in tutte le pagine del nostro sito.
L'unico problema è che il Plugin agisce 'fuori' dal controller e quindi non ha possibilità di accedere al controller e magari settare le variabili della view... Quindi se si vuole lavorare sulla request e magari modificarla, la soluzione migliore è sicuramente il Front Controller Plugin. Se invece si vuole agire a livello globale sui controller, come nel mio caso, è meglio usare un action helper che può essere richiamato in modo automatico sugli eventi.
... Aggiornamento .... dopo 4 ore (dovute soprattutto a convincere l'helper broker a digerire il nuovo helper) il mio helper 'translator' è funzionante e si adatta a qualsiasi controller (attuale o futuro) senza bisogno di scrivere una riga in più.
Anzi già che c'ero l'ho infarcito di tutte le cose che mi servono bene o male per tutti i controller...
(per i curiosi eccolo...)
<?php
require_once 'Zend/Controller/Action/Helper/Abstract.php';
class Helpers_Translator extends Zend_Controller_Action_Helper_Abstract {
public function init() {
$controller = $this->getActionController();
// utilità per le view
$controller->view->baseUrl = $controller->getRequest()->getBaseUrl();
//tutti i metodi della view possono usare $this->user per accedere all'utente
$controller->view->user = Zend_Auth::getInstance()->getIdentity();
//get the session
$sex = Zend_Registry::get('sex');
// numero di pagine
$controller->view->numberOfPageRequests =$sex->numberOfPageRequests;
// esiste un parametro di lingua allora lo mettiamo nella sessione
if($lang = $controller->getRequest()->getParam('lang', '')) {
$sex->lang = $lang;
}
//comunichiamo alla view il lang da usare
$controller->view->lang = $sex->lang;
// carichiamo il file di traduzione
$translationFile = '../languages/'. $sex->lang .'-source.csv';
// carichiamo il file di traduzione
if (file_exists($translationFile)) {
$controller->view->trans = new Zend_Translate('csv', $translationFile, $sex->lang, array('separator' => '|'));
} else {
$controller->view->trans = new Zend_Translate('csv', '../languages/nosource.csv');
}
}
}
2 commenti:
Ciao Brian, molto utile quello che hai scritto, ma purtroppo ho qualche problemino...
una volta fatto il file translator.php e inserito nella cartella application/views/helpers
viene caricato automaticamente?ho devo inserire qualcosa nel file di bootstrap?
ho lo stesso problema con la registrazione dei plugin...non riesco a capire dove metterli e come richiamarli...dà sempre qualche errore...
ciao e grazie
Quello che ho scritto io è un Action Helper e non un view helper...
I view helper vanno nella directory application/views/helpers come hai fatto tu e vengono caricati automaticamente.
Gli Action Helper invece bisogna caricarli a manina.
Io metto ogni Action Helper in library/Helpers (nota l'H maiuscola) e li carico nel bootstrap così:
...
$translator = new Helpers_translator();
Zend_Controller_Action_HelperBroker::addHelper($translator);
...
Naturalmente prima uso registerAutoload per evitare di mettere i require_once
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
Ciao
Posta un commento