Thematically Challenged – Best Practice for Dynamically Changing Themes in Xpages

Home » Thematically Challenged – Best Practice for Dynamically Changing Themes in Xpages

For a while now one of the items on my wish-list of functionality to add to XPages has been the facility for the user to change the theme of an XPages application, possibly even for individual users to select a theme for their own experience. Currently, you need Domino Designer to change the theme for the web (fortunately now free, but still needing to installed).

There is the option of assigning a stylesheet to each page (or a custom control on every page) that is computed based on a sessionScope or applicationScope variable.

My first thoughts on this were to programmatically set the stylesheets in my theme using server-side javascript. After all, the rendered property of a resource can be computed and I can similarly set the value property of the pageTitle or pageIcon property via javascript to applicationScope variables. However, it appears using javascript to set the href of a stylesheet doesn’t work.

So my next thought was to track down where the theme is set. I initially found it in the Icon, as with many other database-level properties (database title, template name etc.). Unfortunately, although there is indeed a $DBTheme field in the Icon, it appears to be the client theme.

So I set my theme and did a search. Sure enough, I found it in xsp.properties, a file only accessible through the Java perspective. But nevertheless it exists in the .nsf, so it must be possible to get a handle on it, right? A few agents later, I managed to export it as DXL by creating a NotesNoteCollection with SelectMiscFormatElements set to true, and looping through them. (Incidentally, this is also where XPages and Custom Controls can be found).

So I’d got my DXL out, worked out how to encode the theme using Base64, and trying to import it back in. But I hit my final stumbling block. After many attempts, all I could get was the message “Document has invalid structure”, even though it follows the same format as the output. The output and agent are attached, in case anyone can get any further with them. My plan was to store the theme in a profile document and kick of a server-triggered agent to do the import, getting round the problem of needing Designer access.

My fall-back position (prompted as I began writing this article) has been to have a single theme with the different stylesheets rendered according to scoped variables, like this (note, you need to escape the ampersands in the XML):

Theme code

Is this a good approach? Are there better practice approaches?

I’d be interested to hear.

 

5 thoughts on “Thematically Challenged – Best Practice for Dynamically Changing Themes in Xpages”

  1. Hi Paul,

    I’m currently putting the finishing touches to a custom control which I hope to publish to OpenNTF real soon and it allow you to change the Theme on the fly

    <xp:comboBox id=”v851ThemeChanger1″

    value=”#{requestScope.possibleAppThemes}”>

    <xp:selectItem itemLabel=”” />

    <xp:selectItem itemLabel=”notes” />

    <xp:selectItem itemLabel=”webstandard” />

    <xp:selectItem itemLabel=”oneui” />

    <xp:selectItem itemLabel=”yourOwnTheme” />

    <xp:eventHandler event=”onchange” submit=”true”

    refreshMode=”complete”>

    <xp:this.action><![CDATA[#{javascript:var f = “/”+@RightBack(context.getUrl().getAddress(),”/”);

    context.setSessionProperty(‘xsp.theme’, getComponent(‘v851ThemeChanger1’).getValue());

    context.redirectToPage(f)}]]></xp:this.action>

    </xp:eventHandler>

    </xp:comboBox>

    Is this best practice? I’m not sure. I guess we’ll find out when we find out how well it performs and stuff.

    Regards,

    Paul.

  2. @Paul

    I think the thing with XPages is the flexibility. There are a variety of ways to do the same thing. It’s a case of identifying the best option for the current requirement, and where there isn’t a best option, ensuring consistency.

  3. The rendered property in a theme is definitely one way to do it but from a performance point of view it may not be the best way to do it. Each time a page is rendered it has to evaluate the formulas.

    the context.setSessionProperty looks like an interesting way to do it. Maybe a session initialization script to set it based on a value in a user profile….

  4. Hi Paul. For the Notes client I have favoured a similar approach to yours of having a computed subform that has the relevant CSS file(s) attached.

    With Xpages (as Paul Hannan) has shown I think you ultimately need to use setSessionProperty(‘xsp.theme’,xxx) to vary the theme from the application default. How that theme is determined can be done in many ways. It could be a function Inside the application (as Paul H showed), it could be by passing a ?theme=xxx parameter on the URL or it may even be held in a user prefererence somewhere (e.g. profile document).

  5. Pingback: XPages ressources in a theme – http vs. https | Dalsgaard Data A/S (Intl)

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top