2

I'm currently trying to set the locale programatically, but can't find a good solution. The use case is I have another website that post data to my site that has a locale parameter, and base on this locale, I have to render my page.

I've already tried setting the locale on preRenderView, constructor and PostConstruct but it seems it's already to late.

Any suggestion? Thanks.

czetsuya
  • 4,773
  • 13
  • 53
  • 99
  • Related: [JSF 2.0 set locale throughout session from browser and programmatically](http://stackoverflow.com/q/5388426/1065197) – Luiggi Mendoza Jan 17 '13 at 06:23
  • Yes, I know how to set the locale. My question is how to set the locale before the page is rendered. This is because my locale value comes from a post variable. – czetsuya Jan 17 '13 at 06:33
  • @czetsuya, just make sure to reload the page (`h:commandButton` without `f:ajax` could do the job for example or with `f:ajax render="@all"`) – Daniel Jan 17 '13 at 06:56
  • @Daniel, yes that's what I'm trying to do. But I need to do that without clicking any button. I'm trying redirecting to the same page it works but doesn't look elegant. – czetsuya Jan 17 '13 at 07:02
  • so how does that locale is being set ? isn't the page being refreshed after that post? – Daniel Jan 17 '13 at 07:05

2 Answers2

4

Key point is that you need to set the locale by UIViewRoot#setLocale() before the view is ever rendered. The <f:view locale="#{languageBean.currentLocale}"> is only set during building of the view. So any request based actions which are invoked thereafter with the intent to change only the bean property won't have any effect. You really need to manually invoke UIViewRoot#setLocale() as well.

Easiest would be to perform that UIViewRoot#setLocale() job in the setter of the currentLocale property as well. The bean example as mentioned in the answer of the link provided by Daniel in your question comment does exactly that: JSF 2.0 set locale throughout session from browser and programmatically. This way no ugly JS hack is necessary to reload the page once.

Based on your own answer, there's another possible problem: your "receiver bean" seems to be request scoped and not be the #{languageBean} itself. If this bean is constructed for the first time after any locale/language related aspects of the view (e.g. language dropdown, localized text, etc), then it's too late to change them as well. You would like to move the construction of the bean to the pre render view event (e.g., via <f:event listener>). An alternative is to just perform the request parameter collecting job in the getter of the currentLocale property instead.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • actually my receiver bean is ConversationScope. Unfortunately, I cannot put the collecting job inside the languageBean currentLocale getter because I'm using the languageBean throughout the project. I'll try the preRenderView event. – czetsuya Jan 26 '13 at 08:56
1

I've resolved the issue by using plain javascript to load the page.

In my PostConstruct, I read the parameter from context's request parameter map. // set locale

try {
    languageBean.setCurrentLocale(LocaleUtils.toLocale(temp.getLocale()));
} catch (IllegalArgumentException | NullPointerException e) {
    languageBean.setCurrentLocale(Locale.JAPAN);
}

And then reload the page using plain javascript:

<script type="text/javascript">
    window.onload = function() {
        if (!window.location.hash) {
            window.location = window.location + '#loaded';
            window.location.reload();
        }
    }
</script>

I've wrote a more detailed codes here: http://czetsuya-tech.blogspot.com/2013/01/loading-locale-from-postget-parameter.html

czetsuya
  • 4,773
  • 13
  • 53
  • 99
  • didn't `FacesContext.getCurrentInstance().getViewRoot().setLocale(LocaleUtils.toLocale(temp.getLocale()));` worked for you ? – Daniel Jan 17 '13 at 08:53