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