Your Development & Design Resource
XPages - UI Layering via UserAgent-based Includes
07/06/2011 09:17:00 PM by Chris Toohey
While building a multi-client (Lotus Notes, Web Browser, and Mobile Device Browser) or hybrid XPages app, there are various techniques that can be used to handle application navigation.
If we're considering the Mail/Calendar/To Dos and the Personal Address Book representative of the typical traditional Lotus Notes Client application, the application navigation has an initial launch screen, and each Form/NotesDocument is launched in a new tab within the client.
If we're considering most Web Browser Client apps, the navigation has an initial launch screen, and each Form/NotesDocument is launched within that same screen instance. In fact, creating new tabs or windows is a deprecated practice, as it often results in the user losing the focus of the intended user experience.
If we're considering most Mobile Device Client apps, the idea of a new tab/window for each Form/NotesDocument will break the application even more. Especially with touchscreen devices, the idea of swiping to move between "screens" but maintaining a same-screen instance is critical to mirroring the native application and operating system user experience.
Using traditional IBM Lotus Notes and Domino Design Elements (ie., Forms, Views, Pages, Framesets, etc.), it was a simple matter of naming two Design Element a common name (let's say a Page named index.html, and hiding each of them using the Design Element Hide design element from or $Flags option.
This, of course, limited you to "n" or "w", or rather hiding from the Notes Client or the Web Browser respectively. For Mobile Devices in 8.5.n, you're kinda stuck should you use this approach.
... it did work though. index.html would launch in Notes and ignore the Web Browser Client-specific index.html. The Web Browser Client-specific index.html would have to pull a double-duty, handling both the Web Browser and Mobile Device Browser clients.
With XPages however, you won't be able to use this technique. Not only does DDE remove the ability to hide an XPage based on Client Type (ie. Notes or Web), but no two XPages can have the same name. Thus, you would have an index.xsp and an index_1.xsp... which makes the whole thing moot.
An alternate approach would be to separate the application navigation for the various client types. For example, if you were serving the three different client types, you would create an index_browser, index_notes, and index_mobile respectively.
You would have to program the application navigation throughout your entire design, making absolute certain that you handled everything from View Form Formulas to in-app links.
Painful, but it could be done...
Unless you use things like the UNID with a null-view placeholder in the URL:
- or -
Using this technique for launching a NotesDocument, the Form Formula is ignored (obviously, since there's no real View Design Element named 0 or doesnotexist) and the NotesDocument tries to open using either the stored Form or the Form Design Element whose name matches the value of the Form NotesItem in the NotesDocument.
And while we're discussing the Form NotesItem in the NotesDocument...
Create a NotesDocument with a Form Design Element named document_notes, and the Form NotesItem will be saved as "document_notes". Edit and save that NotesDocument with a Form Design Element named document_web, and the Form NotesItem will be changed to "document_web".
If you forget a single instance of a defensive coding measure, your NotesDocuments disappear as all of the View Selection Formulas use
form = "document_notes', or they're not processed by Agents due to the same View Selection Formula issues or any dbSearch or Form NotesItem-based logic.
And I'm simply highlighting one or two of the potential pitfalls here. I haven't even mentioned logistics in dealing with screen real estate or user input capabilities...
As a result of all of these yeah, but... and it can done, however caveats to each of these techniques, most application developers developing hybrid, multi-client applications stick everything into a single document Form Design Element and (employing a mind-breaking number of Hide-Whens) squeak out an application that, often at best, doesn't totally suck but can be used in all 3 target clients.
At worse, it'll be the last time they're asked to take that corporate directory to a BlackBerry or web-enable that circa 4.6 app.
With "UI Layering" in XPages however, you can create rich, interactive, and client type-specific user interfaces/user experiences for your hybrid applications without relying of the often fragile nature of the
hacks techniques of the past.
To get started, let's create our index.xsp XPage:
(Note: Just name it core [ie., don't add the ".jss"] as DDE will handle that for you. Otherwise, you'll have a core.jss.jss...)
Add the following function to the core.jss library:
This function will return a defined keyword and set SessionScope Variable based on the reported UserAgent.
In other words, if you use an iPhone, your UserAgent is reported as this:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5
I am simply going to look for iphone in the reported UserAgent and return iwebkit.
Now, let's go back to our index.xsp XPage and add our core.jss library, and put the
setUA() function to use:
Now, I can create index_iwebkit.xsp, index_blackberry.xsp, and index_browser.xsp... or further extend my
setUA() function and return alternate UIs / UXs for things like iPads, the Lotus Notes Client, and more.
And that's where the UI Layering comes in:
index.xsp is a simple base, while the included UserAgent-specific XPage paints the UserAgent-specific User Interface and User Experience.
The added bonus to using this technique is that you can test, pilot, and deploy individual XPages by directly opening them in a given browser. Simply launch index_ipad.xsp from your iPad (or Google Chrome, or any other Webkit-based browser).
Seen above, person_iwebkit.xsp and person_browser.xsp surfaced thru person.xsp: two unqiue, UserAgent-specific User Experiences and User Interfaces.
This is not a new technique by any means. In fact, I believe that Declan Sciolla-Lynch uses the Include Page Container Control to support multiple client types in Blogsphere. It's a technique that I've used in my Mobile XPages webinars and demo applications. It's a technique that I am using in Remote Console HD to provide Notes, Browser, and multi-Mobile Device and Tablet-specific features and function.
And it's a technique that can use more exposure, and I don't see many people adopting it today.
With the ability to add new user experiences specific to the UserAgent (and if you wanted to take this function a step further, enveloping checks for specific User Roles or various other context values), this is a no-brainer.