0

A user can change the language manually from the website. But for better user experience, I would like to change it automatically based on the users' browser language. I have a global Controller and can use init() and then redirect.

Please give me tips to do it right.

Pankaj
  • 698
  • 9
  • 21
  • Possible duplicate, see https://stackoverflow.com/questions/27233350/yii2-make-hyperlink-to-toggle-between-languages?rq=1 – lubosdz Feb 28 '19 at 17:21

1 Answers1

-1

You should remember the chosen language for a user, if they had selected one previously, I store this in the database, in a user_preference table.

Then you need to intercept the request, it can be done in the application configuration file, using the on beforeRequest property.

If you don't have stored a preference for the current user, or the user is a guest, use the browser language to set the application language.

Configuration file

use app\models\User;

...

'on beforeRequest' => function ($event) {

    $user_lang = '';

    if (!Yii::$app->user->isGuest) {

        // Check if you have stored a language preference for the user
        $user_lang = User::findIdentity(Yii::$app->user->id)->getUserPreference('lang');

    }

    if (!empty($user_lang)) {

        // If you have a stored preference for the user, use it
        Yii::$app->language = $user_lang;

    } else {

        // If you don't have a preference, use the browser language
        // Get the browser language from the headers
        $browser_lang = Yii::$app->request->headers->get('accept-language');

        // Alternatively get the headers from the event
        // $event->sender->request->headers->get('accept-language')

        // Calculate the language you want to provide based on the browser language
        $language_code = LanguageHelper::calculatei18nCode($browser_lang);

        Yii::$app->language = $language_code;

    }
},
...

If you wanted to keep your configuration file clean, you could use filters instead to intercept the request.

Your LanguageHelper::calculatei18nCode($browser_lang) method would try to find a match for the browser language in the available languages, if it didn't find one it could return the closest match, or the default application language.

LanguageHelper

public static function calculatei18nCode ($browser_lang) {

    // For example, if you are offering one translation file for french
    if (stripos($browser_lang, 'fr')) {
        return 'fr';
    }

    ...

    return 'en';
}
Raul Sauco
  • 2,645
  • 3
  • 19
  • 22
  • this is not correct way, as this code is run before request, meaning `isGuest` would always be false, as request is not parsed yet. If done `afterRequest` then it might work. Please update – dzona Feb 22 '22 at 19:48