Play with the user language

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:

sfFormExtraPlugin form

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).

Comments

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" ?

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.