Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to handle locales with currencies and language switches

I'm working on a multilanguage project with Zend Framework (German and English) where I have a small form to order a product. The user should be able to:

  • Change his prefered currency for the product prices
  • Change his prefered language for the whole website

At the moment I use Zend_Locale::findLocale() to get the user's locale. With my browser settings I get 'de_CH' and that works well. But there are some problems as soon as:

  • The user has configured his browser to just give me the language code ('de' instead of 'de_CH')
  • The user prefers a language which is not supported by my website
  • The user is from a country where they got a currency which isn't supported by my product order form

Just the language code The language code is enough to handle Zend_Translate, but Zend_Currency needs more information. I think there is no solution to get the full locale with the country code from every possible user. My question is: how do you handle these situations? Do you check in your bootstrap's _initLocale() if a country code is missing and use a default country code? Are there any Zend Framework methods to do that?

An unsupported language If the users language is 'fr', I would like to use a default language because our website doesn't support french. Is there a better possibility than to add a whitelist array in bootstrap? For example a method from Zend_Translate?

An unsupported currency What if the user's language is supported, but not his currency? Should I change the locale in bootstrap or should I make a copy of the locale and change it for Zend_Currency?

The main problem I think my main problem is that I'm not sure how to handle all these different locale issues. My prefered approach would be to verify the locale set in bootstrap's _initLocale(), so I can be sure that I can support it's language and currency.

Thank you for your advises.

Best regards, Nico

Editing 1 I have made myself some more thoughts about a way to handle these issues. What do you think about this approach?

  1. Zend_Locale(): filter all short locales (without a country code) and uses a whitelist with the languages your application supports (just the language code). If there is no matching, use the default given by your application.
  2. Zend_Translate: start with the language code from the locale. But if the user changes the preferred language, leave the locale as it is (perhaps there is no matching locale based on the new language code and the old country code) and just change the language code in Zend_Translate.
  3. Zend_Currency: Use the locale as the default. If the user changes the preferred currency, just change the currency and not the locale. So the formatting would stay based on the old locale because the change of the currency doesn't mean the user also wants to change his locale.

Would this approach be acceptable? There is a problem with step 1 if the browsers locale are set like this:

  • de
  • en_US

Perhaps the application does support German, but because it is a short locale, the application will use en_US instead. But I don't know which solution would fix this problem, because I can't 'upgrade' a short locale to a full locale.

like image 484
Nico Avatar asked Dec 30 '10 14:12

Nico


1 Answers

The problem you highlighted is common and I imagine a small amount of work would be required to set the locale for your user.

de to de_DE requires you to know if they are located in Germany but this can default to de_CH which is your locality, if you do not know the users locality.

* The user has configured his browser to just give me the language code ('de' instead of 'de_CH')

Map this in your application. Your mapping can convert this to de_DE for residents in Germany that speak German. Or de_CH for residents in Switzerland that speak German. Or fr_CH for residents of Switzerland that speak French and so on for English speakers it would be en_CH or en_DE. So this solves 2 problems.

The users language and location are needed to determine the locale for the user accurately.

If you do not know there location you should default to your own default language and locality.

Link: Unicode - locality and language mapping

* The user prefers a language which is not supported by my website

You should have a default language and currency, if you are in Europe then the choice would be whatever is your default locality and language, if you are Swiss then de_CH makes sense.

* The user is from a country where they got a currency which isn't supported by my product order form

In this case you should revert to your default.

Zend has many examples of using Locales on their wiki. The most common place for setting locality in Zend is the bootstrap file.

I used this link to reference support for this response on Zend Framework wiki. The code below provides a small example of how the Zend_Locale class throws exceptions if the locale is invalid. You could check for location and language at this point, and use it in combination with the information you receive from the browser to accurately set locale for the user.

Link: Zend Locale Introduction

  // within the bootstrap file
  try {
      $locale = new Zend_Locale('auto');
  } catch (Zend_Locale_Exception $e) {
      $locale = new Zend_Locale('de');
  }
  // within your model/controller
  $date = new Zend_Date($locale);
  $currency = new Zend_Currency($locale)
like image 59
Tass Skoudros Avatar answered Oct 19 '22 23:10

Tass Skoudros