Adding resources to an XPage at runtime

This evening I was messing around with this blog and was playing with Google web fonts. I was wanting to experiment with some different fonts but I couldn't find an easy way to add additional resources to my blog. This prompted a quick dev session to add that ability. The best part is it didn't take long to do. Here's how I went about it.

XBlog has an applicationScope bean called XBlogUtils. This bean has a lot of utility type methods and plays an integral part in the functionality of XBlog. This bean also stores the maps of the Hot Tags, Hot Text, Translations, Configuration and Layout values. So I added a field to the configuration document and when populated all the values in that document get placed in the configuration map which is a property of the XBlogUtils bean. This field is a multi-value field with a semi-colon as the separator. Each value contains a comma separated list of properties which match up to whatever type of resource you're wanting to add. The value you would enter to use the cabin font from Google web fonts would be something like: "link,http://fonts.googleapis.com/css?family=Cabin,stylesheet,text/css".

Now, in the beforePageLoad of the layoutDefault custom control (this is the starting point for determining what content is displayed in XBlog and is where all resources get loaded from). But I added this code in the beforePageLoad event:

var resources = XBlogUtils.getConfigValue("additionalResourceDefinitions");
if (resources && resources.size() > 0) {
	for (var i = 0;i < resources.size();i++) {
		var resourceDefArr = resources[i].split(",");
		var resource = null;
		if (resourceDefArr[0].equalsIgnoreCase("link")) {
			resource = new com.ibm.xsp.resource.LinkResource();
			resource.setRel(resourceDefArr[2]);
			resource.setHref(resourceDefArr[1]);
			resource.setType(resourceDefArr[3]);
		}else if (resourceDefArr[0].equalsIgnoreCase("meta")) {
			resource = new com.ibm.xsp.resource.MetaDataResource();
			resource.setContent(resourceDefArr[1]);
			resource.setName(resourceDefArr[2]);
		}else if (resourceDefArr[0].equalsIgnoreCase("script")) {
			resource = new com.ibm.xsp.resource.ScriptResource(resourceDefArr[1], true);
		}else if (resourceDefArr[0].equalsIgnoreCase("style")) {
			resource = new com.ibm.xsp.resource.StyleSheetResource();
			resource.setHref(resourceDefArr[1]);
		}else if (resourceDefArr[0].equalsIgnoreCase("dojo")) {
			resource = new com.ibm.xsp.resource.DojoModuleResource(resourceDefArr[1]);
		}
		if (resource) {
			com.xblog.utils.XBlogResources.addEncodeResource(facesContext, resource);
		}
	}
}

What happens here is we get the value of the "additionalResourceDefinitions" field and if there are values there we loop through those values, split each value into it's own array, check what type of resource we're adding and create a new resource based on the type. We then set the pertinent properties of that resource and add it.

Of particular interest in the above code, which isn't really that interesting, is the line: "com.xblog.utils.XBlogResources.addEncodeResource(facesContext, resource);". Now, XBlogResources extends com.ibm.xsp.extlib.resources.ExtLibResources which has the addEncodeResource method. This class provides you a means to add resources to an XPage at runtime. When you add let's say one of the dojo dijits from the extension library. The renderer (usually anyways) makes a call to this class which adds the "dijit.form.Button" DojoModuleResource resource (for example) to the page, pretty handy huh?

If you don't have jd-eclipse (a story for another day) installed, I suggest you install it and have a look at that class. You can add an array of resources or a single resource and it should help you better understand how resources can and are added to an XPage when you drag a component onto the page. If you're reading this post via a web browser (as opposed to a mobile device) you should see that the addition of the resource worked as I'm using the "Lora" font from Google web fonts.    

Share This: