CDbMessageSource?

Devo realizzare un sito che avrà contenuti in diverse lingue. Ho cercato nella documentazione ed ho trovato questa classe: CDbMessageSource.

Cosa sbaglio nello scrivere questo?




      <?php $txt = new CDbMessageSource; ?>

      <?php var_dump($txt->loadMessagesFromDb('categoria', 'it')); ?>



Ricevo come errore ciò:




CDbMessageSource does not have a method named "loadMessagesFromDb".



Ecco dove si può trovare CDbMessageSource:

http://www.yiiframework.com/doc/api/1.1/CDbMessageSource#loadMessagesFromDb-detail

PS. Dopo aver scritto questo POST mi sono ri-scaricato la documentazione ed ora sto leggendo. Vi tengo aggiornati.

A pagina 213 del manuale di Yii 1.1.6 trovo scritto che per recuperare il linguaggio preferito dall’utente posso usare CHttpRequest::preferredLanguage. Per non saper ne leggere ne scrivere ho tentato di fare questa prova:


<?php echo CHttpRequest::preferredLanguage; ?>

Viene INTERROTTA la pagina … mi aspetterei un’eccezione, piuttosto.

Ciao Sensorario.

CDbMessageSource e’ un componente e va configurato nel file main.php.


return array(


   'components'=>array(


      'messages'=>array(


          'class'=>'CDbMessageSource',


      ),


   ),

);

Di default il tuo dbase dovrebbe contenere le seguenti tabelle:


CREATE TABLE SourceMessage

(

    id INTEGER PRIMARY KEY,

    category VARCHAR(32),

    message TEXT

);

CREATE TABLE Message

(

    id INTEGER,

    language VARCHAR(16),

    translation TEXT,

    PRIMARY KEY (id, language),

    CONSTRAINT FK_Message_SourceMessage FOREIGN KEY (id)

         REFERENCES SourceMessage (id) ON DELETE CASCADE ON UPDATE RESTRICT

);

Dopo puoi richiamare i messaggi con il solito Yii::t()

ES:

Yii::t(‘Categoria’,'Testo in Italiano);

Si ci stavo arrivando proprio ora. Secondo me nel manuale si dovrebbe esplicitare quello che mi hai appena scritto. Alle tabelle ci ero arrivato, ma non è automatico il dover mettere mano al file di configurazione. Provo all’istante e poi ti dico.

Ho aggiunto il componente:


    // application components

    'components' => array(

        'messages' => array(

            'class' => 'CDbMessageSource', /* 02 marzo aggiunto supporto per le lingue */

        ),

Ho caricato del testo a manazza nelle due tabelle:


INSERT INTO `Message` (`id`, `language`, `translation`) VALUES

(1, 'it_it', 'Testo in Italiano'),

(1, 'en_en', 'Text in english');


INSERT INTO `SourceMessage` (`id`, `category`, `message`) VALUES

(1, 'perepe', 'Testo in Italiano');

Ma continuo a vedere stampato il "Testo in italiano":


<?php echo Yii::t('perepe','Testo in Italiano'); ?>

PS. ho impostato languages a mano dentro il file di configurazione

OK ho trovato il mio errore. Quando si inseriscono le traduzioni, bisogna inseire solo la sigla della lingua:


INSERT INTO `Message` (`id`, `language`, `translation`) VALUES

(1, 'it', 'Testo in Italiano'),

(1, 'en', 'Text in english');

anzichè


INSERT INTO `Message` (`id`, `language`, `translation`) VALUES

(1, 'it_it', 'Testo in Italiano'),

(1, 'en_en', 'Text in english');

Ora la domanda sorge spontanea … esistono anche componenti per la gestione di questi testi o posso darmi alla pazza gioia con ExtJS =) e crearmi una applicazione che si occupa esattamente di questo =) ?

Mmmm e invece ho un problema: come faccio a cambiare la lingua?

Questa è una potenziale soluzione che funziona ma che non mi pare usare del codice standard.

Per prima cosa ho pensato di modificare la view /protected/views/layouts/main.php. Ho anche pensato di mettere questo codice dentro la index.php ma volevo lasciarla pulita.


<?php @session_start(); Yii::app()->setLanguage(isset($_SESSION['lang'])?$_SESSION['lang']:'it'); ?>

at first line.

Per cambiare la lingua utilizzo "index.php?r=site/changelanguage&lang=it" e funziona correttamente.


  public function actionChangelanguage() {

    @session_start();

    $_SESSION['lang'] = (strtolower($_GET['lang']));

    $this->redirect(array('site/index'));

  }

Il fatto che funzioni mi sta bene ma non mi pare la soluzione migliore in quanto non si tratta di codice standard. Dalla documentazione ho appreso solo che posso aggiungere files nella cartella messages. Posso usare anche classi. Io però gradirei un modo automatico e trasparente senza bisogno di dover aggiungere altro codice o "pezzi" alla querystring.

Di default i messaggi li puoi salvare nella cartella message ma e’ una tua scelta, dipende da quello che hai intenzione di creare.

Per cambiare la lingua dai un’occhiata a questa estensione:

http://www.yiiframework.com/extension/langhandler

Questa estensione e’ un po’esagerata, cambia tutti gli url.

Io faccio una cosa simile a quella che fa sensorario, solo un po; piu’ ordinata:

Ho una behavior per la application:




<?php

/**

 * ApplicationConfigBehavior is a behavior for the application.

 * It loads additional config paramenters that cannot be statically 

 * written in config/main

 */

class ApplicationConfigBehavior extends CBehavior

{

	/**

	 * Declares events and the event handler methods

	 * See yii documentation on behaviour

	 */

	public function events()

	{

		return array_merge(parent::events(), array(

			'onBeginRequest'=>'beginRequest',

		));

	}


	/**

	 * Load configuration that cannot be put in config/main

	 */

	public function beginRequest()

	{

		// set the user language

		

		//if the user choosed a language, we use the choosen one

		if ($this->owner->user->getState('applicationLanguage'))

			$this->owner->language=$this->owner->user->getState('applicationLanguage');

		else 

			$this->owner->language='ru';

	}

}




Che si include nel config main:




	/* the behavior that loads other paramenters that can be loaded only runtime

	 * see protected/components/ApplicationConfigBehavior.php */

	'behaviors'=>array(

		'runTimeConfig'=>array(

			'class'=>'ApplicationConfigBehavior'

		)

	),



Per cambiare la lingua io ho una form che manda ad una azione del site controller:




	/**

	 * set the application language or the theme according to the choice of the user

	 * see protected/components/sectionMenu

	 * see protected/components/theme

	 */

	public function actionSettings()

	{

		if (isset($_POST['language']))

			Yii::app()->user->setState('applicationLanguage',$_POST['language']);


		$this->redirect($_POST['url']);

	}



Grosso modo e’ l’approccio di sensorario, solo che salviamo il valore nello user (perche’ ci pensa Yii a metterlo in session) e carichiamo il valore nella onInit.

Esatto =) era quello che volevo dire ehehe. Grazie!!!

Ora però ho un problema:


      <?php echo Yii::t('menu', 'Chi è ghimas'); ?>

Funziona solo nel layout! Possibile? Ho provato a mettere lo stesso testo in un template ma non recupera dal DB il testo che voglio io. Possibile?

No: non riesco ad ottenere il testo giusto se non dal template /protected/views/layouts/main.php

Be’ e’ chiaro che essendo un sito multilingua dovrebbero cambiare tutti i link.

Comunque Sensorario prova cosi’:


Yii::t("menu","Chi è ghimas",array(),"CDbMessageSource");

Nada =(. A me non è chiaro perchè debbano cambiare i link. La lingua è una informazione che potrebbe tranquillamente risiedere dentro ad una sessione. Ma al di la dello stile di ciascuno di noi … qui non mi va quasi nulla.

Continuo a non comprendere come mai questo codice funzioni nel main ma non funzioni in altri template:


<?php echo Yii::t("testi", "Testo in italiano"); ?>

PS:


Yii::t("menu","Chi è ghimas",array(),"CDbMessageSource");

non funziona proprio da nessuna parte.

Come al solito c’è qualche cosa che mi manca. Diamine e cribbio!

Super accrocchio!!!!

Curiosando nella funzione Yii:t( … ho scoperto che posso anche inviare la lingua.


<?php @session_start(); ?>

<?php echo Yii::t("testi", "Testo in italiano", null, null, $_SESSION['lang']); ?>

Però questo risolve i miei problemi solo in parte. Voglio dire, un domani questo sito potrebbe crescere parecchio e se riempio di accrocchi finisce sicuramente male per me =(.

Se stai lavorando su un backend alora sono d’accordo con te… la lingua puo stare in session…

pero

se stai lavorando su un sito… che tra l’altro ha bisogno di essere trovato tramite google o altri “search engines”… alora la lingua nel link ha la precedenza… perche a tal modo hai piu pagine (in diverse lingue) che google puo trovare… se in questo caso usi la session… google vedra solo la pagina in inglese (ho quela di default)… tutte le altre pagine non le vedra…

Cribbio! Avevo la 1.1.5 sul mio portatile. AH! Propongo una punizione corporale. Facciamo così, io mi lego da solo e voi mi camminate sopra.

Il problema è proprio questo della versione infatti. In effetti è stato ritoccato il CLDR nella 1.1.6. Ecco fatto il misfatto. Ho scaricato .a 1.1.6 da yiiframework. Ho sostituito la vecchia cartella di yii e ora tutto funziona.

Ops, avevo dimenticato il SEO. Bene, ora che ho pulito tutti i miei accrocchi grazie ai vostri consigli e suggerimenti. Ho un’altra domanda da porvi: Ma se io oggi faccio a meno degli url ottimizzati per il SEO e un domani il cliente si sveglia e dice “dannazione, voglio SEO in 10000 lingue” butto il mio lavoro dalla finestra?

Sono tornato nella documentazione e non ho letto nulla di interessante.

IMO non vedo perche qualchuno farebbe un frontend senza la lingua nel URL…

anche se non serve il SEO…

un esempio: se qualcuno vuole mandare una pagina (in una lingua) ha un amico… l’amico potrebbe non vedere la pagina nella lingua desiderata…