context.getProperty(‘xsp.resources.aggregate’).equals(‘…’) working for resource and not resources definition

In a previous post I described a problem when implementing Font Awesome in conjunction with the Use runtime optimized JavaScript and CSS resources XSP property. The solution can be summarized as followed:

  • – Move the @font-face part in the font-awesome.min.css into 2 new CSS e.g.


  • adapt for minified version the paths to the fonts e.g.


  • load in a Theme design element the correct version based upon your XSP property setting:

context.getProperty(‘xsp.resources.aggregate’).equals(‘…’)   //true or false

This works for a resource definition but apparently not for a resourceS definition.

The following code

<resources rendered=”#{javascript:context.getProperty(‘xsp.resources.aggregate’).equals(‘false’)}”>
<resources rendered=”#{javascript:context.getProperty(‘xsp.resources.aggregate’).equals(‘true’)}”>

will load both files in optimized / non optimized runtime. Perhaps IBM can fix this?

“runtime optimized resources” in conjunction with font-awesome

Last week I posted a question on the XPages forum (shameless plug) since I had some problems getting the ‘run-time optimized resources’ xsp property to work in conjunction with font-awesome.  During development I loaded the FA style-sheet via a theme. After staging and enabling the xsp property the icons failed loading.

In this post I will describe my way to have them work together.

My first attempt came after reading the following suggestion on Stack Overflow. This unfortunately did not work for me. Pulling the files via a theme kept on failing. It seems that the resource aggregation messes things up when CSS and JS is added through a theme.

Next I tried to load the new CSS file with only the @font-face part in it via the Resources on an XPage but this only worked with a complete URL, so including the HTTP protocol, which is not desired.

My third approach was by inserting an external style-sheet e.g.:

<link rel=”stylesheet” type=”text/css” href=”font-awesome-4.2.0/css/font-awesome-fontFamily.css”/>

This worked remarkably well.

As a result I have downsized the number of requests for Javascript from 63 to 10 and for CSS from 10 to 3.

If you suggest another solution please drop a line in the comments.

FT Search and symbol characters

A while ago I wrote about how you could build a Live Search function with Domino Access Services & jQuery Tokeninput.  Since then the current version of that has been improved on several items, perhaps I will write about it in another post.

Now that people are more using it it appears that it is not bug free or more, it should be more aware that we are using Domino’s FTSearch in the background. I received a note that in certain circumstances the search did behave odd e.g. certain queries failed. For example the following query fails:

“Optimization of the railway station by Fa. Acme”

The term did not cause a failure when performing a search in the Notes view in the Notes client, but on the web in Java the FTSearch method on the NotesView object failed. When checking the data in the view and document the value was exactly as in the text above there.

Then I found the following on the web:

The full text search treats most symbol characters as a white space. The exception is if the search term itself is wrapped in quotes.

So it turns out the comma is translated into a white space and that results in zero corresponding documents in my FTSearch!

Placing quotation marks around the query does solve the problem but this would also break the search when users would enter AND OR OR NOT queries :-?

Hopefully some is out here aware which characters are on that symbol character list so I can adapt my livesearch function ???

XPages and Java from Start to Finish – My way


Last week David Leedy published on Youtube an excellent episode with the title “XPages and Java from Start to Finish” under his Notes in 9 stream.

In this show I do an in depth demo of an XPages app that’s based on Java Code. I didn’t take time tom build it from scratch but I go over every line of code in the app.

The app lets you you Create, Read, Update, and Delete Project documents, and then add to each project an unlimited number of tasks.

This week I was in the fortune to have time to look at the show and this episode offers what a lot of Notes developers are looking for: a simple, step by step demonstration and explaination how to (re)write an XPages application and keep the business logic as much as possible away from the presentation.

David also offers the application as a download on his NotesIn9 site. I think the concept is quiete interesting in it’s simplicity and I want to investigate if I can extend it to a level where JSON configuration files (Notes documents) can be used to define the data in an application?

In such way the same code can result in different types of applications, say the fifty nifty Lotus Notes type of applications we had in the 90’s. So anyone can write his/her own application only if you know a bit of JSON (or you know a guy who knows a bit of JSON). That sounds even more Notes in 9-ties ;-)

For now I just looked at the design and made some minor changes to the design e.g. I removed the notes view as a data source on the startpage. My sample DB is available under this link (perhaps I should think about using github). Thanks David for your inspiration and I am looking forward to your next show!



Working with JSON in your XPages application (3) – getEntriesByKey


In our third example we will extend the loadPictures method in the first blog entry in this serie to detect whether or not we want to load just all the entries in a view or entries that match a key in the first sorted column.

Use case

In the following simple scenario a user makes an selection (e.g. from a combobox) and corresponding picture documents will be displayed, as in the image:


Whenever a different value is selected the list with corresponding documents will be updated.

So how do we do this?

Switch between Notes views

The main difference is the key send if we do or don’t (empty value) want a filtering of the result list. To collect this key we provide a combobox:


The loadCategories method provides an ArrayList of String values:

public ArrayList<String> loadCategories(String ViewName) throws NotesException{
System.out.println(appRef + “.loadCategories()”);

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();

String ServerName = “dev1”;
String DatabaseName = session.getCurrentDatabase().getFilePath();
Database DB = session.getDatabase(ServerName, DatabaseName);

View luView = DB.getView(ViewName);
ViewNavigator vwnav = null;
ViewEntry vwentry = null;
ViewEntry vwentrytmp = null;

// all results will be added to this
ArrayList<String> categories = new ArrayList<String>();

// disable autoupdate

vwnav = luView.createViewNav();

// setting buffer for fast view retrieval

// perform lookup
vwentry = vwnav.getFirst();
while (vwentry != null){

// Get entry and go recycle
vwentrytmp = vwnav.getNext(vwentry);
vwentry = vwentrytmp;

return categories;

The xp:Combobox control is bound to a viewScope variable and it’s onChange event triggers a partial refresh on a panel:

<xp:panel id=”pictures”>
<xp:pager layout=”Previous Group Next” partialRefresh=”true” id=”pager1″ for=”repeat1″></xp:pager>
<table class=”table table-hover”>
<xp:repeat id=”repeat1″ rows=”15″ var=”pix”>

<xp:this.value><![CDATA[#{javascript:var active = viewScope.get(“activeCategory”);
if (active == “All”){
<xp:text escape=”false”>
getAttachmentURL and getBaseURL from:

function getAttachmentURL(docID:java.lang.String, attachmentName:java.lang.String) {
var base = getBaseURL();
var middle = “/xsp/.ibmmodres/domino/OpenAttachment”;
if (base.substr(0,4) == “/xsp”) {
middle += base.substr(4);
} else {
middle += base;
var result = base + middle + “/” + docID + “/$File/” + attachmentName + “?Open”;
return result;

function getBaseURL() {
var curURL = context.getUrl();
var curAdr = curURL.getAddress();
var rel = curURL.getSiteRelativeAddress(context);
var step1 = curAdr.substr(0,curAdr.indexOf(rel));

// Now cut off the http
var step2 = step1.substr(step1.indexOf(“//”)+2);
var result = step2.substr(step2.indexOf(“/”));
return result;
var thumb = pix.imgthumb;
var id = pix.docUNID;

return “<img src='” + getAttachmentURL(id, thumb) + “‘>”;
<td><xp:text escape=”true” value=”#{pix.subject}”></xp:text></td>
<td><xp:text escape=”true” value=”#{pix.category}”></xp:text></td>
<td><xp:text escape=”true” value=”#{pix.descr}”></xp:text></td>
<td><xp:text escape=”true” value=”#{}”></xp:text>
</tr><!– /.row –>


Depending on the value in the viewScope we call the loadPictures method empty or with a key.

private ArrayList<JsonJavaObject> loadJSONObjects(String ServerName, String DatabaseName, String ViewName, String Key, Integer ColIdx) throws NotesException {
ArrayList<JsonJavaObject> JSONObjects = new ArrayList<JsonJavaObject>();

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();
Database DB = session.getDatabase(ServerName, DatabaseName);

if (!(DB==null)) {
View luView = DB.getView(ViewName);

if (!(luView == null)) {
JsonJavaFactory factory = JsonJavaFactory.instanceEx;

ViewEntryCollection vec = luView.getAllEntriesByKey(Key, true);

ViewEntry entry = vec.getFirstEntry();
while (entry != null) {

Vector<?> columnValues = entry.getColumnValues();
String colJson = String.valueOf(columnValues.get(ColIdx));
JsonJavaObject json = null;

try {
json = (JsonJavaObject) JsonParser.fromJson(factory, colJson);
if (json != null) {

} catch (JsonException e) {
// TODO:

ViewEntry tempEntry = entry;
entry = vec.getNextEntry();
return JSONObjects;

Similar as in the previous examples the JsonJavaObject class from the package is used to return an arraylist of json objects.

In the next post I will describe how we can manipulate the JSON objects.

Opening the Bootstrap modal (dialog) from a repeat control

Here is a simple XPages development tip when working with Bootstrap:

In an app we replaced the Dojo dialog from the Extension Library with the Bootstrap modal due to scrolling problems: When the dialog pane exceeds the content pane, scrolling in the dialog lead often to scrolling of the background content. This was with mobile devices often a crime.

The Dojo dialog you can display in client side and server side JavaScript. The Bootstrap modal only in client-side.

Since I am calling the modal from within a repeat control and I need to update the content of the modal with data from the document represented in the xp:repeat control I needed to first call a function to collect additional back-end document data & perform a partial refresh on the modal (which resides in an xp:panel). Then I needed to call the function to show the modal.


Perhaps a bit well hidden is the onComplete property for the eventHandler. Here is the way I find it:

  • Find the element you want to define and action for (or already have).
  • Select/Highlight the event in the Outline control.
  • Open the Properties view for the Event handler.
  • Navigate to the onComplete property. Here is where you can open the editor.

Here is how it looks like in some screen shots:




The code looks as followed:

<xp:link escape=”true” text=”Link” id=”link2″>
<xp:this.action><![CDATA[#{javascript:var id:String = pix.docUNID;

viewScope.put(“helloWorld”, “Hello World from ” +id)}]]></xp:this.action>

As result my dialog is presented with updated content every time it is presented:


Working with JSON in your XPages application (2) – getEntryByKey


In the previous post we started with the first steps to modernize our xpages application by defining our Notes view data in JSON format, create objects from them in Java with help from and return them to the xpage (repeat control).

In our example we used the AllEntries method which is well known across the languages Domino supports (LotusScript/JavaScript/Java).


As Domino also supports other methods to work with Notes view data we have to extend our Java class with them. Next in line lies the getEntryByKey method.

Changes in setup

Removed Content Delivery Network

In the previous post we used CDN for loading Bootstrap. Since we work with XPages and the latest and greatest Extension Library at our service we simple apply the Bootstrap theme for our application.

New Notes view

In our *NonSQL* database we will add a new view with the first column categorized. I have chosen the following document properties:

varCategory:= Photo_Category;

I also extended the second column compared with the first view. The column formula is as followed:

REM {This column builds a JSON string};

varUNID := @Text(@DocumentUniqueID);
varCategory:= Photo_Category;
varTitle := Photo_Title;

jsonOpener := “{“;
jsonClosure := “}”;
jsonSeparator := “\”,”;
jsonLastItem := “\””;

jsonOpener +
“\”docUNID\”: \”” + varUNID + jsonSeparator +
“\”author\”: \”” + @Name([CN]; varAuthor) + jsonSeparator +
“\”category\”: \”” + varCategory + jsonSeparator +
“\”subject\”: \”” + varTitle + jsonSeparator +
“\”descr\”: \”” + varDesc + jsonSeparator +
“\”created\”: \”” + @Text(@Date(varCreated)) + jsonSeparator +
“\”imgthumb\”: \”” + varThumb + jsonSeparator +
“\”imgsmall\”: \”” + varSmall + jsonLastItem +

Notice I added an additional key:pair for a smaller (preview) image. I also find the @Return function a good best practice to explicit indicate something is being returned.

With this new view available we will update our Java class.

Java class additions

Our Java class will have two new functions:

  • loadPicture(Key)
  • loadJSONObject

The first indicates we will send along a unique identifier and the second indicates we will return a single JSON object.

public JsonJavaObject loadPicture(String Key) throws NotesException {
JsonJavaObject json = null;

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();

String ServerName = “dev1”;
String DatabaseName = session.getCurrentDatabase().getFilePath();
String ViewName = “$v-pixJSONCategories”;

try {
json = loadJSONObject(ServerName, DatabaseName, ViewName, Key, 1);
} catch (NotesException e) {
// TODO Auto-generated catch block
return json;


private JsonJavaObject loadJSONObject(String ServerName, String DatabaseName, String ViewName, String Key, Integer ColIdx) throws NotesException {

JsonJavaObject json = null;

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();
Database DB = session.getDatabase(ServerName, DatabaseName);

if (!(DB==null)) {

if (!(DB.isOpen())) {;

View luView = DB.getView(ViewName);
if (!(luView == null)) {

ViewEntry entry = luView.getEntryByKey(Key);
if (!(entry == null)) {

Vector<?> columnValues = entry.getColumnValues();
String colJson = String.valueOf(columnValues.get(ColIdx));

try {
JsonJavaFactory factory = JsonJavaFactory.instanceEx;
json = (JsonJavaObject) JsonParser.fromJson(factory, colJson);
} catch (JsonException e) {
// TODO Auto-generated catch block

return json;

Probably during development (and acceptance) you would like include a logging mechanism. I have left the System.out.println statements out of the examples…

A new XPage

Since we will call the loadPicture method with a key we need to provide a mechanism to capture this key. In our first example we capture the key from the unid parameter that we attach to the URL e.g. page2.xsp?unid=1234. Notice that the unid has to respond to a category value set in the category column in the Notes view. So my proposal is to use categories that are sufficient distinguished from each other.

In my xpage I drag in a panel and define a dataContext for it:

<xp:dataContext var=”data”>
<xp:this.value><![CDATA[#{javascript:var paramUNID = paramValues.get(“unid”);
strUNID = paramUNID.toString();

Notice I am using the paramValues global object available in XPages to capture the key. With this key I call the loadPicture method.

Within the panel I define a Bootstrap form:

(for some reasons WordPress want to transform my text into HTML)

Data is the variable I have defined for the dataContext. Hereby I can easily access the JSON object properties and collect a value by accessing a key e.g. data.docUNID.

With these new additions our result looks and followed:

isn't she lovely?