pethel
pethel

Reputation: 5537

Get locale in freemarker template

How can I get the current locale used in a freemarker template? I have seen implementation of <spring.message code />

I need this to do a conditional

<#if locale = DE >
.....
<#else>
....
</#if>

Upvotes: 6

Views: 8322

Answers (2)

Alexander
Alexander

Reputation: 3035

@Rob Blake's answer is technically correct, but still I'd like to add some thoughts...

1. Other locale-related variables
There's not just .locale, but also .lang and since FreeMarker 2.3.21 also .locale_object, which provides the actual java.lang.Locale object (not just Strings).

See Freemarker Special Variable Reference for more information.

2. Difference between request's locale and locale in RequestContext
In some cases, the Locale provided by Freemarker is not the same as the Locale that you use.

In my case, I have a Freemarker Spring Boot Application with a LocaleChangeInterceptor, which allows you to set your own locale (e.g. in the session), so that the user can switch language when you use <@spring.message /> to render the texts in different languages.

This code snippet is inspired by this baeldung.com Spring Boot I18N tutorial:

@Configuration
public class McvConfiguration extends WebMvcConfigurerAdapter {

  @Bean
  public LocaleResolver localeResolver() {
    return new SessionLocaleResolver();         
  }

  @Bean
  public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
    lci.setParamName("lang");
    return lci;
  }

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
  }

}

In this case after the Locale has been changed, the locale provided by Freemarker (i.e. ${.locale}, ${.lang} and ${.locale_object}) and the Locale in the RequestContext (i.e. the Locale that is used for <@spring.message /> for example) differ!

In this case, you should read the Locale from the RequestContext instead.

Configuration class

  @Bean
  public ViewResolver viewResolver() {
    final UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); // or TilesViewResolver or whatever
    // make requestContext available for Freemarker templates as "${rc}"
    viewResolver.setRequestContextAttribute("rc");
    return viewResolver;
  }

See also SO - How to get the request context in a freemaker template in spring

Freemarker template

<#-- @ftlvariable name="rc" type="org.springframework.web.servlet.support.RequestContext" -->
<!DOCTYPE html>
<html lang="${rc.locale.language!"en"}">
<!-- ... -->
</html>

So when you hit http://<serverName>:<serverPort>/<contextPath>/index?lang=en or http://<serverName>:<serverPort>/<contextPath>/index?lang=de or http://<serverName>:<serverPort>/<contextPath>/index?lang=fr, or whatever languages you application supports, the <html> tag's lang attribute will match the language from the <@spring.message/> localized texts.

Upvotes: 0

Rob Lockwood-Blake
Rob Lockwood-Blake

Reputation: 5056

As stated by the Freemarker documentation:

Special variables are variables defined by the FreeMarker engine itself. To access them, you use the .variable_name syntax

.locale: Returns the current value of the locale setting. This is a string, for example en_US. For more information about locale strings see the setting directive.

So to access the current local within a Freemarker template you would use

The current locale is: ${.locale}

To use it in a conditional statement as per your requirements, you would do:

<#if .locale == "DE">
   ...
<#else>
   ...
</#if>

Upvotes: 8

Related Questions