Tag: i18n

Settare CakePHP per il multilingua

Spesso mi sono trovato nella situazione di realizzare dei progetti multilingua, per Cake c’è un plug-in che potete utilizzare, sviluppato dal CakeDC, che personalmente uso in tutti i nuovi progetti.

Il vostro sito passerà dall’indirizzo http://www.miosito.it/articoli all’URL http://www.miosito.it/eng/articoli.
Questa modifica da diversi benefici al vostro progetto:

  1. gli URL sono seguibili dai motori di ricerca e vengono indicizzate tutte le pagine con URL diversi per ogni lingua
  2. quando un utente condivide la pagina che sta visionando passa un URL completo e nella lingua corretta

Il plug-in i18n lo trovate nel repository https://github.com/CakeDC/i18n

Vediamo come installarlo ed iniziare ad utilizzare il multi lingua.

Prima di tutto dovete scaricare o clonare la repo nella cartella app/Plugin, verificate di creare la cartella i18n e che tutti i file siano presenti al suo interno.

Ora bisogna aprire il file app/Config/bootstrap.php ed inserire queste righe:

define('DEFAULT_LANGUAGE', 'ita'); // le 3 lettere che definiscono la vostra lingua di default
Configure::write('Config.languages', array('ita','eng', 'deu', 'fre', 'jpn', 'spa', 'rus')); //lista delle lingue che volete utilizzare nel sito
CakePlugin::load('I18n', array('routes' => true)); //caricamento del plugin

Queste righe servono per definire la lingua di default usata, le lingue usate nel sito e dice a CakePHP di caricare il plugin i18n ed utilizzare la classe I18nRoute che si trova nel plugin.

Bene, spieghiamo a CakePHP come deve utilizzare i nostri nuovi URL. Aprite il file app/Config/routes.php e modificatelo in questo modo:

App::uses('I18nRoute', 'I18n.Routing/Route');
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'), array('routeClass' => 'I18nRoute'));
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'), array('routeClass' => 'I18nRoute'));

Ricordate che ogni nuova direttiva che andrete ad aggiungere in questo file dovrà avere come parametro array(‘routeClass’ => ‘I18nRoute’).

Assicurati di avere questa riga:

CakePlugin::routes();

dovresti trovarla verso la fine della pagina, e commenta o cancella la riga:

require CAKE . 'Config' . DS . 'routes.php';

Abbiamo quasi finito, ora insegniamo a come creare i nuovi URL, apri il file app/View/Helper/AppHelper.php e modificalo così:

class AppHelper extends Helper {
public function url($url = null, $full = false) {
if (empty($url) || (is_array($url) && !array_key_exists('lang', $url))) {
$url['lang'] = Configure::read('Config.language');
}
return parent::url($url, $full);
}
}

Ottimo, abbiamo finito, ora ti spiegherò ancora due cosette.

Come creare lo switcher per le lingue

Se vuoi creare in modo semplice uno switcher per cambiare la lingua, CakePHP ha già “tutto pronto”. Nel tuo layout devi solamente inserire queste poche righe e magicamente vedrai comparire le bandiere per la selezione della lingua.

Aggiungi nell’AppController l’helper dell’i18n, apri app/Controller/AppController.php e modifica così:

class AppController extends Controller {
public $helpers = array('I18n.I18n', ...);
}

nel tuo layout, in questo caso quello di default, app/View/Layouts/default.ctp

<?php echo $this->I18n->flagSwitcher(array('class' => 'languages', 'id' => 'language-switcher')); ?>

Come usare il requestAction

Ti capiterà di utilizzare il requestAction all’interno del tuo progetto, cerca di usarlo quando è strettamente necessario, quando fai una chiamata con questa funziona purtroppo CakePHP ha bisogno di un aiuto, gli devi specificare in che lingua ti servono i risultati, questo si fa così:

&lt;?=$this-&gt;requestAction('/'.Configure::read('Config.language').'/menus/generate/1',array('return'));?&gt;

oppure, questo è il metodo che uso io, in AppController:

public function beforeFilter() {
$this-&gt;set('language',Configure::read('Config.language'));
}

così ho la lingua disponibile in tutto il sito e per il requestAction:

&lt;?=$this-&gt;requestAction('/'.$language.'/menus/generate/1',array('return'));?&gt;

tutto questo naturalmente nella view.

Utilizzare LC_TIME con CakePHP

Il grande team di CakePHP dalla versione 1.3 ha implementato il supporto alle traduzioni LC_TIME. Siccome ho investito un po’ di tempo nella ricerca dei vari elementi che servono ad impostare CakePHP e a capire il suo funzionamento ho pensato di scrivere qui queste informazioni in modo da risparmiare tempo a chi dovrà utilizzarlo dopo di me.

Prima di iniziare dovete sapere come funziona l’internazionalizzazione di CakePHP (Internazionalizzare le tue applicazioni) ed un piccolo appunto sull’i18n qui

Prepariamo CakePHP per LC_TIME

Prima di tutto abbiamo bisogno di un file con i parametri giusti per la nostra lingua, io naturalmente preparo tutto per l’italiano, ma lo potete fare per tutte le lingue che vi servono. Per avere i parametri se avete una macchia Linux a disposizione copiatevi il file /usr/share/i18n/locales/it_IT (it_IT nel mio caso) sul desktop oppure nel caso non avete una macchina a Linux a disposizione scaricatevi questo zip dove trovate tutti i file che erano presenti nel mio server.

Bene! Fatto questo, per far funzionare __ c (), $this->Time->format () e $this->Time->i18nFormat () abbiamo dobbiamo:

  1. creare un file denominato /app/Locale/ita/LC_TIME (ita nel mio caso per l’italiano)
  2. aprite il vostro file i18n di Linux, il mio it_IT
  3. copiate tutto quello che trovate tra LC_TIME  ed END LC_TIME, incollatelo nel file creato nel passaggio 1 e salvate

Attenzione: assicuratevi di aggiungere le definizioni “escape_char” e “comment_char” all’inizio del file LC_TIME appena modificato oppure rischiate di perdere delle ore alla ricerca del perché non funziona la vostra configurazione (come il sottoscritto):

comment_char %
escape_char /

Testiamo LC_TIME appena impostato

Aggiungiamo le seguenti linee ad una delle nostre viste ed aggiungiamo l’helper “Time” nel controller:

$timestamp = time();
 $timestring = $this-&gt;Time-&gt;format('Y-m-d H:i:s', $timestamp);
 $months = __c('mon',LC_TIME);
 pr("Timestamp = $timestamp");
 pr("Timestring = $timestring");
 pr("strftime() tradotto = " . strftime("%A %e %B %Y", strtotime($timestring)));
 pr("i18nFormat  tradotto = " . $this-&gt;Time-&gt;i18nFormat($timestring, "%A %e %B %Y"));
 pr("Time::format tradotto = " . $this-&gt;Time-&gt;format($timestring, '%A %e %B %Y'));
 pr($months);

Il risultato che dovremmo ottenere è questo:

Timestamp = 1353682742
Timestring = 2012-11-23 15:59:02
strftime() tradotto = Friday 23 November 2012
i18nFormat  tradotto = venerd 23 novembre 2012
Time::format tradotto = venerd 23 novembre 2012
Array
(
    [0] =&gt; gennaio
    [1] =&gt; febbraio
    [2] =&gt; marzo
    [3] =&gt; aprile
    [4] =&gt; maggio
    [5] =&gt; giugno
    [6] =&gt; luglio
    [7] =&gt; agosto
    [8] =&gt; settembre
    [9] =&gt; ottobre
    [10] =&gt; novembre
    [11] =&gt; dicembre
)

Per imparare ad utilizzare il formato di LC_TIME leggetevi questa pagina di PHP: strftime()