Internationalization (i18n)
* at top of controller: uses('L10n');
* create /app/locale/eng/LC_MESSAGES/default.po (French is fre/
fra)
o http://www.loc.gov/standards/iso639-2/php/code_list.php
* create entries in default.po as such:
msgid "close_window"
msgstr "Close"
msgid "where_pin"
msgstr "Where is my PIN?"
* call translations in view: <?__("close_window")?> )
("close_window" is msgid from default.po)
o this is going to echo out the msgstr for the given msgid,
else it wil display the msgid given
o use __("button_submit", true) to return the value as
opposed to echoing it
* you can specify different languages as such:
$this->L10n = new L10n();
$this->L10n->get('eng');
Thank you all, I have successfully implemented translations.
The implementation to help other facing the same situation:
1. Create the i18n tables from the sql file /config/sql/i18n.sql
2. Create the news_articles table
id (int8) prim key, auto incr.
.... other fields like created_at, updates_at ....
3. Create a demo article in news_articles
id created_at
1 2007-06-01 14:55:41
4. Add some demo data to i18n
----
id content
1 Title in english
2 Titre en français
3 Content in english
4 Contenu en français
----
5. Add some demo data to i18n_content
----
id locale i18n_content_id model row_id field
1 en 1 NewsArticle 1 title
2 fr 2 NewsArticle 1 title
3 en 3 NewsArticle 1 content
4 fr 4 NewsArticle 1 content
-----
6. Build the model for news_article (/models/news_article.php)
----
class NewsArticle extends AppModel{
var $name = 'NewsArticle';
var $actsAs = array('Translate' => array('title','content'));
(title,content are the fields to translate. Add more for every field)
7. Basic news_articles controller with index action (/controllers/
news_articles_controller.php)
----
class NewsArticlesController extends AppController{
var $name = 'NewsArticles';
function index(){
//set the required language identifier here, 'en' or 'fr' in this
example
$this->NewsArticle->locale = 'fr';
$this->set('news_articles', $this->NewsArticle->findAll());
}
Changing $this->NewsArticle->locale to 'en' would fetch english
content.
It would probably be best to set this locale via a beforefilter in
this controller or the appcontroller for real use.
8. Basic view, nothing fancy (/views/news_articles/index.ctp):
----
<table>
<tr>
<th>ID:</th>
<th>Title / Content:</th>
</tr>
<?php foreach($news_articles as $article): ?>
<tr>
<td>
<?php echo $article['NewsArticle']['id']; ?>
</td>
<td>
<?php echo $article['NewsArticle']['title']; ?>
<br /><i><?php echo $article['NewsArticle']['content']; ?></i>
</td>
</tr>
<?php endforeach; ?>
</table>
The following issues need to be resolved for my project;
- The ability to fetch default data when the data is not available in
the database in the requested language. For example a news article is
not available in French so the English version would be fetched by the
model given English is the default language of the site.
- Some sort of indicator stating the requested language is not
available so a version in the default language is given.
Maybe this sort of functionality is already in Cake 1.2. If someone
knows something about this issue then this would be very helpful also.
Thanks,
Worked out a solution for;
> - The ability to fetch default data when the data is not available in
> the database in the requested language. For example a news article is
> not available in French so the English version would be fetched by the
> model given English is the default language of the site.
> - Some sort of indicator stating the requested language is not
> available so a version in the default language is given.
---
function beforeFilter(){
//set supported languages
$languages = array('en_US','fr_FR');
//set language preference if present in the url (?language=xx_XX)
if(isset($this->params['url']['language'])){
if (in_array($this->params['url']['language'],$languages)){
$this->NewsArticle->locale = $this->params['url']['language'];
}
else{
$this->NewsArticle->locale = 'en_US';
}
}
else{
$this->NewsArticle->locale = 'en_US';
}
}
function index(){
//get articles array in the requested language
$trans_art = $this->NewsArticle->findAll();
//get articles array in the default language
$this->NewsArticle->locale = 'en_US';
$def_art = $this->NewsArticle->findAll();
//build array of translated articles - array key is the id of the
article
foreach($trans_art as $artT){
$trans_art_list[$artT['NewsArticle']['id']] = $artT['NewsArticle'];
}
//replace articles not found in the requested language by articles
in the default language
//also set isLocale status - yes if the translation is there, no if
not
foreach($def_art as $art){
if(array_key_exists($art['NewsArticle']['id'],$trans_art_list)){
$trans_art_list[$art['NewsArticle']['id']]['isLocale'] = 'yes';
$artList[]['NewsArticle'] = $trans_art_list[$art['NewsArticle']
['id']];
}
else{
$art['NewsArticle']['isLocale'] = 'no';
$artList[]['NewsArticle'] = $art['NewsArticle'];
}
}
//set the combined array to the view
$this->set('news_articles', $artList);
$this->set('siteVars', $this->Conf->get('site.*'));
$this->set('title_for_layout', $this->Conf->get('site.name'));
}
-----
Short description:
- The beforeFilter get's the requested language or the default if not
given or invalid
- The index controller first get's every article in the default
language
- The index controller than get's every article in the requested
language (this array could be smaller)
- The index controller builds an array based in the default language.
- The index controller replaces records in the articles array for
every article where a translation is available
- Every article has a status variable indicating if the translation
was available or not (isLocale yes / no)
Next step would be to transfer this functionality to the model. In the
above example this functionality will be build into every controller
function. Something for the days to come...
....
来自: http://groups.google.com/group/cake-php/browse_thread/thread/889c63d32cfdf69
change language by manual way:
The correct way would be:
You can also use:
$language = 'deu';
$this->Session->write('Config.language', $language);
$language = 'deu';
Configure::write('Config.language', $language);