0

In my xpage I need to set a user defined language before the page loads. the language to be set is stored in a document in the database

so I do this in beforePageLoad

var lang = getUserDoc().getItemValueString("Language")
facesContext.getViewRoot().setLocale(new java.util.Locale(lang));
context.reloadPage();

the problem is that if I do not do context.reloadPage the language is not set.

but context.reloadPage gives all kind of other problems when loading the page so I need to find a better way.

is there anyway I can set the language of the page without reloading the page.

Thomas Adrian
  • 3,543
  • 6
  • 32
  • 62
  • I my opinion there is no way to set the language of the page without reloading it. What kind of other problems do you have with this solution? – Georg Kastenhofer Oct 22 '15 at 13:38
  • It is a bit complicated to explain. I get strange reload issues for users after the page timeout or if I rebuild the application. It is causing massive hits to the server. – Thomas Adrian Oct 22 '15 at 13:52

4 Answers4

2

This doc suggests using context.setLocale/setLocaleString instead of viewRoot.setLocale. The advantage is that the context locale is used for the rest of the browser session. The context locale will be set as the viewRoot locale when any subsequent viewRoots are loaded, so you don't have to re-set the locale for every page. It does still require a context.reloadPage for the current viewRoot though, so its not exactly what you were asking for.

The doc is: Locale use in XPages: Programmatically setting the locale

1

The problem is beforePageLoad runs too late - the components have already been loaded into the component tree with the relevant language.

It may work if you use a ViewHandler, as in Jesse Gallagher's Scaffolding framework on OpenNTF. You would definitely need to identify the language before the call to super.createView() though.

To use beforePageLoad, I think you would subsequently need to iterate through controls and amend the labels etc.

Paul Stephen Withers
  • 15,699
  • 1
  • 15
  • 33
  • Sven's code won't work in a `ViewHandler` for setting the language, because the `UIViewRoot` is only created by the call to `super.createView()`, but the language needs setting before that call. The key would be working out where it retrieves that locale from - it must be held somewhere session-wide, because otherwise you'd default to the application default language on each view. – Paul Stephen Withers Oct 22 '15 at 14:27
1

Setup a phase listener that sets the appropriate locale based on the user's configuration.

See this blog post by Sven Hasselbach for more details: http://hasselba.ch/blog/?p=649

I use this approach in several apps using the following phase listener based on the approach from Sven. The code reads the locale from a user bean:

public class LocalizationSetter implements PhaseListener {

    private static final long serialVersionUID = -1L;

    public void afterPhase(PhaseEvent event) {
    }

    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        UIViewRoot view = facesContext.getViewRoot();
        view.setLocale(User.get().getLocale());
    }

    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }
}
Per Henrik Lausten
  • 21,331
  • 3
  • 29
  • 76
  • that looks nice! however, The example from Sven still require a reload of the page, I need the page to have the correct language set when the page loads. – Thomas Adrian Oct 22 '15 at 15:25
  • A reload is not needed. It's a phase listener that kicks in during load. I use this approach to set default language for anonymous users based on configuration and for setting language based on user preference. – Per Henrik Lausten Oct 22 '15 at 15:28
  • where do you set the session variable, in beforePageLoad? last note on Svens post is: After changing the language a full refresh is required! – Thomas Adrian Oct 22 '15 at 15:31
  • Thomas, a full refresh is of course required when you change the language (which is what Sven does in his example XPage). I updated my answer to show you how I read the user locale from a user bean (and this does not require a reload). – Per Henrik Lausten Oct 22 '15 at 15:45
  • Yes, you can read any document in the phase listener. It's "just" Jave and you have access to beans, documents, scopes etc. – Per Henrik Lausten Oct 22 '15 at 15:46
  • Well setting the language worked from the phaselistener. the HTML tag has set the correct language but my resource bundle containing the translation files is not reflecting the change. so my site is not translated into the language set. – Thomas Adrian Oct 23 '15 at 06:07
  • I have just scripted a small answer for resource bundle. Probably that helps? – Chintan Parekh Oct 23 '15 at 08:04
1

Hope I have got it correctly, just extending my answer to Per Henrik's solution here (based on the last comment), for setting the resource bundle correctly probably you can just compute it? Something like this?

<xp:this.resources>
        <xp:bundle var="application">
            <xp:this.src><![CDATA[#{javascript:if(context.getLocale()=="en_US")
return "/application.properties";
else
return "/application_de.properties";}]]></xp:this.src>
        </xp:bundle>
    </xp:this.resources>

I have just used the context variable here, but I am sure that the document variable is accessible too.

Hope this helps.

Chintan Parekh
  • 1,101
  • 1
  • 12
  • 31
  • Thank you very much Chintan, don't understand why I haven't thought about this!. seem to work very good and might be the answer to my translation issues. I will do some more testing, thanks again – Thomas Adrian Oct 23 '15 at 11:16
  • Glad that it helps, actually it is easy to miss, as XPages hides the computed thing inside "All Properties" instead of directly showing that it can be computed under resource tab. – Chintan Parekh Oct 23 '15 at 11:34