Tagged: i18n
[Grails] i18n: LocaleResolver, Accept-Language
Warning!!! I made plugin grails-locale-configuration-plugin that replace this solution. [Grails] Сегодня опубликовал стабильную версию grails-locale-configuration-plugin
Also this chapter of book may be interest for you
В каждом броузере пользователь может настроить предпочтительные языки. Например в хроме Settings / Languages (chrome://settings/languages) они выглядят так:
Тут указано что пользователь хочет видеть американский английский, или любой английский, но если его не будет тогда на русском, а если и на русском не будет, тогда давайте уже на украинском.
Эти параметры передаются в каждом запросе на сервер через заголовок Accept-Language:
Accept-Language:en-US,en;q=0.8,ru;q=0.6,uk;q=0.4С помощью параметра
q
(quality value) мы передаём приоритет от 0 до 1.Grails умеет работать с этим заголовком и автоматически переключать локаль. Если есть интернационализация для этого языка то она сразу же автоматически показывается и всё хорошо. А вот если не находится i18n/messages_xx.properties для нужной локали, тогда отображается текст по умолчанию из i18n/messages.properties, обычно английский.
Хоть текст и будет английский, но системная локаль будет установлена в ту которую пользователь запросил больше всего.
Например, у нас есть пользователь у которого украинский язык на первом месте и русский на втором.
Запросив страницу Grails запомнит украинскую локаль в сессии, но отобразит всё на английском.
Это не всегда хорошо, особенно если ваш сайт жёстко поддерживает только несколько локалей. Например в зависимости от локали вы разные флажки отображаете.
Скорее всего что захотите ограничить локали которые поддерживаете.
Для этого создайте в файле Config.groovy опцию supportedLocales:supportedLocales = [Locale.ENGLISH, new Locale('RU')]А теперь создадим фильтр который будет проверять локаль
class LocaleResolverFilterFilters { def filters = { all(controller: '*', action: '*') { before = { // Сначала ищем такую же локаль, если не нашли то локаль с тем же языком, если не нашли то по умолчанию английский Locale selectedLocale LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request) List<Locale> supportedLocales = grailsApplication.config.supportedLocales if (request.locale in supportedLocales) { selectedLocale = request.locale } else { selectedLocale = findLocaleWithSameLanguage(request, supportedLocales) } selectedLocale = selectedLocale ?: Locale.ENGLISH localeResolver.setLocale(request, response, selectedLocale) } } } private Locale findLocaleWithSameLanguage(HttpServletRequest request, List<Locale> supportedLocales) { supportedLocales.find({ it.language == request.locale.language }) } }В дальнейшем из кода получить локаль мы можем через объект запроса
request.locale
а список всех локалей предпочитаемых пользователем черезrequest.locales
.
Ту локаль с которой мы отрисовали страницу можно увидеть через объект ответа:response.locale
.
Смотрите демо приложение на гитхабе.Что ещё почитать по теме: