You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by "Cort, Tom" <To...@state.vt.us> on 2007/05/15 20:54:45 UTC

Localization: get/setLocale before other managed beans execute?

Greetings List Lurkers,

I'm localizing a myfaces application and I'm having trouble changing the
locale before my managed beans load a locale specific resource bundle. If
anyone has any hints, ideas or links, it would be greatly appreciated. Thank
you!

Expected Results
----------------

The goal is to have a drop down menu in the corner with the available
languages. The user will select a language and the page will re-load in that
language. The correct language should be automatically selected when the
user first visits the page based on the browser's language settings.

Actual Results
--------------

I have this mostly working. When the browser's locale is set to 'fr', the
page loads in French. I can select 'English' from the drop down menu and the
page re-loads in English. The only problem is with a bean that I'm using to
dynamically generate navigation menus. When the user selects a locale, the
page reloads in the proper language, but the menus are still in the previous
language (i.e. getLocale() returns the previous locale). The menus are in
English on the next reload (i.e. the new locale is returned on the next page
loads).

Example of the Problem
----------------------

- The user's browser's locale is set to 'fr'
- The user visits /welcome.faces and the page loads in French
- The user selects the 'English' locale which submits the form to
/welcome.faces
- /welcome.faces loads and everything is in English except the menu which is
still in French
- The user types /welcome.faces in the browser's location bar and presses
enter
- The page reloads and now everything (including the menus) is in English.

What I think is Happening
-------------------------

The bean that generates the navigation menus is executing before the locale
is set.

Questions
---------

Is there a way to set the locale before my other beans call getLocale(), or
maybe there is a way to tell it to process the form before the other beans
execute? Is there a better way to do what I want, I'm sort of new to
JavaServer Faces?

Things I've Tried
-----------------

I tried accessing my localesBean via "#{localesBean.locale}" (source below)
from leftNavBean (source below), but I get the same results.

Some Ideas I've Had
-------------------

One idea I have is to create a JSP ('bounce.jsp'). When the locale is
changed, the user is sent to bounce.jsp. When the user gets to bounce.jsp,
it displays "Locale Changed" and redirects him back to the original page.
While I think this would work, it isn't ideal.

Relevant Source Code / Config Settings
--------------------------------------

If you need more than this, let me know.

The following 3 files exist in WEB-INF/classes
	LocalizationResources.properties
	LocalizationResources_en.properties
	LocalizationResources_fr.properties

-----------------------------------------------------------------------
--- locale drop down list
-----------------------------------------------------------------------

<h:form>
	<h:selectOneMenu onchange="submit()" id="locale"
value="#{localeBean.locale}">
		<f:selectItems value="#{localeBean.supportedLocales}"/>
	</h:selectOneMenu> 
</h:form>

-----------------------------------------------------------------------
--- an example faces page
-----------------------------------------------------------------------

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="/WEB-INF/tlds/portal-taglib.tld" prefix="portal" %>
<%@ taglib tagdir="/WEB-INF/tags/layout" prefix="layout" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<f:view locale="#{localeBean.locale}">
	<f:loadBundle basename="LocalizationResources" var="txt"/>
	<layout:page>
		<h:outputText value="#{txt.welcome}"/>

		<!-- content omitted -->

		<!-- Menu -->
		<portal:list value="#{leftNavBean.allLinks}"
var="currentLink">
			<h:outputLink value="#{currentLink.uri}">
				<h:outputText value="#{currentLink.text}"/>
			</h:outputLink>
		</portal:list>
	</layout:page>
</f:view>

-----------------------------------------------------------------------
--- LeftNavBean.java (the relevant part)
-----------------------------------------------------------------------

	public NavBeanBase[] getAllLinks() {
		ResourceBundle txt =
ResourceBundle.getBundle("LocalizationResources",
FacesContext.getCurrentInstance().getViewRoot().getLocale());
		
		// was a DB call
		TopNavBean[] links = {
				new
TopNavBean(txt.getString("urlFoo"),txt.getString("urlFooDisplay")),
				new
TopNavBean(txt.getString("urlBar"),txt.getString("urlBarDisplay "))
		};
		
		return links;
	}

-----------------------------------------------------------------------
--- LocaleBean.java
-----------------------------------------------------------------------

public class LocaleBean {
	
	private String locale = null;
	
	public String getLocale() {
		if (this.locale == null) {
			this.locale =
FacesContext.getCurrentInstance().getViewRoot().getLocale().toString();
		}
		
		return locale;
	}

	public String getLocaleDisplayName() {
		Locale locale = new Locale(this.getLocale());
		return locale.getDisplayName(locale);
	}
	
	public void setLocale(String locale) {
	
FacesContext.getCurrentInstance().getViewRoot().setLocale(new
Locale(locale));
		this.locale = locale;
	}
	
	public List<SelectItem> getSupportedLocales() {
		Iterator supportedLocalesItr =
FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
		List<SelectItem> localeItems = new ArrayList<SelectItem>();
		
		while (supportedLocalesItr.hasNext()) {
			Locale supportedLocale = (Locale)
supportedLocalesItr.next();
			localeItems.add(new
SelectItem(supportedLocale.toString(),
supportedLocale.getDisplayName(supportedLocale)));
		}

		return localeItems;
	}
}

-----------------------------------------------------------------------
--- faces-config.xml (the relevant parts)
-----------------------------------------------------------------------
	<application>
		<message-bundle>LocalizationResources</message-bundle>
		<locale-config>
			<default-locale>en</default-locale>
			<supported-locale>en</supported-locale>
			<supported-locale>fr</supported-locale>
		</locale-config>
	</application>

	<managed-bean>
		<description>Used managing the current Locale.</description>
		<managed-bean-name>localeBean</managed-bean-name>
	
<managed-bean-class>gateway.portal.beans.LocaleBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

	<managed-bean>
		<description>TopNavBean</description>
		<managed-bean-name>topNavBean</managed-bean-name>
	
<managed-bean-class>gateway.portal.beans.TopNavBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

--
Tom Cort
Systems Developer
Vermont Department of Taxes