RE: Custom Language-Selection Liferay 7 Theme

Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
Hey Guys,

i want to create a custom Language-Selection in my custom Liferay-Theme (Version 7, Freemarker)

My Idea was : looping over all available Languages and echo theme out in some <a href="${language-link}">${language-text}</a> Tags.

I already tried some versions of the following:

in init.ftl

&lt;#assign languages = languageUtil.getAvailableLocales() /&gt;


in header.ftl

&lt;#list languages as language&gt;
    <a href="/language.getLanguage()theme_display.getURLCurrent()">
        language.getDisplayName()
    </a>
 <!--#list-->


My first Problem is that the assignment to the Variable "languages" is not working. The Variable is always null or missing.

Can you help me how i can get access to all available languages that are available in a custom Liferay 7 Freemarker Theme?

Thank you!
thumbnail
Fernando Fernandez, modified 7 Years ago. Expert Posts: 401 Join Date: 8/22/07 Recent Posts
Jan Wallitschek:
i want to create a custom Language-Selection in my custom Liferay-Theme (Version 7, Freemarker)


Hi Jan,

I'm not sure what your requirements are but I think you could consider reusing the language selector portlet and maybe embed it on your theme.

That way you'd avoid the work of redoing the language selection logic that's already available.

HTH

Fernando
Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
Hi Fernando,

thank you for the quick reply.
I already considered reusing the language selector portlet but i cant find any useful informations on how to adjust the look and feel of that portlet.

Requirements : I need to display only the language-keys (EN | DE | HU | RO) and want to adjust some styling to it with css.

Is that possible? If yes, could you provide me some informations on how to do this?

Thank you very much!
thumbnail
Shahbaz Khan, modified 7 Years ago. Junior Member Posts: 40 Join Date: 11/18/14 Recent Posts
Hi Jan,

Just use themeDisplay.getLocale() in your theme and change css according locale id.

Hope this will work for you.
Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
Hi Shahbaz,

thank you for replying. themeDisplay.getLocale() will give me the current locale.

But i want alle locales that i have configured in the backend/admin-settings.

Do you know a way of doing it?

Thank you!
Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
I just tried something like that:


&lt;#assign VOID = freeMarkerPortletPreferences.setValue("displayStyle", "1")&gt;

&lt;@liferay.languages default_preferences="${freeMarkerPortletPreferences}" /&gt;

&lt;#assign VOID = freeMarkerPortletPreferences.reset()&gt;


I hope that i can change the displayStyle-Preference to something valid, that only displays the language text. (Tried 1,2,3, etc.)
But I cannot find any documentation on this.
thumbnail
Shahbaz Khan, modified 7 Years ago. Junior Member Posts: 40 Join Date: 11/18/14 Recent Posts
Hi Jan

You can use Short Text ADT. Which is available in the Global Site -> Configuration -> Application Display Templates.
Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
Hi Shahbaz,

thank you, i found the Template-Key for Short Text, which is LANGUAGE-SHORT-TEXT-FTL

But when i try:

&lt;#assign VOID = freeMarkerPortletPreferences.setValue("displayStyle", "LANGUAGE-SHORT-TEXT-FTL")&gt;

&lt;@liferay.languages default_preferences="${freeMarkerPortletPreferences}" /&gt;

&lt;#assign VOID = freeMarkerPortletPreferences.reset()&gt;


Nothing changes... Unfortunately i cant find anything on how to apply the correct Template-Key to portlet
Jan Wallitschek, modified 7 Years ago. New Member Posts: 6 Join Date: 1/26/18 Recent Posts
My current Solution is the following (which feels very squishy to be honest):

in my header.ftl i have the following:


<div class="language"><ul id="languages"></ul></div>

in my main.js i have:


