Switching locale on the login page
Overview
Spring provides ways to change the display locale. This documentation describe how to change it via an URL query string parameter and how to persist it with cookie or in session. This method may or may not work in any particular Spring version.
The configurations below can be placed in conf/global.xml
General Configuration
URL query string based locale changing
To change locale via an URL query string parameter you have to define two beans: a LocaleChangeInterceptor that will inspect request parameters and a LocaleResolver that will remember the locale change - use either CookieLocaleResolver or SessionLocaleResolver - see below (the present-by-default AcceptHeaderLocaleResolver does not allow locale changes).
LocaleChangeInterceptor configuration
You also need to add the mvc XML namespace to conf/global.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
[...]
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="[...]
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
[...]"
[...]
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
</mvc:interceptors>
Here we enabled changing locale based on the URL query string parameter lang
.
Cookie locale persistence
Enabling locale change persistence via a cookie is done by defining CookieLocaleResolver bean and optionally changing it's defaults:
CookieLocaleResolver configuration
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="lang"/>
</bean>
Here we changed the cookiename to be lang
instead. Now you can set a cookie called lang
to be any locale your IDP supports, e.g. en_GB
. This can be done via Javascript e.g. or use LocaleChangeInterceptor below.
Session locale persistence
Enabling locale change persistence via a session is done by defining SessionLocaleResolver bean and optionally changing it's defaults:
SessionLocaleResolver configuration
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
Change the value to your primary/default language code - ie. fr, de etc.
Messages files
The standard internationalization requires to have at least one messages_<lang>.properties file in the <idp_home>/messages/ directory.
You need to place your local strings into this file - ie. messasges_fr.properties
idp.title = Service de connexion
and optionally customize the messages.properties file - ie
idp.title = 'Login service'
From the templates you can call #springMessageText('key', 'Default value') macro - ie:
#set ($title = "#springMessageText('idp.title', 'Web Login Service')")
Lookup flow
When ‘fr’ language code is selected (or set as default) - the message for idp.title key is constructed as follows:
Lookup key in messages_fr.properties and return the value (“Service de connexion“) - else:
Lookup key in messages.properties and return the value (“Login service“) - else:
Return the default value - “Web Login Service“
Troubleshooting
If your IDP does not behave as described above - ie it looks like the language switching is not working and you always get you locale strings only - you can check the following.
Symptoms
Locale value from view(s) URL(s) is being properly intercepted and stored in either cookie or session depending on the localeResolver configuration. When using the cookie locale resolver - cookie is set and the value changes correctly.
Velocity templates can access correct locale value:
#set ($locale = $springMacroRequestContext.getLocale())
$rpUIContext properties - ie. serviceName, organizationName, getServiceDescription() - are being translated properly according to selected locale.
#springMessageText macro and other $springMacroRequestContext.getMessage() calls always return values from the messages_lang.properties file
Only when you create messages_en.properties and put ie idp.title = Login service there - the value for ‘en’ locale gets selected - otherwise it always fallback as in 4.
This means that the application fallbacks to a default locale - which might happen to be your system locale and it might match your translation messages file.
Resolution
To restore the expected behaviour as described in Lookup flow - you need to update your conf/global.xml and set fallbackToSystemLocale
to false
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- Set the base name of the messages.properties file -->
<property name="basename" value="%{idp.home}/messages/messages"/>
<!-- Set the encoding to UTF-8 (or your preferred encoding) -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- Enable or disable fallback to the system locale -->
<property name="fallbackToSystemLocale" value="false"/>
<!-- Set cache timeout (in milliseconds) for how often to check for file changes
- good for tunning the localization -->
<!--
<property name="cacheMillis" value="10000"/> --><!-- 10 seconds -->
</bean>
Reference
See Spring documentation for: