I have already talked about the sfFormExtraPlugin
in a previous post and
people were quite amazed by some widgets provided by the plugin.
Today, I will talk about sfFormLanguage
, a form also provided by the
sfFormExtraPlugin
plugin.
Let the user change his language
sfFormLanguage
allows the user to change his current language:
To create a sfFormLanguage
form, you need to pass the symfony user object (sfUser
)
and an array of supported languages:
class mainActions extends sfActions { public function executeChangeLanguage($request) { $this->form = new sfFormLanguage($this->getUser(), array('languages' => array('en', 'fr'))); } }
The related template is quite straightforward:
<form action="<?php echo url_for('@change_language') ?>" method="post"> <label for="language">Choose a language:</label> <?php echo $form['language'] ?> <?php echo $form->renderHiddenFields() ?> <input type="submit" value="ok"> </form>
When the user submits the form (post
), we need to process it:
class mainActions extends sfActions { public function executeChangeLanguage($request) { $this->form = new sfFormLanguage($this->getUser(), array('languages' => array('en', 'fr'))); if ($request->isMethod('post')) { $this->form->process($request); return $this->redirect('@homepage'); } } }
The sfFormLanguage::process()
method takes the current request as a parameter,
binds the form with the data provided in the request, validates the form, and if the form is
valid, automatically changes the user culture.
The above code does not manage form errors because it can't really happen, except if
the user fakes the select values. In such a case, we don't really care if an error is displayed or not.
But if you want to, the process()
method returns true
if the culture has been
changed and false
otherwise (if there was an error during validation for example):
class mainActions extends sfActions { public function executeChangeLanguage($request) { $this->form = new sfFormLanguage($this->getUser(), array('languages' => array('en', 'fr'))); if ($this->form->process($request)) { // culture has been changed return $this->redirect('@homepage'); } // the form is not valid (can't happen... but you never know) return $this->redirect('@homepage'); } }
sfFormLanguage
is simple to use and very useful for internationalized website.
How to guess the language of the user?
When a user comes to your website for the first time, it is sometimes desirable to display the homepage
in her "preferred" language. The symfony request
object provides a getPreferredCulture()
method
that does the work for you. So, it is just a matter of changing the current user culture by the
preferred one:
$user->setCulture($request->getPreferredCulture(array('en', 'fr')));
The getPreferredCulture()
method takes an array of ordered cultures you support on your website.
It guesses the best culture possible, based on the HTTP_ACCEPT_LANGUAGE
HTTP header. It returns
the fist match between the HTTP header and your array of languages.
If there is no match, the method returns the first supported culture (en
in this example).
Yet Another Great Feature
It is half of october gone, I'm going nevrouse, waiting for the ver 1.2 ;)
Wow! It seems very usefull and complete!
I am curious about the multilanguage support at database level. For example if I want to support different languages for every text entity in the database. If that's the case, it would be usefull to have redirect('@current_page') insted of redirect('@homepage').
Sounds great indeed, will the switch also enable the switching of the Locales? That would be quite sensible I think.
For me, language and culture are different.
Language: fr Culture: fr_CH
If i use fr in culture, the numeric are comma. In Switzerland, the delimiter is point (.).
How to manage it properly?
@Garfield-fr: I don't understand the problem. You can pass cultures if you want (like fr_CH or fr_BE). And the good news is that the browser also gives you cultures in the ACCEPT_LANGUAGE HTTP header.
Is there a way to display the language choice in the language culture "english, francais" and not "english, french" ?