AUI().ready(

	/*
	This function gets loaded when all the HTML, not including the portlets, is
	loaded.
	*/

	function() {
		var languagesList = document.getElementById('languages');
		var availableLanguages = Object.keys(Liferay.Language.available);
		for(var i = 0; i &lt; availableLanguages.length; i++) {
			var languageKey = availableLanguages[i];
			var shortLanguageKey = languageKey.substring(0,2);
			var languageItem = document.createElement('li');
			var languageLink = document.createElement('a');
			if( languageKey === themeDisplay.getLanguageId()) {
				languageLink.setAttribute('class', 'active language-link')
			} else {
				languageLink.setAttribute('class', 'language-link')
			}
			languageLink.innerText = shortLanguageKey.toUpperCase();
			languageLink.href = getNewUrlFromLanguageKey(shortLanguageKey.toLowerCase());
			languageItem.appendChild(languageLink);
			languagesList.appendChild(languageItem);
			
			var separatorItem = document.createElement('li');
			separatorItem.setAttribute('class', 'language-separator');
			separatorItem.innerText = '|';
			if(i !== availableLanguages.length - 1) {
				languagesList.appendChild(separatorItem);
			}
		}
	}
);

function getNewUrlFromLanguageKey(languageKey, availableLanguages) {
	if(/\/(.*?)\//.exec(Liferay.currentURL) &amp;&amp; searchStringInArray(/\/(.*?)\//.exec(Liferay.currentURL)[1], Object.keys(Liferay.Language.available)) &gt; -1) {
		return themeDisplay.getPortalURL() + "/" + languageKey + Liferay.currentURL.substring(3, Liferay.currentURL.length);
	} else {
		return themeDisplay.getPortalURL() + "/" + languageKey + Liferay.currentURL;
	}
}

function searchStringInArray (str, strArray) {
	for (var j=0; j<strarray.length; j++) { if (strarray[j].match(str)) return j; } -1; < code></strarray.length;>
<br>This works just like i want it to be, but as i said... It feels dirty to me.<br><br>I wanted to replace the function <strong>getNewUrlFromLanguageKey</strong> with some logic which i found in the forum. This logic depends on the Liferay-Javascript object instead of parsing the url with regex.<br>So this variant would be as follow:<br><br><pre><code> function getNewUrlFromLanguageKey(languageKey, availableLanguages) { var portletURL = Liferay.PortletURL.createURL(themeDisplay.getURLControlPanel()); portletURL.setDoAsGroupId('true'); portletURL.setLifecycle(Liferay.PortletURL.ACTION_PHASE); portletURL.setParameter('javax.portlet.action', '/language/view'); portletURL.setParameter('p_auth', Liferay.authToken); portletURL.setPortletId("82"); portletURL.setParameter('languageId', languageKey); return portletUrl; } </code></pre><br>But <strong>Liferay.PortletURL</strong> is null in my Liferay-Context. Cant tell you why...<br><br>I am open to any improvements / criticisms of this whole thing
thumbnail
Fernando Fernandez, modified 7 Years ago. Expert Posts: 401 Join Date: 8/22/07 Recent Posts
Jan Wallitschek:
Requirements : I need to display only the language-keys (EN | DE | HU | RO) and want to adjust some styling to it with css


You can define what languages show up by defining the languages available on the site: "Configuration / Site settings / Languages / Define a custom default language and available languages for this site."

You can change CSS for the portlet in the portlet instance "Look and Feel configuration" - easier - or in your own theme - harder.

HTH

Fernando
thumbnail
Pasi Kössi, modified 7 Years ago. New Member Posts: 12 Join Date: 10/13/08 Recent Posts

I guess the standard way to do this is to use a custom ADT for the language selector portlet. This works in Liferay 7.1 GA1, using one of the stabdard ADTs built in.

 

<#assign VOID = freeMarkerPortletPreferences.setValue("displayStyle", "ddmTemplate_LANGUAGE-SHORT-TEXT-FTL")>
<#assign VOID = freeMarkerPortletPreferences.setValue("languageIds", "fr_FR,en_GB,ru_RU")>
<@liferay_portlet["runtime"]
        defaultPreferences="${freeMarkerPortletPreferences}"
        portletProviderAction=portletProviderAction.VIEW
        portletProviderClassName="com.liferay.portal.kernel.servlet.taglib.ui.LanguageEntry"
/>
<#assign VOID = freeMarkerPortletPreferences.reset()>

Note that the display template name is prefixed with "ddmTemplate".

Also, this only sets the preferences the first time the language selector portlet is loaded in a certain scope. During testing, you may need to remove the preferences from database every now and then.

Swathy R, modified 6 Years ago. New Member Posts: 3 Join Date: 4/4/19 Recent Posts
Hi I used the same method to display languages as long text in header and  it's working well.

But the only issue is it's only translating the portlet content. Theme content is not translated. How to resolve this issue?