Anyone who has attended Tim Tripcony’s inspirational session on taking themes to the next level will never develop their XPages applications in the same way ever again. I was fortunate enough to attend it at BLUG and UKLUG, and took the opportunity to put the learning into practice in the XPages Help Application.
So when I saw a question on Twitter last week about how to change the label for Pager elements for a whole application, one solution jumped to mind: themes. After a little investigation, sure enough, it was possible to do quickly and easily.
The first step was to identify the theme ID for the pager elements and the property that needed to be set. To find the theme ID it was just a case of opening one of the themes found from the Notes install (xspnsfthemes) and searching for “Pager”. The themes are well-commented making it easy to find the default theme ID for the relevant elements, something I first saw documented on Chris Toohey’s blog well over a year ago.
Setting the layout property of the theme is standard for me now. There are a variety of keywords to be used for pagers (“First”, “FirstImage”, “Previous”, etc.). So to do override the layouts for all pagers, a theme would include the following code:
<control>
<name>Pager</name>
<property>
<name>layout</name>
<value>First Previous Group Next Last</value>
</property>
</control>
But you have to use one of the keywords for the layout property. Although you can’t currently set complex properties via themes, fortunately for the pager controls you don’t need to. Because there are specific pager theme IDs for all of the pager’s child controls. It’s fairly easy to guess what the property you need to set to override the value of the label on pager child elements is. But the best way to find out, if you’re unsure, is to add a pager to an XPage, set the layout to Custom, and create your own pager. If you look at the source pane you’ll see that it has added elements. Selecting one, looking at the properties and changing the label, you’ll see that it is the value property that needs to be overriden.
Combining the two approaches – looking at the theme and the XML created for the custom pager – it’s not rocket science to work out that to get this layout:

you need to add the following code:
<control>
<name>PagerControl.Pager.First</name>
<property>
<name>style</name>
<value>padding:5px</value>
</property>
<property>
<name>value</name>
<value>Page Number One</value>
</property>
</control>
<control>
<name>PagerControl.Pager.Previous</name>
<property>
<name>style</name>
<value>padding:5px</value>
</property>
<property>
<name>value</name>
<value>Previous Page</value>
</property>
</control>
<control>
<name>PagerControl.Pager.Next</name>
<property>
<name>style</name>
<value>padding:5px</value>
</property>
<property>
<name>value</name>
<value>Next Page</value>
</property>
</control>
<control>
<name>PagerControl.Pager.Last</name>
<property>
<name>style</name>
<value>padding:5px</value>
</property>
<property>
<name>value</name>
<value>Final Page</value>
</property>
</control>
Modify this, and you can add custom labels for your pagers across your application. This is why Tim’s session has change the way I develop XPages applications.
Well done, Paul… great example of how you can go beyond just loading stylesheets and applying CSS classes, to in fact tweak just about any property you want in a way that standardizes look & feel across an entire application.
One handy method that I don’t believe is in my slides for the session you mentioned (thanks for the kind appraisal, by the way) is that you can programmatically determine any component’s base theme Id using the getStyleKitFamily() method:
getComponent(“somePager”).getStyleKitFamily() // returns “Pager”
Thus, another way you could have determined the correct theme Ids to use to provide your custom labels is to bind a repeat control to the pager’s child components ( getComponent(“pagerId”).getChildren() ), and add a label or computed field inside the repeat, bound to each child’s styleKitFamily. Inspecting this property is the quickest “approved” way to identify the correct syntax… there is an even quicker way, but technically it’s a “Terms of Use” violation, so I’ll refrain from advocating it. 😉
Thanks Paul for your follow-up post after your twitter reply!
Unfortunately I’m not yet full confident with themes, eventhough I realize I can accomplish many tasks with that.
For other people like me, I did the following:
– since I already used the oneuiv2 thene, I created a new theme “mytheme” inside my app
– extended the oneuiv2 theme
– copy/paste your sample control tags and customize the labels
– in my app, xpages property window, I set the application theme to “mytheme”
it works as expected.
Thanks
Thanx for this post. Themes are very powerfull. After the BLUG I was playing around with themes for a customer application and it was easy to maintain the look and feel across the app. I implenteded in buttons, pagers etc.
Great find.
I always thought I needed to install a language pack just to change the previous/ next labels on pagers.
@Mark: I have written a follow-up article on how to dynamically calculate the label http://www.eknori.de/2012-03-02/followup-paul-withers-extending-themes-custom-pager-labels/
The thanks really go to Tim. Themes are extremely powerful, once you know what can be set in them (because of the JSF lifecycle, some things can’t and some are better set elsewhere).
Hopefully we’ll see the session at Lotusphere next year. It certainly deserves as wide an audience as possible.