In this post, I am going to show you how to enable site wide settings for the Language Portlet, so you can add the portlet to your header or footer without having to edit the settings for each and every page.

The Problem

In Liferay, the Language Portlet uses a different set of settings for every page.  This is fine if you have the Portlet added to only one page on your site. However, if you need it on multiple pages, like on the header or footer, you will need the settings set the same for every page.

languageConfig

Default Settings popup for the Language Portlet. Be careful, these are different for every page!

The Solution

I found the simplest solution for this issue is to create a jsp hook and pull the settings from portal-ext.properties, instead of the portlet’s config screen. Of course, the one disadvantage to this approach, is that you need to restart Liferay whenever you make a change. However, I don’t see this as a big issue because changing available languages and display styles is usually not done frequently.

Embedding the Language Portlet inside your theme

Inside portal_normal.ftl, assuming you are using velocity, add this snippet where you want the Language Portlet displayed:

${theme.runtime("82")}

Override JSP files using a hook

This is very simple, because you only need to touch two files, which are located in webappsROOThtmlportletlanguage.

You need only to override the configuration.jsp and init.jsp files using a hook. Note: do not change these files directly. Make sure you use a hook.

configuration.jsp:

The  code in this file should be completely commented out, so it does not confuse anyone who tries to use it later. I added this reminder note at the top of the file which is displayed if the admin user clicks the config link on the portlet topper:

Note: This config screen is now obsolete, due to the language-hook.
The settings for supportedLocales, displayStyle and displayCurrentLocale are now pulled from
portal-ext.properties.

Everything else in the file must be commented out.

init.jsp:

You want to comment out the lines that set the languageIds, displayCurrentLocale, and displayStyle and get those values from portal-ext.properties instead. Here is a before and after shot of that file:
Before:

Locale[] availableLocales = LanguageUtil.getAvailableLocales(themeDisplay.getSiteGroupId());
String[] availableLanguageIds = LocaleUtil.toLanguageIds(availableLocales);
String[] languageIds = StringUtil.split(portletPreferences.getValue("languageIds", StringUtil.merge(availableLanguageIds)));
boolean displayCurrentLocale = GetterUtil.getBoolean(portletPreferences.getValue("displayCurrentLocale", null), true);
int displayStyle = GetterUtil.getInteger(portletPreferences.getValue("displayStyle", StringPool.BLANK));

After:


Locale[] availableLocales = LanguageUtil.getAvailableLocales(themeDisplay.getSiteGroupId());
String[] availableLanguageIds = LocaleUtil.toLanguageIds(availableLocales);
/*------------------------------------------------------------------
The following lines are commented out, because we want to get all settings from
one place in order to make them the same across the entire instance.
String[] languageIds = StringUtil.split(portletPreferences.getValue("languageIds", StringUtil.merge(availableLanguageIds)));
boolean displayCurrentLocale = GetterUtil.getBoolean(portletPreferences.getValue("displayCurrentLocale", null), true);
int displayStyle = GetterUtil.getInteger(portletPreferences.getValue("displayStyle", StringPool.BLANK));
------------------------------------------------------------------*/
int displayStyle = Integer.parseInt(PropsUtil.get("languagePortlet.displayStyle"));
boolean displayCurrentLocale = Boolean.parseBoolean(PropsUtil.get("languagePortlet.displayCurrentLocale"));
String[] languageIds = StringUtil.split(PropsUtil.get("locales.enabled"));

portal-ext.properties:


# FYI: locales.enabled is a default property, but it is also being used for the custom language-hook
locales.enabled=en_US,ja_JP
# displayStyle:
# 0=Icon
# 1=Long Text
# 2=Short Text
# 3=Select Box
languagePortlet.displayStyle=2
languagePortlet.displayCurrentLocale=true

Wrapup

Once you start Liferay and deploy the hook, you will no longer need the default config screen. All instances of your portlet will use the exact same settings.

Enjoy!