Achieving Multilingual User Interface

On November 14, 2017, we turned on the Multilingual feature for www.yorubaname.com, making it possible to view the content of the website not only in English but also in the Yorùbá language.

If you visit the Dictionary now, at the top right corner, you will find the language switch button.

This language switcher allows a user to toggle the language in which the content of the website is displayed. Right now, English and Yorùbá are supported. Clicking on YOR would switch the website’s’ language to Yorùbá.

Multilingual capabilities have always been a feature we planned for the YorùbáName dictionary. It was not an afterthought; we knew at the very beginning when we started working on the codebase for the YorùbáName dictionary, that we would like to support multiple languages.

Even though it was not going to be possible to have multilingual at launch, we made sure, the technical infrastructure to easily support multiple languages was in place. So that when the time came, it was easy to add another language, since the technical foundation that was needed has already been laid.

In this post, I will quickly give a broad overview of the technical aspect that enabled us to easily support a multilingual user interface. I will also mention the things we still need to do.

The Building Blocks

The YorùbáName website is built using Spring boot, which makes it easy to quickly hit the ground running when developing applications with the Spring Framework.

One of the advantages of having a framework like Spring at your disposal is the fact that there are already implementations for a lot of the supporting features, outside the business logic that is needed by a non-trivial web application.

So when it came to building the multi-lingual support into the YorùbáName website, it was a matter of assembling the necessary components and configuring them to taste, rather than having to develop the necessary moving parts that would be required for such a feature from scratch.

Spring framework provides 3 main components that were used to achieve our aim. But before I touch on them, let us imagine we need to build multi-lingual support into an application, but without the support of Spring. What would this entail? What are the things I might have to develop?

I can imagine I would have to build something that allows the user to select the language they are interested in. Then provide the mechanism that communicates the selected language to the rendering part of the application. Maybe using sessions, the URL, HTTP headers, cookies etc.

I would then need to make sure the rendering part of my application is built in such a way it can resolve to different texts depending on the selected language.

And all these would need to be built with user isolation in mind, so as to prevent one user’s language selection from interfering with the selection made by any of the other users visiting the web application.

These can be roughly grouped into recognizing language selected, rendering the content of the site in the selected language, and provide a per-user mechanism for switching language.

These stated capabilities are already available with Spring, and I now briefly explain what they are and how they were configured.

LocaleResolver

When a request is made, the LocaleResolver is the component responsible for determining which language is to be used when responding to the request. There are various places the LocaleResolver can look for in other to accomplish its task. These include the accept-language header in an HTTP request, the session or in the cookie.

The implementation we went with, uses the cookie.

So depending on a specific value set within the request cookie, the right language is used when constructing the response to be sent back to the user

The configuration looks like:

@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(Locale.ENGLISH);
cookieLocaleResolver.setCookieName(LANG);
return cookieLocaleResolver;
}
MessageSource

The messageSource is the component that helps in defining and grouping the translations for each language to be supported. As can be gleaned from the name, it provides the source for all of the text translation and makes it available depending on the language required.

So while the LocaleResolver component helps determine the language, the MessageSource helps in providing the translations for that language.

We are using property files as the mechanism for providing the language translations. You can see these files here

The MessageSource makes use of these property files to supply the required translations.

The configuration looks like:

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
source.setDefaultEncoding("UTF-8");
source.setBasename("classpath:/messages");
return source;
}
LocaleChangeInterceptor

Last but not the least is the LocalChangeInterceptor, which is the component that makes it possible to manually switch the current language as needed.

Since the LocalResolver mechanism uses cookies to convey the preferred language, the LocalChangeInterceptor updates the cookie value depending on the language selected.

This is the component that makes it possible to switch the language by clicking on the language selector.

The configuration looks like:

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName(LANG);
return lci;
}
// and then registered as an interceptor

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

For more on how things stack together on the code side of things, you can take a look at the Spring context configuration here

The Road Ahead

The work still needed to be done around internationalization and localization can be grouped into supporting more languages and providing a more exhaustive translation.

Support more languages. It is good to have the website in Yorùbá, but it would be better if we can add more Nigerian languages. This obviously needs the manpower needed to provide the translations. So if you are interested in helping make the YorùbáName dictionary available in another language, please do get in touch. :).

Please send an email to volunteer@yorubaname.com with “Translate” in the subject line.

Providing An Exhaustive Translation. As can be seen, not every single content on the website has been translated. Apart from this, the meaning of the names in the dictionary is still only in English.

We would like to improve on this, but it would require some extra work: from rethinking the data model used to store the names to providing the necessary tools that would support the lexicographers in managing the meaning of names in multiple languages. These are technical challenges, and tackling them won’t be trivial, but it sure promises to be fun. For example, instead of depending on static language translation files, what stops us from writing a custom implementation of the MessageSource interface to use the google translation API?

All of these are on our radar, and in due time, they would be worked on. So, if you are a developer and you are interested in helping out with the technical side of things, feel free to get in touch also 🙂

But in the meantime, as at now, do enjoy YorubaName.com in Yorùbá!