Recent Posts
- (09/10) Fixing Warning: the ECDSA host key for 'github.com' differs from the key for the IP addressTAGS:Web Server Admin
- (12/26) CakePHP 3 - Getting List of Column Definitions from a Table (like schema())TAGS:CakephpCake3
- (09/14) Change Order of Loaded Behaviors in CakePHP 3TAGS:Cake3CakephpWeb ProgrammingPhp
- (05/29) CakePHP 3 - Accept JSON Header Only Working When Debug FalseTAGS:Web ProgrammingCakephpCake3
- (05/23) Remove All Events from Google Calendar (Reset Calendar)TAGS:Web ProgrammingPhp
- (11/08) Google Tag Manager (GTM) Not Firing Default PageView EventTAGS:Web ProgrammingJavascriptGoogle Tag Manager
- (10/13) In PHP, how do you get __toString() Magic Method Result without calling echo?TAGS:CakephpCake3Cakephp 13PhpWeb Programming
- (11/14) Getting output from shell_exec() at all timesTAGS:Web ProgrammingWeb Server Admin
Subscribe to my feed
MainelyDesign.com Blog
CakePHP Translate Behavior - Lessons Learned
Posted on 12/15/2009 at 08:29 am by Kevin Wentworth
Viewed 34,776 times | 5 comments
I've been working on setting up a multi-lingual web site for one of my clients. I was excited at the opportunity to finally use CakePHP's built-in internationalization and locale functions. However, I ran into some issues that I'm sure other newbies to internationaliztion will run into as well. Here's some take-backs of what I learned while using the Translate Behavior in Cake...
(Author's Note: This posting is still a work in progress. I'm still implementing the translate behavior and have found quite a few work-arounds that I needed to implement. Over the next few days/weeks I'll be sharing more about Cakephp's translate behavior and how I wrangled it for my use. It looks like CakePHP will fix/implement several issues I've had with the translate behavior to date)
Only Simple Find Methods Return Translated Fields
This is important! At this moment (v 1.2.5), the Translate Behavior will only translate simple $model->find() calls. If you have a model that relates to a translated model, the related model will not be translated! After much research and reading, I've learned that it's due to the lack of support for beforeFind and afterFind calls in CakePHP related models/behaviors (see: ticket).
I did find a work-around, that I recommend for anyone needing to use related models with translated fields at this time.
Less Configuration is Better
With the translate behavior, the less you configure it the better. I got really confused at first by attempting to return ALL the translations using the bindTranslation() method (actually, I set the behavior to return all translations). I did this because I was building the back-end first, but wasted a lot of time thinking things weren't working right. The other area that got me into trouble was setting the locales manually using $this->Model->locale instead of the Config.language setting.
To recap, if you have the i18n table populated with data in the current locale, when you do any type of DB find, the fields will be automagically re-mapped to have the right translation in the find results. With no intervention (or configuration) you'll end up with just what you wanted- translated fields in the "find" data array.
$this->Model->locale Value Changes Translate Behavior Results
You wouldn't think it would change things too much, but how you specify languages via $this->Model->locale changes the results and behavior of Translate. I recommend not setting the locale this way, it's too confusing and abnormal.
Setting it to a string works as expected (i.e. normal). However if you set locale to an array() then things change:
- $this->Model->locale = 'en-us'
- Returns false if translation doesn't exist
- $this->Model->locale = array('en-us'); //or array('en-us', 'de-de', '3-rd');
- DOESN'T RETURN FALSE if en-us doesn't exist (instead returns default Config.language)
- returns what's in the model table... does no translation even if it exists
- effectively shuts off translate behavior
Locale and Language are Different
This one got me good. I kept trying to set the default language to German in my CakePHP app using Config::write('Config.language', 'de_de'); It wasn't working and the en_us locale kept getting returned. Well, as it turns out, you actually need to set your languages using HYPHENS not UNDERSCORES!
Once I began using de-de (not de_de) everything worked like a charm. I still don't know all the details of the locale vs. language. I now at least have a reference point: l10n class (look at var $__l10nCatalog definition).
What Do You Use for Abbreviations/Codes for Locales?
For English (American) as the locale, I was using en_us. (Not to be confused with the language identifier of en-us) However, I see 'eng' all over the web. What locale do you use? It looks like 'eng' is mapped to 'en' anyway, so I'm not sure why the localeFallback isn't just en? RESEARCH AND FIGURE THIS OUT
Array Format for Saving Multiple Languages at Once
You can change the $this->Model->locale setting and then save your translation, however you can avoid changing the $model->locale (see above) by using the following array format:
Tags for CakePHP Translate Behavior - Lessons Learned
Web Programming | Cakephp | Usage | Php | Mysql
Comments for this Posting
Posted by Rich
on 23/5/10
RE: Array Format for Saving Multiple Languages at Once
I can't see the code sample, has it been removed?
This is exactly the information I am afterr as I want to build a CMS with tabs for each locale containing the translated model fields - saving the data all at once instead of one locale at a time.
Posted by Lapinski
on 8/8/10
Locale and language are different, but not by - and _ : en-us or en_us both implies en as language and us as locale. Check out ISO 3166 for country codes and ISO 639-2 and 639-3 for language codes, and that's why the mapping between en and eng for English.
Posted by José
on 8/4/11
I'm very curious about the array format for saving many translations at once, it seems it didn't appear in your blog, can you email me with it please??
Sorry, comments are closed for this posting.
Please Email Kevin if you have any questions. Thanks!
Posted by Nicolas
on 21/1/10
Thanks for this article and the link to the workaround! It worked perfectly for me :)