Category Archives: General

Quick HCP title hack with the Navigation Manager

One of the great things about the new SAP is that it has embraced open standards and protocols, and is building the UX and UI present and future on HTML5. A by-product of that is the ability to see how they’re building things and make, or suggest, changes.

At SAP Inside Track Sheffield last year, one of the sessions I gave was “Fixing up a nicer HCP Destinations table”, where I showed the power of UI5 introspection and the Chrome Developer Tools that enabled us to modify the surface upon which we were standing, to improve things. I re-recorded my session as a video here, in case you’re interested:

Fixing the HCP cockpit titles

Anyway, there’s something else that’s been niggling me a bit while using the HANA Cloud Platform (HCP) cockpit. And that’s the inability to see which tabs in my Chrome browser are open at what particular areas of the cockpit. Due to the way each location’s title text is structured, all the tabs look the same – at least at the start. It’s only when you hover over them you see what a given tab contains.

Here’s an example:

Screen Shot 2016-03-28 at 11.42.06

It’s only when hovering over the first tab that I see that it’s showing the HTML5 Applications part of the cockpit. If I’m looking to switch to that tab, the search for the correct one is painful.

So I wanted to take a quick look to see where this title was being set, and when. I used the Chrome Developer Tools’ DOM breakpoints feature to halt when the <title> element was changed:

Screen Shot 2016-03-28 at 11.46.08

This led me to a section of the HCP cockpit code that inside the Navigation Manager (cockpit.core.navigation.NavigationManager), in a function called “navigate”. This is what the code that sets the title looks like (I took the liberty of formatting it a little bit better for readability):

Screen Shot 2016-03-28 at 11.49.41

You can see how the title string is constructed – with the most significant part (current.navigationEntry.getTitle()) buried deep within it.

A small change to this code, so it looks like this:

Screen Shot 2016-03-28 at 11.49.54

brings the most significant part to the front, meaning that now I can see what tab contains what HCP cockpit feature – at a glance:

Screen Shot 2016-03-28 at 11.30.28

I think that’s a nice improvement. Personally, I’d love to see this make it into a future release. What do you think?



Impromptu JS session at UKISUG15

We’re hearing a lot about Fiori at #UKISUG15 this year, of course. Many of you (perhaps especially those reading this) realise that Fiori is built using the power of HTML5, and specifically with the UI5 toolkit. This means, amongst other things, JavaScript.

I was talking to my friend and colleague and fellow SAP Mentor Chris Kernaghan on the evening of Day 1 about levelling up in JavaScript, and had planned to go through some JavaScript goodness with him during the conference. But then I thought it might be fun for others to come along too. So here’s the (rough) plan:

