Do you want to detect the language of the user visiting your website? This is a really useful function for automatically setting the locale of your Laravel application.
Add the following to your base controller's public function __construct()
. This will make sure that it loads for every page. However, please be aware that if you overwrite the __construct()
in your own controllers that you will have to refer to the base controller's function by using parent::__construct()
.
App\Http\Controllers\Controller
public function __construct()
{
if(Session::has('locale'))
{
Config::set('app.locale', Session::get('locale', 'en'));
}
else
{
Config::set('app.locale', getBrowserLocale());
}
}
You will need to add a helper function to get the user's locale.
Please note that you can add the locales that your website accepts in the array $websiteLanguages
helpers.php
function getBrowserLocale()
{
// Credit: https://gist.github.com/Xeoncross/dc2ebf017676ae946082
$websiteLanguages = ['EN', 'JA', 'NL'];
// Parse the Accept-Language according to:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
preg_match_all(
'/([a-z]{1,8})' . // M1 - First part of language e.g en
'(-[a-z]{1,8})*\s*' . // M2 -other parts of language e.g -us
// Optional quality factor M3 ;q=, M4 - Quality Factor
'(;\s*q\s*=\s*((1(\.0{0,3}))|(0(\.[0-9]{0,3}))))?/i',
$_SERVER['HTTP_ACCEPT_LANGUAGE'],
$langParse);
$langs = $langParse[1]; // M1 - First part of language
$quals = $langParse[4]; // M4 - Quality Factor
$numLanguages = count($langs);
$langArr = array();
for ($num = 0; $num < $numLanguages; $num++)
{
$newLang = strtoupper($langs[$num]);
$newQual = isset($quals[$num]) ?
(empty($quals[$num]) ? 1.0 : floatval($quals[$num])) : 0.0;
// Choose whether to upgrade or set the quality factor for the
// primary language.
$langArr[$newLang] = (isset($langArr[$newLang])) ?
max($langArr[$newLang], $newQual) : $newQual;
}
// sort list based on value
// langArr will now be an array like: array('EN' => 1, 'ES' => 0.5)
arsort($langArr, SORT_NUMERIC);
// The languages the client accepts in order of preference.
$acceptedLanguages = array_keys($langArr);
// Set the most preferred language that we have a translation for.
foreach ($acceptedLanguages as $preferredLanguage)
{
if (in_array($preferredLanguage, $websiteLanguages))
{
$_SESSION['lang'] = $preferredLanguage;
return strtolower($preferredLanguage);
}
}
}
You can create a controller to manage the switching of languages.
App\Http\Controllers\Controller\LocaleController
namespace App\Http\Controllers;
use Redirect;
use Session;
use App\Http\Controllers\Controller;
class LocaleController extends Controller
{
/**
* Switch the locale of the website into English.
*
* @return Redirect
*/
public function english()
{
Session::put('locale', 'en');
return Redirect::back();
}
/**
* Switch the locale of the website into Japanese.
*
* @return Redirect
*/
public function japanese()
{
Session::put('locale', 'ja');
return Redirect::back();
}
/**
* Switch the locale of the website into Dutch.
*
* @return Redirect
*/
public function dutch()
{
Session::put('locale', 'nl');
return Redirect::back();
}
}
Don't forget to add the routes to handle the switching.
routes.php
Route::get('en', ['as' => 'locale.english', 'uses' => 'LocaleController@english']);
Route::get('ja', ['as' => 'locale.japanese', 'uses' => 'LocaleController@japanese']);
Route::get('nl', ['as' => 'locale.dutch', 'uses' => 'LocaleController@dutch']);
Some ideas may be to pass the $websiteLanguages
to the function as an arguement and store the acceptable languages in a config variable. You could also have the function scan which locale folders exist in your application.
Now that was easy! This code has been tested on Laravel 5.1
Comments
Christian Weiske 2018-07-23 13:29:20
The symfony http-foundation class "Symfony\Component\HttpFoundation\Request" used by Laravel has a "getPreferredLanguage()" method that implements your "getBrowserLocale()" code already.
Bryse Meijer 2019-05-05 04:45:34
Thanks for the tip Christian Weiske!
Simone 2019-09-05 15:56:28
Thank you very much! :)