Speaking at Mastering SAP Technologies

Next week I’m travelling to Johannesburg, to attend and speak at the Mastering SAP Technologies conference. It’s a great honour to have been invited, and I’m excited at the prospect of the topics covered in the agenda.

I’m continuing my journey spreading the word about Fiori and UI5. Last November I was in Sydney giving a locknote, a workshop and speaking at an executive lunch, at the SAP Architect & Developer Summit. A couple of weeks ago it was a short trip to Brussels to speak about OpenUI5 at FOSDEM, and now at Mastering SAP I have three slots. Here’s the description of each of them.

Keynote: Can I Build a Fiori App? Yes You Can!

Fiori is not just the new UX-focused, role-based application paradigm from SAP, it’s also a set of technical constraints coupled with a rich but finite set of design patterns for UI. Most importantly it’s made possible by certain parts of the SAPUI5 toolkit that were specifically built with Fiori in mind. (In fact, the first customers of the sap.m library in SAPUI5 were the SAP Fiori developers themselves). This session tells you what you need to know to build a Fiori app.

Tips & Tricks from the Trenches of a Fiori/UI5 Developer

Developing Fiori and UI5 apps with the UI5 toolkit is different than what you’re used to. Different generally because it’s HTML5 based, and different specifically because it’s UI5. Learn the tips and tricks that I use on a daily basis, and get to know how to drive, modify and extend Fiori/UI5 apps from the command line console of Chrome’s developer tools. Master UI5 debugging and maintenance from within the browser and get a step ahead.

Workshop: Building an SAP Fiori-like App From (Almost) Scratch – Hands On!

Starting from a skeleton app that has a structure but minimal content, and an OData or JSON data source, we build together a working Fiori app with SAPUI5. We cover bootstrapping the SAPUI5 toolkit, the Component-based approach to development, Model-View-Controller based development, XML views, navigation, data binding, model operations and more. This is similar to the Open Source Convention (OSCON) hands-on session I co-presented in Portland, June 2014, and the CD168 hands-on sessions I co-built & co-presented at SAP TechEd in 2013 (which were sold out / overbooked many times).

Perhaps I’ll see some of you there. In any case, share & enjoy!

Fiori & UI5 Related Videos

I thought it would be worth collecting together a lightly annotated list of Fiori and UI5 public videos that I’ve published on my YouTube channel. (I say public, as there are quite a few OpenUI5 related videos still marked as private, waiting in the wings … watch this space!)


Fiori Apps Reference Data into a Spreadsheet 09 Jan 2015
Pulling the Apps info from the OData service used by the SAP Fiori Apps Library app into a Google spreadsheet. More info here: Fiori App Data into a Spreadsheet? Challenge Accepted!


YAML Model for UI5 20 Dec 2014
I scratched an itch and built a simple YAML Model implementation for UI5. More info here: https://github.com/qmacro/YAMLModel

Creation & Reload of UI5 UIs in the Chrome Developer Console 24 Nov 2014
Following my workshop session at the SAP Architect & Developer Summit, this screencast shows the creation of a quick UI, using the manual Chrome Developer Console techniques we learned, and the subsequent export and reload as XML. (I recorded this at Sydney airport on the way back from the summit).

SAP Fiori Rapid Prototyping: SAP Web IDE and Google Docs 05 Nov 2014
With the power of the SAP Web IDE and its plugin / template architecture, we can create custom templates that allow you to create Fiori apps based on all sorts of data sources, in this case, a Google Spreadsheet.

SAP Web IDE Local Install – Up and Running (3-video playlist) 27 Oct 2014
SAP made available its Web IDE as a locally installable service in Oct 2014. This short series of videos shows you how to get up and running with it.

SAP Fiori & UI5 Chat, Fri 17 Oct 2014 17 Oct 2014
Brenton O’Callaghan and I have a 30 min chat about SAP Fiori and the new, unofficial SAP Fiori App that gives information about the available SAP Fiori Apps.

UI5 Icon Finder 14 Sep 2014
A very quick screencast of an “Icon Finder” app that remembers your own word associations you make, so you can more easily find the icons next time. See Scratching an itch – UI5 Icon Finder for more info.

OpenUI5 MultiComboBox First Look 25 Jul 2014
A first look at the sap.m.MultiComboBox in OpenUI5 version 1.22. Note that the addition of a key for the root element is not entirely necessary (but probably what you might want). I wrote more about this here Keyed vs Non-Keyed Root JSON Elements & UI5 Binding.

The SAP Fiori App Analysis application 30 Jun 2014
A short overview of the SAP Fiori App Analysis app, written itself as a Fiori style app. In this overview I show the source for the information (the SAP help documentation), mention how I convert the gathered spreadsheet data into a more easily consumable form, and explore the app a little bit too.

DSON (Doge Serialized Object Notation) Model mechanism for UI5. So model, wow! 06 Jun 2014
A bit of fun for a Friday late afternoon, and it helped me to play about with extending existing client models in the sap.ui.model library set.

Manipulating UI5 Controls from the Chrome Dev Console 17 May 2014
Just a quick screencast to show how easy it can be to find, grab, manipulate and create controls in a UI5 application from the Chrome Developer Console.

Simple Workflow App with UI5 13 Apr 2014
This is a quick screencast of the app I wrote for the basis of my chapter in the SAP Press book Practical Workflow 3rd Edition.

Coding UI5 in JSBin 11 Apr 2014
A quick recap of what we did during the UI5 Mentor Monday in March 2014, showing how easy it is to construct good looking UIs with UI5, and also the great facilities of JSBin – creating, viewing and sharing HTML CSS and JavaScript snippets with live rendering.

Mocking Up the Payroll Control Center Fiori App 14 Feb 2014
There was a blog post on the Payroll Control Center Fiori app and I decided to mock the UI up directly. This video shows me doing that.

#UI5 Control on the Screen, Quick 12 Feb 2014
There was a conversation about how fast you could get a UI5 control on the screen. I decided to try to see how fast it could be.

Using Gists on Github to share code 09 Jan 2014
This screencast relates to a document on SCN “Help Us To Help You – Share Your Code” that describes how and why you should share your code that you want help with, using Gists on Github.


SublimeUI5 – Snippets & Templates for SAPUI5/OpenUI5 19 Dec 2013
SublimeUI5 is a package for Sublime Text 2 for developing SAPUI5 / OpenUI5 applications. There are two parts to it – a series of snippets and some basic application templates to help you quickly get started with complete MVC-based running apps. (I don’t maintain this package any more but you’re welcome to take it over!).

SAPUI5/Fiori – Exploration of an App 22 Nov 2013
An exploration of a custom Fiori app and the SAPUI5 controls that are used to build it. For the full context of this, see the 2-part SAP CodeTalk – SAPUI5 and Fiori playlist.

SAP Fiori-style UI with SAPUI5 06 Nov 2013
This was a short video to show the sort of thing that attendees of our SAP TechEd 2013 Session CD168 “Building SAP Fiori-like UIs with SAPUI5” would be building.


Re-presenting my site with SAPUI5 13 Dec 2012
A short demo of an experiment I carried out to explore SAPUI5 and learn more about it. I really like the Shell component as a user interface paradigm and decided to see if I could re-present the content of my home page and weblog using SAPUI5 and specifically the Shell. It seemed to work out OK.

Stupid Firebase and SAPUI5 tricks 14 Apr 2012
Saturday evening hacking around with Firebase, the command line, and an SAPUI5 Data Table. Fairly pointless but interesting nonetheless. Firebase uses websockets for realtime data streaming to your browser-based app, and you can interact with the JSON data with HTTP. Every piece of data has a URL. Now that’s nice.

SAPUI5 and OData 12 Feb 2012
I looked at the data binding support for OData based data sources (such as those exposed by SAP NetWeaver Gateway!) in the (then relatively) new SAPUI5 toolkit. I also wrote this up on SCN: “SAPUI5 says “Hello OData” to NetWeaver Gateway“.

Morning Fiori Fix

John Moy tweeted today about the Fiori App Reference Library showing duplicate entries recently. It’s something I’d noticed too, after checking the app following the publication of information on SCN about new Fiori apps on the post “New Fiori Apps for HCM” last week.

I’m not 100%, so earlier this morning I needed a bit more time than usual to get my brain in gear. So with a coffee I decided to spend a few mins hacking the list display. It’s not a permanent solution of course, but at least demonstrates that there are properties in the Apps entity that can be used to distinguish the “duplicate” entries. Should be a quick fix (yes, pun intended!) for the Fiori Implementation eXperience folks to carry out.

Here’s a quick screencast as an animated GIF (why not?)


Right, on with the morning.

OpenUI5 at FOSDEM 2015

I just returned from FOSDEM, the conference for free and open source software developers that’s held annually in Brussels. It’s a super event that has a long pedigree already, and has managed to remain true to the hacker culture and spirit that pervades the open source world. Innovation, scrutiny, sharing and collaboration are the bywords of this culture.

I have attended FOSDEM a number of times over the years; in the early days in my capacity as a Jabber / XMPP programmer, and these days more generally, but this time it was specifically about OpenUI5.

IMG_20150202_080814SAP’s open sourced UI development toolkit for HTML5 is SAPUI5’s twin with an Apache 2.0 licence. SAPUI5 is the basis for SAP’s UI innovation and with what SAP Fiori apps are built. Although still relatively young, it’s a very accomplished toolkit, and one I was eager to share with the open source developer community at large.

I spoke on the subject of OpenUI5 in this talk:

A Whirlwind Introduction to OpenUI5

and it was very well received; the room was packed and there was some great feedback. It wasn’t difficult talking about a product from such a great team, although to add extra spice, I’d decided not to use any slides, and instead, do some live coding on stage.

IMG_20150202_080838I had deliberately set myself up for a fall, showing how difficult it can be to built hierarchies of controls in JavaScript, which then set the scene for my favoured approach of defining views declaratively, with XML being my favourite flavour in that vein. Luckily the audience seemed to appreciate the in-joke, and not everyone thought I was an idiot :-)


I’ve made the source code of the app I built on stage available on Github, in the fosdem-2015-openui5 repository.

The SAP folks had an OpenUI5 booth at FOSDEM too which was staffed by a few of the real UI5 developers, so the conference attendees were able to learn first hand about the toolkit from the source. The booth saw a nice increase in traffic after my talk, which is a great sign.

SAP has had a presence at many conferences in the past few years, but this one resonates particularly with me, as some folks might think that the SAP and open source worlds are far apart. How wrong they are. Onwards!

Picture credits: Denise Nepraunig, Jan Penninkhof, Martin Gillet – thanks!

Atom, Snippets, Tabs and CSON parsing

This morning on the train down from Manchester to Bristol I fired up the Atom editor and noticed that when trying to load a snippets file from my ui5-snippets package, I got an error:

Screen Shot 2015-01-19 at 08.18.19

Between Stafford and Wolverhampton I hacked around with the source, particularly the html.cson file that contained a number of UI5 snippets for HTML files. From where was this error message emanating, and why now?

Well, it seems that a few days ago, in release 0.171.0, Atom had moved from parsing CoffeeScript Object Notation (CSON) with cson, to parsing with cson-safe. CSON is the format in which snippets can be written. Moving to cson-safe meant that the parser was rather stricter and was the source of the “Syntax error on line 4, column 11: Unexpected token” error.

By the time we’d got to Birmingham, I’d figured out what it was: tabs. In wanting to move in the direction of the UI5 coding standards, I’d started moved to tabs for indentation within the UI5 snippets, as you can see in this openui5 starter snippet. While the original cson parser used by Atom was fine with real tabs in the snippet source file, cson-safe didn’t like them.

Switching the tabs to literal “\t” tab representations (i.e. backslash then ‘t’) solved the issue.



Fiori App Data into a Spreadsheet? Challenge Accepted!

In October last year, following the original meta SAP Fiori App ;-), SAP announced their own long-awaited SAP Fiori Apps Reference Apps Library. At the time, Brenton and I chatted about it in “SAP Fiori & UI5 Chat, 17 Oct 2014“.

Today there was a comment in the announcement post, asking whether there was “any way this information can be supported via a downloaded (into Excel perhaps)?  It would make sorting and filtering much easier“.

Seeing as one of the technical guidelines for Fiori apps is the use of an OData service to supply the domain data, and I had a bit of time over lunch, the well known phrase “Challenge Accepted!” floated into my consciousness.

With the power of OData, JSON, Google Apps Script and the generally wonderful cloud productivity platform that is Google Apps, I set to work, and within a short amount of time, the challenge was completed.

Here’s a video with all the details. The spreadsheet is here,

Share and enjoy!


Running: 2014 in review, and some Clojure

I enjoyed running in 2014 and logged each one via Endomondo. This post is a random collection of thoughts about the running, the data and some simple analysis, in Clojure.


Garmin Forerunner 110

Garmin Forerunner 110

I’ve been using a Garmin Forerunner 110 watch which has been very good, on the whole, although the USB cable and connectivity left something to be desired.

I bought my wife Michelle a TomTom Runner Cardio for her birthday back in August, and have been intrigued by it ever since. And she bought me one for Christmas, so I’m trying that out for 2015. I went out on my first run of this year with it just this morning, in fact.

Run data

But back to 2014. I completed 101 runs (1,281.22km) and they’re all logged in Endomondo. I don’t have the premium subscription, just the basic, but the features are pretty good. There’s an option to upload from the Garmin watch, via a browser plugin which (on this OSX machine) has become pretty flakey recently and now only works in Safari, but once uploaded, the stats for each run are shown rather nicely:

A run on Endomondo

A run on Endomondo

Endomondo also offers simple statistics and charts, and a tabular overview of the runs, that looks like this:

Tabular view of runs in Endomondo

Tabular view of runs in Endomondo

One thing that bothered me, at least with the free service, is that there was no option to download this data. So I paged through the tabular data, and copy/pasted the information into a Google Sheet, my favourite gathering-and-stepping-off point for a lot of my data munging.

Running history in a Google Sheet

Running history in a Google Sheet

If nothing else, as long as the data is largely two dimensional, I’ve found it’s a good way to visually inspect the data at 10000 feet. It also affords the opportunity for some charting action, so I had a look at my pace over the year, to see how it had improved. This is the result:

Pace improvement in 2014

Pace improvement in 2014

The three peaks in Feb, Jun and Sep are a couple of initial runs I did with Michelle plus her first 8km in London (now she’s in double km figures and has a decent pace, I’m very proud of her).

Some Analysis in Clojure

I could have gone further with the analysis in the spreadsheet itself, but I’m also just starting to try and teach myself Clojure, and thought this would be a nice little opportunity for a bit of data retrieval and analysis.

Exposing the data

Start of the JSON representation of the run data

Start of the JSON representation of the run data

Of course, the first thing to do was to make the data in the Google Sheet available, which I did with my trusty SheetAsJSON mechanism. It returned a nice JSON structure that contained all the data that I needed.

So now I had something that I could get Clojure to retrieve. Here follows some of what I did.

Creating the project

I’m using Leiningen, which is amazing in a combined couple of ways: it Just Works(tm), and it uses Maven.  My only previous experience of Maven had me concluding that Maven was an absolute nightmare, but Leiningen has completely changed my mind. Although I don’t actually have to think about Maven at all, Leiningen does it all for me, and my hair is not on fire (for those of you wondering, Leiningen’s tagline is “for automating Clojure projects without setting your hair on fire”, which I like).

So I used Leiningen to create a new application project:

lein new app running-stats

and used my joint-favourite editor (Vim, obviously, along with Atom), with some super Clojure-related plugins such as vim-fireplace, to edit the core.clj file. (more on my Vim plugins another time).

Here’s a short exerpt from what I wrote:

Screen Shot 2015-01-03 at 12.51.47

Let’s look at this code step by step.

Library use

I’m using Clojure’s data.json library (line 2) to be able to parse the JSON that my SheetAsJSON mechanism is exposing. I’m also using the clj-http HTTP client library (line 3) to make the GET request. Finally I’m using the clojure.walk library (line 4) for a really useful function later on.

I decided to churn through step by step, which is why you’re seeing this code in four chunks, each time using the def special form to create a var in the current namespace.

Creating stats

There’s stats (line 6), which has the value of the parsed JSON from the body of the response to the HTTP GET request. To unravel lines 6-9 we have to read from the inside outwards.

First, there’s the call to client/get in line 9 (the clj-http library is aliased as client in line 3). This makes the HTTP GET request and the result is a Persistent Array Map that looks something like this:

running-stats.core=> (client/get "http://bit.ly/qmacro-running-2014")
{:cookies {"NID" {:discard false, :domain ".googleusercontent.com", :expires #inst "2015-07-05T12:23:49.000-00:00", :path "/", :secure false, :value "67=EUPTfvAv3U5Vofm1F3Fb_D9OjmwYS1yC3Ju-uvgostmqzKSNLHKHiHGMc-cwFBAES0R3qcLFQW7W75x6sZjSzein3H7Trxeg6Bk0wOJ0q-AaYXA0RxYw0-uEhR5ogaXg", :version 0}}, :orig-content-encoding nil, :trace-redirects ["http://bit.ly/qmacro-running-2014" "https://script.googleusercontent.com/macros/echo?user_content_key=jmP
5, :status 200, :headers {"Server" "GSE", "Content-Type" "application/json; charset=utf-8", "Access-Control-Allow-Origin" "*", "X-Content-Type-Options" "nosniff", "X-Frame-Options" "SAMEORIGIN", "Connection" "close", "Pragma" "no-cache", "Alternate-Protocol" "443:quic,p=0.02", "Expires" "Fri, 01 Jan 1990 00:00:00 GMT", "P3P" "CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"", "Date" "Sat, 03 Jan 2015 12:25:02 GMT", "X-XSS-Protection" "1; mode=block", "Cache-Control" "no-cache, no-store, max-age=0, must-revalidate"}, :body "{\"Year-2014\":[{\"Date\":\"2014-01-02T00:00:00.000Z\",\"Description\":\"First run of 2014\",\"Distance\":\"13.50 km\",\"Time\":\"1h:13m:51s\",\"Avg_Speed\":\"11.0 km/h\",\"Avg_Pace\":\"5:28 min/km\",\"Avg_HR\":168,\"Distance_Value\":13.5,\"Pace_Value\":\"1899-12-30T05:28:00.000Z\",\"Pace_Val_Mins\":5,\"Pace_Val_Secs\":28,\"Pace_In_Secs\":328,\"Month_of_Run\":1},{\"Date\":\"2014-01-05T00:00:00.000Z\",\"Description\":\"Wet and windy Copster Hill.\",\"Distance\":\"14.05 km\",\"Time\":\"1h:16m:31s\",\"Avg_Speed\":\"11.0 km/h\",\"Avg_Pace\":\"5:27 min/km\",\"Avg_HR\":169,\"Distance_Value\":14.05,\"Pace_Value\":\"1899-12-30T05:27:00.000Z\",\"Pace_Val_Mins\":5,\"Pace_Val_Secs\":27,\"Pace_In_Secs\":327,\"Month_of_Run\":1},{\"Date\":\"2014-01-08T00:00:00.000Z\",\"Description\":\"Brookdal [...]

Quite a bit of a result. Looking at the keys of the map, we see the following, which should be somewhat familiar to anyone who has made HTTP calls:

running-stats.core=> (keys (client/get "http://bit.ly/qmacro-running-2014"))
(:cookies :orig-content-encoding :trace-redirects :request-time :status :headers :body)

There we can see the :body keyword, which we use on line 8 as an accessor in this collection. With this, we get the raw body, a string, representing the JSON:

running-stats.core=> (:body (client/get "http://bit.ly/qmacro-running-2014"))
"{\"Year-2014\":[{\"Date\":\"2014-01-02T00:00:00.000Z\",\"Description\":\"First run of 2014\",\"Distance\":\"13.50 km\",\"Time\":\"1h:13m:51s\",\"Avg_Speed\":\"11.0 km/h\",\"Avg_Pace\":\"5:28 min/km\",\"Avg_HR\":168,\"Distance_Value\":13.5,\"Pace_Value\":\"1899-12-30T05:28:00.000Z\",\"Pace_Val_Mins\":5,\"Pace_Val_Secs\":28,\"Pace_In_Secs\":328,\"Month_of_Run\":1},{\"Dat [...]

Now we need to parse this JSON with the data.json library, which we do in line 7. This gives us something like this:

running-stats.core=> (json/read-str (:body (client/get "http://bit.ly/qmacro-running-2014")))
{"Year-2014" [{"Pace_Val_Secs" 28, "Distance_Value" 13.5, "Date" "2014-01-02T00:00:00.000Z", "Month_of_Run" 1, "Description" "First run of 2014", "Distance" "13.50 km", "Avg_Speed" "11.0 km/h", "Pace_Val_Mins" 5, "Pace_Value" "1899-12-30T05:28:00.000Z", "Avg_Pace" "5:28 min/km", "Time" "1h:13m:51s", "Pace_In_Secs" 328, "Avg_HR" 168} {"Pace_Val_Secs" 27, "Distance_Value" 14.05, "Date" "2014-01-05T00:00:00.000Z", "Month_of_Run" 1, "Description" "Wet and windy Cop [...]

which is eminently more useable as it’s another map.

Although it’s a map, the keys are strings which aren’t ideal if we want to take advantage of some Clojure idioms. I may be wrong here, but I found that converting the keys into keywords made things simpler and felt more natural, as you’ll see shortly.

The Year-2014 data set

Lines 11-13 is where we create the Year-2014 var, representing the data set in the main spreadsheet tab.

Looking up the “Year-2014″ key in the stats (line 13) gave me a vector, signified by the opening square bracket:

running-stats.core=> (stats "Year-2014")
[{"Pace_Val_Secs" 28, "Distance_Value" 13.5, "Date" "2014-01-02T00:00:00.000Z", "Month_of_Run" 1, "Description" "First run of 2014", "Distance" "13.50 km", "Avg_Speed" "11.0 km/h", "Pace_Val_Mins" 5, "Pace_Value" "1899-12-30T05:28:00.000Z", "Avg_Pace" "5:28 min/km", "Time" "1h:13m:51s", "Pace_In_Secs" 328, "Avg_HR" 168} {"Pace_Val_Secs" 27, "Distance_Value" 14.05, "Date" "2014-01-05T00:00:00.000Z", "Month_of_Run" 1, "Description" "Wet and windy Copster Hill.",

The vector contained maps, one for each run. Each map had strings as keys, so in line 12 I used the keywordize-keys function, from clojure.walk, to transform the strings to keywords. Here’s an example, calling the function on the map representing the first run in the vector:

running-stats.core=> (keywordize-keys (first (stats "Year-2014")))
{:Pace_Value "1899-12-30T05:28:00.000Z", :Month_of_Run 1, :Distance_Value 13.5, :Distance "13.50 km", :Avg_HR 168, :Avg_Pace "5:28 min/km", :Pace_Val_Mins 5, :Pace_Val_Secs 28, :Date "2014-01-02T00:00:00.000Z", :Description "First run of 2014", :Time "1h:13m:51s", :Avg_Speed "11.0 km/h", :Pace_In_Secs 328}

I assigned the resulting value of this call to a new var Year-2014.

Getting the HR values

The Garmin Forerunner 110 measures heart rate (HR) via a chest strap, and an average-HR detail is available for each run:

running-stats.core=> (:Avg_HR (first Year-2014))

There were a few runs where I didn’t wear the chest strap, so the value for this detail on those runs was a dash, rather than a number, in the running statistics on the Endomondo website, which found its way into the spreadsheet and the JSON.

running-stats.core=> (count (filter (comp not number?) (map :Avg_HR Year-2014)))

Yes, six runs altogether without an average HR value. So to get the real average HR values, I just needed the ones that were numbers. I did this on lines 15-17.

By the way, composing with the comp function sort of makes me go “wow”, because I figure this is revealing a bit of the simplicity, depth and philosophy that lies beneath the scratch mark I’ve just made in the surface of functional programming in general and Clojure in particular.

Average HR

I took the average of the HR values in line 21. This actually returned a Ratio type:

running-stats.core=> (/ (reduce + HR-values) (count HR-values))
running-stats.core=> (type (/ (reduce + HR-values) (count HR-values)))

This was interesting in itself, but I wanted a value that told me something, so I called the float function in line 20:

running-stats.core=> (float (/ (reduce + HR-values) (count HR-values)))

(Yes, I know taking the average of averages is not a great thing to do, but at this stage I’m more interested in my Clojure learning than my running HR in 2014).

And more

I did continue with my analysis in Clojure, but this post is already long enough, so I’ll leave it there for now. If you got this far, thanks for reading! I hope to teach myself more Clojure; there are some great resources online, and the community is second to none.

If you’re thinking of taking the plunge, I’d recommend it! I’ll leave you with a quote from David Nolen at the end of his talk “Jelly Stains. Thoughts on JavaScript, Lisp and Play” at JSConf 2012:

“[Dan Friedman and William Byrd] got me realising there’s a lot more left to play with in Computer Science”.

As I embark upon my journey in this direction, I realise that’s a very true statement. It’s like learning programming all over again, in a good way!



DNA is still in our DNA

Via a tweet that was retweeted by Ben Nuttall, I came across a recent article in the Independent “Microsoft to replace Internet Explorer with new, streamlined browser“. The article has some classic sentences that made me groan with displeasure, not least the lead:

“Codenamed Spartan, the new app will look much more like competitors Chrome and Firefox”

which completely misses the major point in that it’s not how IE *looks*, it’s how it *behaves*.

Anyway, the sentence that most caught my eye was this one:

In the past the company has considered changing the name to separate the current browser from “negative perceptions that no long reflect reality”

This very much reminds me of a passage from Douglas Adams’s Hitch Hiker’s Guide To The Galaxy, specifically from Episode 11:

The problem of the five hundred and seventy-eight thousand million Lintilla clones is very simple to explain, rather harder to solve. Cloning machines have, of course, been around for a long time and have proved very useful in reproducing particularly talented or attractive – in response to pressure from the Sirius Cybernetics marketing lobby – particularly gullible people and this was all very fine and splendid and only occasionally terribly confusing. And then one particular cloning machine got badly out of sync with itself. Asked to produce six copies of a wonderfully talented and attractive girl called “Lintilla” for a Bratis-Vogen escort agency, whilst another machine was busy creating five-hundred lonely business executives in order to keep the laws of supply and demand operating profitably, the machine went to work. Unfortunately, it malfunctioned in such a way that it got halfway through creating each new Lintilla before the previous one was actually completed. Which meant, quite simply, that it was impossible ever to turn it off – without committing murder. This problem taxed the minds, first of the cloning engineers, then of the priests, then of the letters page of ’The Sidereal Record Straightener’, and finally of the lawyers, who experimented vainly with ways of redefining murder, re-evaluating it, and in the end, even respelling it, in the hope that no one would notice.



The Inaugural SAP Architect & Developer Summit

Update: This has also been published on the Bluefin Solutions website

I was honoured to have been invited to speak at the inaugural SAP Architect & Developer Summit which happened last week (20-21 Nov 2014) in Sydney. It was a fantastic event, mainly due to the people and the content, but also because it hit a sweet spot between different types of SAP developer events.

The summit was the first of its kind to be organised by SAP, and judging from the feedback from the attendees there and then, combined with my own experience, it was a huge success. It was held over a two day period in the centre of a hotbed of SAP architect and developer talent, with folks converging on the wonderful Australian Technology Park in Sydney from all over the region, plus various additions from the UK, USA and elsewhere.

The Australian Technology Park was almost the perfect setting, being based on a centre of technology (heavy transport and industry) from the last millenium, a centre that proudly displayed historical, and some still-working physical artifacts, reminding me a lot of the Museum of Science & Industry back home in Manchester.

The Summit

Falling directly after SAP TechEd Berlin, firmly within the SAP tech conference season, the summit attracted over 300 attendees. There were a number of reasons for this being a great event to attend – the style was a sweet-spot between different sized events, it was priced well, and the content was just right.

Sweet Spot

There’s the daddy of all SAP conferences, SAP TechEd && d-code, and then at the other end of the scale there are grass roots community-organised types such as CodeJams and InsideTracks. While the former extends, with the InnoJam pre-event, to more or less a week, and the latter often being single-day affairs, this summit hit the sweet spot in between, finding a great balance between time and content.

Price Point

This was one of those unusual events where the travel and accommodation costs, even for those relatively local, were more than the event itself. (Because I was speaking, SAP covered my costs – thank you!). This is significant; a price point of AUD 695.00 (around GBP 385.00) combined with the agenda means that it was hard to resist.

People & Content

The two most important ingredients of course for any event are the people and the content, often going together. Here are just a few of the hands-on workshop items from the agenda:

  • Developing SAP HANA Native Applications with SAP HANA Cloud Platform (Thomas Jung)
  • Designing SAP Fiori Custom Applications (Kynan Jones & John Patterson)
  • SQLScript – Push Code Down into SAP HANA to Achieve Maximum Performance (Rich Heilmann)
  • Advanced OData Service Development with SAP Gateway (Mustafa Saglam)
  • Build SAP HANA Cloud Applications which Integrate with On-Premise Systems (Chris Paine)

With those sessions typical of the quality and content, given by those people, you know it’s going to turn out well.

Just as significant as the agenda were the conversations to be had with the amazing folk that were there too. Trying to name them all would be an exercise in futility; suffice it to say that the large majority of what I’m going to call the “ANZ SAP Mob” (in reference to the “Dutch SAP Mafia”) were there, which for me was reason enough to attend. To be able to learn from conversations with these people was priceless.

My Contribution

I was lucky enough to be able to contribute in three ways to this summit.


I gave a keynote at the end of Day 1 (called a “locknote” – who knew?) entitled “Fiori and UI5 Software Logistics, or: Are We in the Future Yet?“.

My aim was to convey the idea that in the SAP development world, we’ve been heretofore shielded from and largely unaware of one of the most important parts of software development – the artifacts.

You could perhaps think of artifacts as the tangible results of our mental machinations, a developer currency that we grow, discuss, exchange and share. And with the advent of Fiori and UI5 development, we should think explicitly about how we should nurture these artifacts to be the best we can make them, and in doing that, embrace tools available outside the traditional SAP developer ecosphere. Tools such as linters, editors, workflow mechanisms and source code control systems. In particular, I focused on git and Github Workflow.


On Day 2 I held a 2 hour hands-on workshop entitled “Learn to Drive Fiori Applications from Underneath and Level Up!“.

Workshop booklet screenshot

In this workshop I took the attendees (the workshop was fully booked!) through a Fiori application, from underneath, discovering it, controlling it, driving it and modifying it via the Chrome Developer Tools. There was a lot of content to get through but we managed it, not least due to the fact that everyone got on board with the approach and really did a great job in collaborating and keeping up with me. Thanks folks!

When I was preparing the workshop booklet, it took on a life of its own, so much so that it turned into a standalone 48-page mini-publication so that anyone who had it could follow through everything I wanted to teach, even after the workshop. And I’m making that workshop booklet available to everyone so that they can all benefit:

Workshop Booklet: Learn to Drive Fiori Applications from Underneath and Level Up!

If you would like to leave any feedback please go ahead and do that at the end of this post.

Executive Lunch

On Day 1 there was an Executive Lunch event with folks from all around the Australia and NZ region. I spoke on the new development paradigm that Fiori and UI5 has ushered into the SAP developer world, and gave an impromptu demonstration on UI5 development, building a simple app as they ate their lunch :-)

The Future

I hear that SAP ANZ are planning to run this event again next year, which is great. The aim is to attract more attendees, which is also great. But there’s also a balance to be maintained; the synergy, the timing of two full days, the ability to talk to everyone, was, in my opinion, just right.

I’m really hoping that this event has a future, stays roughly true to this inaugural incarnation, and spreads to other areas around the globe. If one came to Europe, I’d sign up immediately and encourage my fellow SAP hackers to do the same.

Well done to all the team for organising this, and thanks to all the superheroes that attended and shared knowledge and experience. We are architects and developers. Learning from one another and sharing with one another is what we do.


Creation & Reload of UI5 UIs in the Chrome Developer Console

At the inaugural SAP Architect & Developer Summit last week, one of the things that I did was prepare and deliver a 2 hour hands-on workshop: “Learn To Drive Fiori Applications From Underneath And Level Up!“. This was a fun and successful workshop which focused on working within, and using the tools of, the powerful Chrome Developer Console. It triggered great conversations afterwards with some folks, including fellow SAP Mentor Matt Harding, who also tweeted:

Screen Shot 2014-11-24 at 14.58.39

One of the strands of the conversation with Matt, Nigel James & others was regarding the potential transient nature of the definition of views, or other smaller UI elements, created while working within the console. In the console you can quite easily build views in JavaScript (as the console is a JavaScript console!). Building machine readable, declarative views such as those based on XML or JSON is a little bit more cumbersome.

However, with a great feature of the UI5 Support Tool – Export to XML – we can indeed have our UI declared for us in XML, which is rather useful! Not only that, but we can then iterate by loading that generated XML back into Chrome.

While at SYD airport just now, waiting for my flight back home, I recorded a quick screencast to illustrate this. It shows the creation of a quick UI, using the manual console techniques we learned in my workshop. Then, the UI is exported as XML, which the Support Tool duly does for us, inside an XML View container. That exported XML View is then reloaded, and we can see of course that it is faithful to what was originally created.

Share & enjoy!