– meet at the Bluefin Solution stand on the show floor on Tue 24 Nov (last day of #UKISUG15) at 1300 (should give you time to grab a bit of lunch first) if you’re interested in coming along (that’s TODAY, folks!)

– we’ll find (or will have found) a room to use – probably Level 5 Hall 8b (the SAP Mentors Track room)

– the session will be between 30 and 45 mins max

This session will be for those already with some basic JavaScript skills, and / or those interested in using JavaScript to manipulate data inside an SAP Fiori app. Even if you have no JavaScript skills, you might find it interesting. And if you don’t, you can always just laugh at me.

The session is titled “Programming in a more functional style in JavaScript” and we’ll go through handling and manipulating data from a running Fiori app. Handling and manipulating data like this is a common use case. Becoming more familiar with doing this will help you build your skills and confidence in the future normal of SAP frontend development. Learning to do this in a functional way will give you a basis to write more solid and reliable code.

See you at the Bluefin stand at 1300 today!

Speaking at SAP TechEd EMEA 2015

Screen Shot 2015-11-03 at 09.36.37

I’m looking forward to a packed set of days next week in Barcelona, where SAP TechEd EMEA 2015 is taking place. It’s packed in many ways: so much to share, so much to learn, so many people to meet and re-meet, so many kilometres to walk in the convention centre, and so much coffee.

I’m involved in a number of activities during the event. I’m co-presenting a number of hands-on sessions relating to SAP HANA Cloud Platform (HCP) and the SAP Web IDE, Fiori, and of course the fantastic UI5 toolkit. Here’s a quick summary (in my own words):

UX260 Experience SAP Fiori on SAP HANA Cloud Platform
SAP HANA Cloud Platform (HCP) is changing the Fiori landscape in so many ways, by offering features and services all the way from development, through connectivity & deployment, to exposure to end users. This session gives you hands-on experience at the places where Fiori and HCP meet.

UX261 Extend a Fiori App with SAP Web IDE based on beautiful Fiori Reference Apps
The key to the present and future success of Fiori in your organisation is the correct adoption of best practices, both from a general development perspective and also from an extension perspective (for standard SAP delivered Fiori apps). There’s a lot to get wrong, but a ton of help for you to get it right. This session shows you what and how.

UX262 Building SAPUI5 Applications using SAP Web IDE
The SAP Web IDE is the cloud-based IDE that can. From a standing start not too long ago, it’s progressed into an impressive set of features, not least those involving the templating and plugin system. This (4hr) hands-on session, which is being given twice next week, covers these subjects and more in particular the rather exciting Runtime Adaptation (RTA) features of UI5. Oh yes!

In addition to these hands-on sessions, I’m taking part in a couple of SAP TechEd Live Studio events – I’m interviewing one of my heroes on SAP Development Tools (and in particular those available on HCP), and taking part in a live panel discussion on developer engagement. Stay tuned!


openSAP Experiences

(Please see the update from later the same day as I posted this, at the bottom.)

Don’t get me wrong, the openSAP initiative is excellent, free learning materials of high quality? Yes please and thank you! This instills a passion in me (and I’m sure many others) for (a) learning more and (b) trying to attain the highest achievement. In the case of openSAP, this means trying to attain high marks in the assignments.

Unfortunately, the question and answer sections of the weekly assignments sometimes get in the way of that, in that the questions and / or answers are ambiguous. The current openSAP course “Build Your Own SAP Fiori App in the Cloud“, has great content but the questions are dubious. Here are a couple of examples, that we’re discussing on Twitter right now:

In the assignment for Week 2, there is the following question, with the 4 possible answers thus:

Within the context of SAP HANA Cloud Platform, where do applications run?
(a) In the HANA Database
(b) Inside the cockpit
(c) In an SAP HANA Cloud Platform account
(d) On the SCN community page of SAP HANA Cloud Platform

The officially correct answer has been marked as (c). But an account is not somewhere where code can be run. It’s not an execution environment. It’s an accounting, configuration, billing artifact. It’s the credentials, the units of computing allocated and allowed, it’s the sets of permissions for access to features and subscriptions and so on. It’s not an execution environment. So there’s no way that anything can run in the SAP HCP account. The nearest correct answer as far as I could see is (a). But that’s not entirely accurate. However, the ambiguity of this question and the possible answers force me to choose “the nearest that makes sense” which is (a), as (c) can certainly not be correct.

Another example is in the assignment for Week 3, where there’s the following question and 4 possible answers:

Which end-to-end application development phases are currently supported by SAP Web IDE?
(a) Prototyping, developing, testing, deploying, and extending
(b) Requirements management, prototyping, developing, testing, deploying, and extending
(c) Prototyping, developing, functionality testing, A\B testing, deploying, and extending
(d) Developing, testing, deploying, and extending 

The officially correct answer has been marked as (d).

The official download materials for this week contain, as usual, a complete transcript of all the units, the slides, and the videos. This is great in itself. Unfortunately, the official transcript records exactly what the instructor said, which is (starting at 00:02:22, bold emphasis mine):

And we do so by covering the end-to-end application development lifecycle with one tool. And when we refer to the end-to-end application lifecycle development, we start from the prototyping of the application, then the development, the testing on the different devices of course, the packaging and the deployment into different application landscape and then later on after we released the application, also the extension of the application in order to customize it and make it suitable for the different scenarios and customers.

The slide related to this section looks like this:

Screenshot 2015-04-22 at 08.35.41

See that tiny couple of words in a footnote in the bottom left? They say “*future innovation”. The instructor didn’t mention this, so if you didn’t see the slide or were watching on your smartphone (which I was) where it was too small to see, but were nevertheless intensely listening to her, and then reading the transcript to double check the facts, you would not have noticed this.

Now call me old fashioned, but if the transcript says that prototyping is supported, then I take it that prototyping is supported. But I don’t just take the transcript’s word for it … I do prototyping in the SAP Web IDE. I don’t use the Powerpoint-based kit, I build simple views in XML either by hand in the coding editor, or sometimes with the layout editor. So practically speaking, the SAP Web IDE does support prototyping, regardless of what is or is not said.

The challenge is not the course itself, the content, as I said, is great. The challenge is setting clear questions with unambiguous answers. Here are two occasions (and there have been others, on other openSAP courses in the past) where this is not the case.

I’m passionate about learning and sharing knowledge, and being the best I can be. Something like this where incorrect answers are given as the officially correct answers, does make me somewhat sad.

But one thing’s for certain: If you’re reading this and not participating in the course, head on over there right now and catch up with these great learning opportunities!

Update 21:30 on the same day:

Now this is worth shouting about. Around 3 hours after I took part in the discussions on Twitter this morning and published this post, the regular weekly “Welcome to Week N” email arrived in my inbox as usual. But what was special was this section:

Weekly Assignments: Problematic Questions in Weeks 2 and 3
Week 2: Within the context of SAP HANA Cloud Platform, where do applications run?
Week 3: Which end-to-end application development phases are currently supported by SAP Web IDE?
In both these cases, we realized that the questions were slightly misleading. You can
find more information on the discussion forums for weeks 2 and 3. To ensure fairness toall our learners, we will assign full points for these questions to all learners who took the weekly assignments. Your scores will be adjusted at the end of the course.

This is the openSAP team directly and pretty much immediately addressing our concerns and worries, within a few hours. I cannot commend the openSAP team enough for this. Not primarily for addressing the issue (issues arise in all manner of contexts, that’s normal), but for being ultra responsive and in touch with the participants of the course directly.

Other MOOCs, heck, other educational institutions in general, please take note. The openSAP team shows how it’s done.

The Maker’s Schedule, Restraint and Flow

A few years ago Paul Graham published a short essay “Maker’s Schedule, Manager’s Schedule“. It described succinctly how, and perhaps more importantly why calendar entry driven task scheduling, and in particular meetings, cause issues for makers. And I include myself and many of my colleagues within that “makers” general collective term.

Both the manager’s schedule and the maker’s schedule are important, but resonate differently and don’t mix. When making, building, creating things, solving problems, interruptions are disastrous, for all the reasons that Paul explains.

On the other side, time management, the proper organisation of tasks and working out what work to do, and how, doesn’t come for free. Managers and makers alike need skills in these areas. In order to build these skills, each one of us needs to understand that the areas actually exist, first of all. Email, phone calls, interruptions, the almost endless todo list and prioritisation issues are all things that we need to manage. And I recognise that I need to manage those things better. I use the Pomodoro Technique on occasion, but that’s just one tool. I also need to learn restraint. I need to resist the temptation to say “yes”, and to allow myself to be interrupted. If I get it right, I will find myself in flow more often. And that’s the mode that makers – developers, in our context – work.

Since that original article on the Maker’s Schedule, I’ve come across many other great articles and videos, and I wanted to share a few of them with you here, as you may find them useful too.

Remember – saying “no”, creating situations where you’re less able to be interrupted, using task and time management techniques that work for you, that let you produce more (or less, but that’s the subject for another post), is what we *should* be doing. Don’t fall into the trap of thinking that just because your project manager thinks and works in 1 hour chunks of time, you need to do as well. Of course, real life has a habit of getting in the way, but don’t let that stop us trying to be our best.

Further viewing & reading:

Scott Hanselman: It’s Not What You Read, It’s What You Ignore

Johnny Wu: Developer Productivity – The Art Of Saying “No”

Inbox Pause (great as an idea as well as this implementation)

The Pomodoro Technique

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 "")
{:cookies {"NID" {:discard false, :domain "", :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 ["" "
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 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 ""))
(: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 ""))
"{\"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 "")))
{"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.



Scratching an itch – UI5 Icon Finder

There are a huge number of icons as standard in the UI5 library, both in the SAPUI5 and OpenUI5 flavours. Here’s the Icon Explorer from the SDK.

Screenshot 2014-09-14 at 20.35.07One of the problems I have is that when I’m looking for an icon, the search term I have in my head is not necessarily going to match up with the name of the icon in the library.

For example, I might be looking for a “cog”, with the icon on the left in mind, but I’m not going to be able find it unless i use the term “action-settings”.

And in the light of the session I gave this weekend at SAP Inside Track Sheffield on “Quick & Easy Apps with UI5″, where I focused on single-file apps, albeit with full MVC, I decided to hack together a little smartphone-focused app where I could search for icons, and add my own “aliases” so that next time I searched, the search would look at my aliases too.

It’s a very simple affair, and in this first version, is designed to use the localStorage mechanism in modern browsers so that you build up your own set of aliases. Perhaps a future version might share aliases across different users, so that we can crowdsource and end up with the most useful custom search terms.

Anyway, it’s available currently at and you can grab the sources from the Github repo (remembering that the whole point of this is it’s a single-file app!).

Screenshot 2014-09-14 at 20.50.16 Screenshot 2014-09-14 at 20.48.52

Here’s a short screencast of a version of it in action:

Let me know what you think – is it useful? In any case, share & enjoy!


OpenUI5 Tutorial at OSCON 2014

This week finds me in Portland, Oregon, for O’Reilly’s Open Source Convention (OSCON), an amazing conference with a wonderfully diverse range of topics (over 20 of them). I attended OSCON as a speaker in the early 2000’s and, along with an old friend and colleague Piers Harding, talked about SAP and Open Source, and I’m very happy to be coming back to OSCON as part of an extended SAP team to talk about SAP and Open Source topics.

This year SAP is an OSCON Gold Sponsor and there are a number of sessions that are related to that. One of these was a 3.5 hour tutorial on OpenUI5

Discover OpenUI5 – The New Web UI Library from SAP

We (Andreas Kunz, Frederic Berg and me) presented this tutorial which was based on an updated version of some work we and other UI5 team members had previously prepared for SAP TechEd. It was a lot of fun, and hopefully, educational for the attendees.

Of course, being Open Source related, we’ve made the session material (slides), comprehensive exercise document, the starter project and all the solutions to the exercises available. We collaborated on a Github repo, and it’s all there:

So have at it, see how you get on, and spread the OpenUI5 love.

Share & enjoy!