Unplugged Controls 3.0

Today we have released the latest version of the Unplugged Controls project which I work with Teamstudio on. And it’s a larger release than usual.

Over the last few months we’ve completely re-written the CSS which governs the controls using LESS. When I say “we”, it’s really been Jack Herbert who’s done most of that good work. What it allows us to do is create “themes”, so in our new Sampler application you can switch between our standard dark theme, a new light theme and another theme which we call iOS7 (which is hopefully obvious from the look of it!).

The screenshots above are of our new Sampler app which shows off some of the new functionality as well; a Text Reader control with text size buttons, we’ve integrated Font Awesome for all of our icons, and it also give you the ability to use them in your apps, we’ve also added a new “media library” control which offers a more iTunes Store feel to navigation.

I’d also offer a big thanks to Mark Leusink who has given some great feedback and suggestions for improving the Controls. It’s good to work with smart people.


Basically everything about the controls has been rewritten in some way, so it’s definitely worth taking a look if you’re doing any mobile development. And with version 3 of the Unplugged app itself, you’ll see some dramatic performance improvements if you haven’t taken a look in a while. I’m not overstating the improvements on the performance side of things, we’ve all spent a long time making things faster, and with the latest Apple hardware thrown in, our benchmarks which used to run in around 30 seconds, now take 5 seconds on a new iPad Air.

But this is not the only change. We have also created a new website which we call the Restyler. This site allows you to create you own custom themes which are easier to integrate into your apps to make them fit your own corporate look and feel guidelines. It saves you having to get your hands too dirty in our CSS (although you can of course still edit that as much as you like). The reason we can do all of this is down to the use of LESS, so that we can parameterise our CSS to allow us to relatively quickly change the look and feel of the controls. 

Of course the Controls will still work in Webkit browsers as well, so if you aren’t using Unplugged then you can still use the controls to create mobile web applications. So we continue to support iOS, Android and mobile web deployments.

Now, to be honest, to do a good job, you have to be a “UI person”, but the stuff which Jack can do with these 100 or so settings looks really good. Our three different stock themes were created with just these settings. He talks about how to do that in our documentation.


So when you go to the Restyler website, you can create a theme (or several if you want), and see live what your changes will do to the controls. When you save the theme we generate a new CSS file and integrate it into two places. First, if you install Teamstudio Unplugged and sync your device to the Restyler site (by changing your user configuration settings) then you’ll see the changes you just made in our Sampler application. Or you can choose to download the file you just created so that you can merge the CSS into your own custom applications.

The final piece of work we did was to make the documentation a little easier to use. So now if you go to you get much nicer looking and hopefully easier to navigate documentation for each control along with a guide on how to use the Restyler.

So there we have it, three releases in one; new controls including new UI and a new sampler app, new restyler website that allows you to create custom themes and new documentation.

Logitech Ultrathin Keyboard Cover for iPad Air

I recently upgraded my iPad to the new iPad Air, it’s a huge difference in terms of performance and usability, but regardless of the touch based device I’ve never been able to type very fast on them.

I am able to access the email for one of my clients on the iPad which means I don’t have to log into the VPN to check everything is OK, it makes my life a lot easier, and since I’ve got this new Logitech Ultrathin Keyboard case for the iPad it’s even better. I can type pretty close to normal speed, even though the keys are smaller, they are *real*. So on my desk now I have the iPad sat on the keyboard as a reasonably good stand, that also allows me to type.

I can also envisage me using the keyboard and iPad at conferences and the such like, I’m typing this now sat on the sofa and it feels reasonably solid and saves me having to have the full laptop out. Even with the improved battery life of OS X Mavericks, I still don’t get a full day, whereas with the iPad I really can.

The other thing which the keyboard offers is some real improvements in terms of shortcut keys, so cut, copy and paste work as though I were on my laptop, the “Escape” key allows me to quickly switch between applications and I can use the keyboard to control media playback, volume etc. All in all, if you use your iPad for any sort of serious input rather than just as a consumption device then I’d highly recommend this.

Cross Domain Ajax Requests

I’m rather late to the party with this one, but I had always understood it to be the case that it was not possible to make cross domain ajax requests. That means that if I have JavaScript running on it can’t make a request to This was what JSONP was invented for and it worked fine, at least for GET requests.

But I’m in the process of writing an application which Mark and I are going to use in our IBM Connect session in January and I thought I’d investigate what the current options were. I’m very glad I did as there is now an officially supported option to allow cross domain ajax requests.

What we need to do is make a couple of configuration changes to the Domino server, and then also make sure that our ajax request is crafted very carefully indeed.

So first, the Domino server. I’m going to assume you’re running with Internet Sites enabled, so you open your internet site document and add a new Rule document from it.


In this example, I have set the rule to only apply to a single XPage in my application called api.xsp. You can obviously build your own rule here. The expires header I just left with the defaults and then the important bit is the custom headers. We add two here:

First is “Access-Control-Allow-Origin” which I have set to “*” but you can configure to only allow specific domains to make a remote ajax request from.

Second may or may not be needed depending on your situation. I am wanting to post JSON data to the XPage which I will then read and do something with. I found that if I didn’t add this second setting of “Access-Control-Allow-Headers” with a value of “Origin, X-Requested-With, Content-Type, Accept” that the server would throw an error of “Cannot use bufferedreader while servletinputstream is in use” when I tried to read the posted data.

The usual caveats apply about the configuration of this, run it past the significant admin in your life to make sure that no security vulnerabilities are being opened up. In my case I am creating a demo so am not too worried.

On the client side, your ajax request has to be very carefully crafted. I am using jQuery to do the POST for me in this format:

type: "POST",
url: "" + id,
data: JSON.stringify({"status":newstatus}), 
cache: false, 
complete: getMyRequests,
headers: { "Content-Type": "application/json"},
dataType: "json",
error: function(request, error) {

The key things to note are that the data property is wrapped with JSON.stringify and that the headers property has been completed.

Be aware that not all browsers support this. This article covers in detail the issues which you may face with IE8 and 9 (basically you’ll have to hand craft you’re own ajax requests rather than relying on a library).

The other thing which I discovered is that the REST services in the Extension Library do not honour the Web Site Rules, so they will not add the required headers. So if you want to do this you will have to hand craft your own REST service in Java. To be honest, having played with the Extension Library REST Services, they don’t do what I need anyway so it’s not a great hardship, but as ever YMMV.

Geeky buying spree

It’s been a bit of an expensive month on the tech front for me, some bits necessary, some not so much, but all, so far, good. So what were the additions to the White household?

First, were new iOS devices. I justify the new iPhone 5S and the iPad Air by the fact that I spend an ever increasing amount of time doing mobile development. The fact that they’re actually really nice devices is a by the by and should be ignored!

I also needed to finally invest in a NAS. I have been using a Drobo for years now and it’s fine, but it’s only USB and the prospect of a new Drobo chassis was looking quite expensive. So on the advice of Messrs Poole and Robichaux I checked out the Synology line of products. I ended up plumping for the DS413J and four Western Digital 2tb Red drives. It gives me 6 terabytes of storage which should keep us ticking over for quite a while. And along with a new gigabit switch for the home network it all pretty much flies along. The Drobo can also plug into the back of the NAS so I can either expand the amount of storage I need or add an extra layer of redundancy on my backups.

The last thing we’ve got is a new wireless speaker for the living room. This is basically heresy for my Sonos loving friends, but I’m not an audiophile and I was balking at the cost of starting a Sonos installation. It occurred to me that as an all Apple household, we’ve got music playing devices all over the place in the form of phones, tablets and laptops. So I invested in a wireless speaker which supports Airplay from Philips, the Fidelio AD7000W. It’s nice and discreet and produces good sound (to my ears anyway).

 And with that the credit card crawls back to its hiding place to recover.

End of the Pebble experiment

Steve’s woes overnight with his DOA Pebble watch reminded me that I was going to post an update on mine.

Like Steve, my first watch was DOA, it seems to be a fairly common occurrence, but to their credit a new one was sent out pretty quickly. So now, 9 months later, I find I can’t rely on mine. About 50% of the time the screen is pixelated to the point where I can’t read it which pretty much makes it a useless thing to be carrying around. I’ve also found the battery to be unpredictable, sometimes it will last a week, sometimes a day and I can’t see the pattern behind it.

So at his point I’m calling the Pebble an honourable failure. I actually enjoyed the Kickstarter process, but in this case the end product just wasn’t up to scratch.

Lessons learned with Jekyll and Github Pages

One of my projects at the moment has a requirement to create a semi static site for documentation to be hosted on Github. The fact you can do this in Github is great, but we wanted to make the documentation fit the rest of the application in terms of look and feel. So over the last week I’ve been created a Jekyll site which has a set of layouts and then a bunch of posts for content. In theory it’s a great way of creating these sorts of sites, but I found there were several peculiarities when using Jekyll in combination with Github Pages that weren’t immediately obvious.

So a little about my configuration first of all. I’m running a Mac with Mavericks installed, and I wanted to be able to do local testing of the pages. This involved several steps to get set up:

  1. Install Xcode, this is needed to install some of the command line tools we’re going to need later on.
  2. Once Xcode is installed then you need to install the command line tools (so that we can then install Ruby). I think this has been made more difficult, so I’m not sure how long these instructions will work, but as of November 2013, you need to open a terminal window and type:

    xcode-select -install
  3. Once that process has completed (it will all take a while), we need to install Ruby, so again from the terminal window:
    \curl -L | bash -s stable --ruby
  4. Again this may take some time, but once we’re done then we can create out Jekyll site.
  5. First we want to make sure we’ve got the appropriate Github project cloned to disk and then switched branches to the “gh-pages” branch. If it’s not been created then you can do this from the Settings page of the project on the Github website.
  6. Delete any content in the site, and navigate to the folder in your terminal window
  7. Now we’re going to generate an empty site:
    jekyll new my-site-name
  8. Once the site is generated, move the content into the root of the Github project folder
  9. Now we need to go and modify the _config.yml file. Now this is quite important and I’m very much a noob at this, so these settings are what work for me, YMMV:
    safe: true
    lsi: false
    pygments: true
    baseurl: /my-site-name
    markdown: rdiscount
    permalink: /docs/:title.html
  10. If you specify the markdown setting, you’ll also need to install the rdiscount Ruby Gem:
    gem install rdiscount
  11. You’ll also want to add a “.gitignore” file to the root of the folder and put in it:
  12. Now you can run the server, with a few extra switches so that it will live generate any changes that you make to the site:
    jekyll serve --watch --baseurl ''
  13. The baseurl switch is important because locally you want to run http://localhost:4000/index.html but on Github Pages you will be running, so the default setting is made in _config.yml and you’re overriding when starting your local server.
  14. Now you’ll want to create index.html, my suggestion is that you make use of the default.html file located in _layouts to control the look and feel of your site, just put content into the index.html page.
  15. And then you can start creating real content in the _posts folder.

Once you sync up to Github changes are not visible immediately they can take up to ten minutes to show, which is why you want the local server.

A few other bits and pieces that I learned after a bit of messing around:

  • Changes to the _config.yml file require you to restart the Jekyll server, everything else will be picked up live (if you’ve used the –watch switch)
  • I couldn’t work out how to host images, so you’ll need to put those up somewhere else, I use a public readable Amazon S3 bucket.
  • There are various chunks of code which Jekyll has for outputting lists of posts, but none of them matched what I needed so in the end I hard coded quite a lot of links. When building links, make sure to use this format:
    <a href="{{ site.baseurl }}/docs/MyPage.html">My Page</a>

    The baseurl is coming from the _config.yml file, the “/docs/” part is coming from the permalink, you can set this up however you want, but I found this easier than trying to use the date format links which there Jekyll site seems to recommend. The “MyPage.html” element is the file name of the post document.

  • Beware case sensitivity! On my local server it was forgiving of getting file name cases wrong, but Github is not so generous, that wasted several hours of my life!

Overall Github Pages with Jekyll is nice if you’re wanting a semi static, nice looking website, so perfect for documentation and lots of people seem to use if for blogs as well. Personally I found the whole thing a little painful to use, but each to their own!



Minor warning for upgrading to 9.0.1

I upgraded my dev server the other day, all went swimmingly it seemed. That is until this morning when I needed to do some work on an application which uses some slightly non standard Java. 

Part of the non standard-ness is that I had previously made changes to the java.policy file in the file system. So just a small reminder really, that these files get overwritten when the server gets upgraded, so bear it in mind if you have modified the files that you should make a backup of them before commencing the upgrade.

Submitting a long running Ajax request in XPages

This is definitely not best practice, but sometimes there is a need to fire an Ajax request which might take a long time, I have just come across just such a situation. In XPages, the default timeout for Ajax requests is 20 seconds, after that you get an alert which says there was a problem and would you like to submit the whole page. But what if you need to exceed that? 

Well it’s very simple really. Once the page loads, you just need to increase the timeout:

XSP.submitLatency = 30000;

The number is the timeout in milliseconds which you want to support. 

As I said, not best practice, but if you ever need it, then simple to do. 

OS X Audio Source Tip

I’ve recently got hold of a Plantronics Voyager Legend bluetooth headset so that I can wander round the home office a little more when on my (never ending) conference calls. 

It all seems to work nicely, except that Skype doesn’t really “see” it properly so I need to manually switch Audio sources at the OS level when I want to use it with Skype. This initially felt like a real faff; open System Preferences, open Sound, set the Output and then set the Input.

Screenshot 2013-10-31 09.28.06.png

This morning I was playing around and noticed that if I hold the Option key down while clicking the Sound option in the menu bar I see the different sound sources and can change them without having to go via Settings. 

It’s nice to find new tricks in an OS I’ve been using for decade. 


Today marks the end of Bruce Elgort’s time at the helm for OpenNTF

All of us in the Lotus community owe Bruce a lot, me more than most. I think a lot of people had the experience where Bruce introduced himself to you (shy chap that he is) and then proceeded to introduce you to everyone else in the world. That happened for me in the middle of the last decade, and it pretty much changed my professional life.


I had been bumbling along doing contracting work, on the fringes of the Lotus community, but we seemed to get on, we chatted a lot at Lotusphere and ILUG and from there, Bruce and I created IdeaJam and IQJam and we’ve been working together ever since. We won awards, and we have a nice little business where our software has been rolled out to hundreds of thousands of people all over the world.

But to be honest that’s not the most important thing about meeting Bruce. I made a friend, in fact Bruce was the Best Man at my wedding!

So #thanksbruce for everything you have done over the years for the Lotus community, and #thanksbruce for being a great friend. 

Clark College is very lucky to have you.