Why a locale sometimes is not enough in Laravel.

Why a locale sometimes is not enough in Laravel.

It’s always important to let your users feel welcome and appreciated. When you‘re creating apps that need to be scaled globally, that can be a challenge sometimes. Lucky for us, Laravel introduced “Using Translation Strings As Keys” a while ago which makes our code readable again in opposition to the “short key” translations we had to use before.

But still, there are a few challenges when it comes to localization. Translation is not the only concern. In this post, I will try to explain and also give the solution we’re using at Involved Group (we made this package public available). I’ll try to illustrate with some examples of a dashboard app. Typically these kinds of apps don’t use localization preferences in the URL’s and need some other input to set the Laravel locale settings.

Challenge 1: ‘Country’ !== ‘Language’

Let’s tell you our story how this ball got rolling in our development. In Belgium, there are two spoken languages: French and Dutch (Flemish). We were serving many languages in our app, the Belgium users were able to select either the Dutch or the French flag in the language selector. Problem solved, right? No! Our Belgium users complained that there was a Dutch flag on their account while they were Belgian users. Remember that our goal as developers should be to make our users feel welcome and appreciated? These clients really had a fair point. How could we solve this through out-of-the-box Laravel? We could create two more translation .json files like nl-BE.json and fr-BE.json and then set the Laravel Locale to either _nl-BE_ or fr-BE. The downside of this approach is that we need to have these .json files created and translated while the content will be exactly the same as the nl.json and fr.json files. This is will result in maintenance mess and is not an option for us.

Challenge 2: Date formats are defined by the country, not the language.

We’ve been using the awesome Date package in our apps. It’s always one of the first dependencies we’re adding for almost every new project. It is like a translation wrapper around Carbon, if you’ve never used it, give it a try! One of the problems we encounter is that we now have the ability to translate the date, but not automatically format the date according to the country’s preferences.

Example

We’ve established the Belgian/Dutch differences already, but let’s take this a step further. In The Netherlands, the date will be typically written like d-m-Y, in Belgium the format d/m/Y is more common and in Germany d.m.Y. Small difference, but it’s just the small things that matter to make a user feel comfortable with the app he or she is using. A bigger difference is when we would like to spell out the date in full text. In the Netherlands this would default to l j F Y (dinsdag 24 april 2018) while in the US this would be l F jS Y (Tuesday April 24th 2018).

The solution

We’ve created a package that can help you. We’ll not go too much in detail, you can read the rest on the github page or in the code.

A middleware for all page visits will be set. When no user (with lang_country preference) is detected, we’ll try to make a perfect match between the browser language preferences and the allowed language/countries in the config file. The lang_country variable will be stored in a session.

The user can change the lang_country variable through the language/country selector (the package will provide a nice helper for this).

The lang_country variable will match a .json file in the package which stores all the applicable settings for this lang_country. The middleware will set the right locale for Laravel for the translation and also the right locale for the Date package.

You’ll be responsible for the right language .json files in the /resources/lang directory. But you’re able to create different files for certain language/country combinations if you need this. We’ll make a smart check on that. So if your lang_country variable is es-CO we will check if this file is present: /resources/lang/es-CO.json. If so, we’ll set the Laravel Locale to es-CO so this file is used. If not, we’ll set the Laravel Locale to ‘es’ so the /resources/lang/es.json is used.

When we need nice date format string we can use:

\LangCountry::dateWordsWithDay($blog->post->created_at);

in our code. Now, every user will see a date format which is comfortable for them.

The package does more:

  • We’ll store the lang_locale preference in the User record of the database if you want this.
  • It provides a helper to make a simple language/country switcher dropdown. The LangCountry Facade has a lot of helpers, check it out!

I’m pretty sure your opinion about this can differ, that’s cool! But if you’re on the same page as us, take a look at our package and save yourself some time!