I have submitted some XSnippets for the XSnippets-Contest. This is the first one, the XPages Localization Setter: The Snippet allows to change the language settings of a XPage „On-The-Fly“, including the used browser language, the dojo settings, the ressource files etc.
package ch.hasselba.xpages.jsf.core;
import javax.faces.context.FacesContext;
import javax.faces.application.Application;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.component.UIViewRoot;
import java.util.Locale;
import java.util.Map;
public class LocalizationSetter implements PhaseListener {
private static final long serialVersionUID = -1L;
private static final String scopeVarName = "Language";
private static final String scopeName = "sessionScope";
public void afterPhase(PhaseEvent event) {}
public void beforePhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
UIViewRoot view = facesContext.getViewRoot();
view.setLocale( getLanguage(facesContext) ) ;
}
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
private Locale getLanguage( FacesContext facesContext ){
try{
Application app = facesContext.getApplication();
Object obj = app.getVariableResolver()
.resolveVariable(facesContext, scopeName );
Object lang = ((Map) obj).get( scopeVarName );
if( lang != null ){
return new Locale((String) lang);
}
}catch(Exception e){}
return Locale.getDefault();
}
}
This phase listener updates the language settings of the UIViewRoot-Element during the rendering of the response. The language the XPage will be set to the stored value in a session scope variable named „Language„. If you want to change this you just have to change the variable scopeVarName.
To activate the phase listener in your XPages-Application you have to alter the faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<lifecycle>
<phase-listener>
ch.hasselba.xpages.jsf.core.LocalizationSetter
</phase-listener>
</lifecycle>
</faces-config>
Here is a simple example to demonstrate the XSnippet:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:comboBox id="comboBox1" value="#{sessionScope.Language}">
<xp:selectItem itemLabel="Chinese" itemValue="zh" />
<xp:selectItem itemLabel="German" itemValue="de" />
<xp:selectItem itemLabel="Turkish" itemValue="tr" />
<xp:eventHandler event="onchange" submit="true"
refreshMode="complete" />
</xp:comboBox>
</xp:view>
If you are choosing „turkish“ from the combobox, the html source looks like this after the page was reloaded:
If you add a simple date picker to your XPage and change the language to chinese, the dojo dialog will be in chinese from now on:
To add more languages you have to use the two letter ISO 639 code. To get a list of all available locales you can use this small repeat control:
<xp:repeat id="repeat1" rows="999" var="locale">
<xp:this.value>
<![CDATA[#{javascript:
java.text.SimpleDateFormat.getAvailableLocales();
}]]>
</xp:this.value>
<xp:label id="label1">
<xp:this.value>
<![CDATA[#{javascript:
locale.getDisplayName() + " -> " + locale.toString()
}]]>
</xp:this.value>
</xp:label>
<xp:br/>
</xp:repeat>
Note:
After changing the language a full refresh is required!
How does this work in combination with strings.properties files?
Hi Malin, you need to perform a full refresh of the XPage.
Hi Sven, I followed your example but for unknown reasons I have to reload the page before the correct resource bundle becomes active. I added the file:
and on my xpage i read the value e.g. strings file: . the other files are called strings_de.properties, strings_nl.properties etc. What am I doing wrong here? I notice the sessionscope is set correctly