Google+
Now Playing Tracks

Modernizr Command Line Interface

Modernizr is an an excellent library used for client-side feature detection.

Modernizr

The full set of features detected can be obtained using its development version, however, including this entire file is not ideal in production - why make users download all the extra code for feature detection tests that will not ever be used?

Thankfully, Modernizr has a nifty download feature, which lets you fill in a form to select which tests you want, and then it generates a customised file for you to download.

How about a CLI?

Modernizr + Command Line = ?

That is great, however, what if you want to use Modernizr to generate custom files on the command line?

I came across this closed ticket raised against Modernizr, and that helped somewhat, as I found a way to generate custom files on the command line, but the command I had to issue was extremely convoluted.

Seeking an easier way, I came up with this, which was a huge improvement in usability.

Now it is even easier:

    npm install -g modernizr-cli
    modernizr custom.json

(Where custom.json should conform to this format)

Check it out: modernizr-cli on github | modernizr-cli on npm

Making Maven Grunt - Windows Edition

Recently, I needed to make a single-page web app that would be served by a Java backend. That would be as simple as copying the static files into the relevant folder, right? Well, as it turns out, not quite, as each project used a different build system.

Single-page web apps are typically built using the Grunt and Bower toolchain, which are NodeJs scripts. Java backends are typically built using either the Ant or Maven toolchains.

Pick one, or make a bridge?

So, should we replace the build tool of with the build tool of the other, or should we just make one of them talk to the other? Addy Osmani has an article, Making Maven Grunt, whichdescribes this situation quite succinctly:

"More times than not, it’s the back-end team who will define the build process and end up having to wrangle your front-end code into there."

"Whilst there are many plugin options for JavaScript processing in the Maven world, these plugins can be a real chore to create, maintain and update. In addition, they often have outdated dependencies – meaning you need to monkey-patch them to work and developers – especially those not coming from a Java background – dislike it."

Thus it appears that in order to get the best of both worlds, the best option would be to create the bridge that allows one build system to talk to the other. In this case, to make maven invoke grunt.

The options

Turns out that this is a problem that several have had, and solved, before.

If you your web app is generated by yeoman, then the yeoman-maven-plugin provides some sensible configurations that work out of the box. However, if you need something a little more flexible, the maven-antrun-plugin, or the exec-maven-plugin is your best bet.

However, I did not want to throw Ant into the mix, as I was already using two other build systems, and their syntaxes - and thus reluctant to throw a third syntax into the mix; thus exec-maven-plugin it was!

Why don’t my plugins run?

I asked a question on Stackoverflow: "Maven exec-maven-plugin and maven-resources-plugin not running, not sure why"

Excuse the newbie question on this one - this was my first time using maven after all!

When including a maven plugin, you define a list of <executions>. I thought that defining a <phase> for each <execution> was sufficient to trigger them. I learnt that it simply was not. It is necessary to define at least one <goal> for the plugin to get invoked.

Why can’t my plugin find executables?

A follow up question, also on Stackoverflow: exec-maven-plugin says cannot run specified program, even though it is on the PATH

Now this one was not a newbie question at all - it turned out to be a Windows-specific bug.

Basically, even though entering grunt on the command line worked, as it was on the path, when the maven plugin ran, it failed to find it, much to my puzzlement.

After much tinkering, and inspecting the source code of exec-maven-plugin, I found what I think is a bug in the plugin:

    CommandLine toRet;
    if ( OS.isFamilyWindows() && exec.toLowerCase( Locale.getDefault() ).endsWith( ".bat" ) )
    {
        toRet = new CommandLine( "cmd" );
        toRet.addArgument( "/c" );
        toRet.addArgument( exec );
    }
    else
    {
        toRet = new CommandLine( exec );
    }

It assumes that only commands that invoke .bat files need to be prepended with cmd /c.

I checked the npm path, where the links to all the global installed NodeJs libraries are, i.e. the ones installed using npm install -g, and found that it had, for each, a Unix shell script, with no extension, and a Windows batch script, with a .cmd extension.

Fixing the problem

Normally I would have fixed the problem by patching the bug in exec-maven-plugin. However, it was using a svn instead of git, and using xircles instead of github. I was not new to Subversion, but had not used it before in the context of a open source contributions. Prior to github the way I contributed to open source projects was:

  • svn diff > bug-that-this-patch-should-fix.diff
  • Attach bug-that-this-patch-should-fix.diff to the issue tracker, forum, or email the maintainer of the project.

I have since been spoilt by git’s cheap branching, and the ease with which pull requests can be managed in github’s interface.

I did give it a go, nonetheless, but I the web interface took more than a minute to load (kid not!), and that was all it took for me to start looking for another way to solve the problem.

A quick and easy way was to simply rename the .cmd files to .bat files, since they were batch script files anyway, and everything magically began working once more.

See my answer for a more detailed explanation.

Rant over

That has been half rant, half description of my learning experience. I must say, I wish that a rather simple task like this were a little easier.

Hopefully this helps anyone else trying to use maven with grunt, on Windows.

New & Improved: Star rating widget with SASS

I came across this interesting write up on a star rating system with SASS.

I happened to be creating something with a star rating system myself, so I decided to incorporate this. Unfortunately, I found it to be a bit clunky, requiring classes to be set in two places - once on the <ul> and once on the <li> - in the case of a half star.

While this was possible to do in an AngularJs directive or an EmberJs Component, the code for it proved to be a little unwieldy for my liking. I wanted to simply set one class, on the <ul>, and not have to do anything else.

So I came up with some improvements of my own. And in gist form.

SASS star rating widget improved


EDIT: Just noticed that my comment has been marked as spam - please fix!

my comment marked as spam - oh noes

Introducing qryq server

I have given talks on qryq a few times now, and, quite often I have been asked, about how to actually begin using qryq.

qryq is a general purpose library, and it can be used in a number of different ways. The most common, or default, use for it is to expose a single API endpoint on a server, where any number of APIs can be invoked in a query queue specified by the client. Thus I have created a template server that does just this, and have (creatively) decided to name it qryq-server.

This project is most useful as a scaffold or template, where you simply make a copy of it, and in most cases merely need to add more methods to the api object.

OSDC2013 and WDS2013 back to back

Last week, I had the opportunity to attend two conferences back to back: Open Source Developer’s Conference 2013 in Auckland, and Web Directions South 2013 in Sydney. Being in a profession where I am sitting in front of a desk all day, going on the road for a week mixed things up quite a bit. Plus, preparing to talk at one added to the stress, and to the lack of sleep.

What a great experience though, I have been put through an accelerated learning curve on a diverse range of topics. They ranged from the very technical, such as dissecting the GPU’s role in rendering CSS using layers; to the more fun, such as how to generate a choose-you-own-adventure game in pastebin; to the unexpected such as a crash course on 3D modelling using Blendr.

Open Source Developers Conference 2013

Open Source Developers Conference 2013

This was my first time in New Zealand. I had a great time exploring Waiheke island on Sunday - a couple of days before my presentation - while running through the presentation in my head. It was pretty much a picture postcard view every couple of minutes along the coastline. At some point in this rather nice walk, inspiration struck on qryq. That culminated in these code snippets, and was the basis for re-jigging about half my presentation.

Web Directions South 2013

Web Directions South 2013

It was a great experience attending what felt like the biggest tech conference in Australia. It was also great to see a few familiar faces presenting: Mark Dalgleish, Ryan Seddon, and Glen Maddern. The talks here were grouped into two streams, code and design - which made it easier to select which ones to attend.

Attending next year?

OSDC focussed a lot more on programming; and its scope was very broad, covering many different technologies, and languages. Web Directions South focussed a lot more on design; and its scope was more specific, covering only technologies in the web stack. Worth mentioning that Web Directions has a sister conference, Web Directions Code which is more focussed on programming, but still focussed on technologies on the web stack.

On attending conferences

This being the first time I have attended large tech conferences, I have learnt much not just about the subject matter of the talks given, but also much about the other aspects of them. When attending them, one wears different hats - traveller, attendee, and speaker - and here are a few things I took away about maximising the time spent at them.

As a traveller

Travelling to a conference is not a lot different to travelling for other reasons. The main thing to remember is that being on conference is like going to work, and thus not very relaxing. Pro-tip: Do not book a hectic flight schedule!

As an attendee

Attending a conference is mostly about sitting down and listening to someone speak. Making the most of this experience is a balancing act. Listen to the speaker; watch the screen projection; take notes; follow the twitter feed; reflecting about how what you have just taken in can be applied to your own work. Juggling all of that can be tricky.

I found that the easiest thing to do is to leave out the twitter feed, except for right at the beginning, and right at the end of the talk. Save reflections and developing ideas for application till after the talk, and just jot the ideas down quickly when you have them. Most importantly, take notes; and when doing so, avoid writing down anything that is on the slides, and instead what the speaker is saying, as usually you can find the slides afterwards anyway.

One thing about conferences is that they often run multiple concurrent tracks. OSDC had three, and WDS had two. While it is great that you get to pick your favourite ones to attend, sometimes there are two that you would like to attend that happen to run at the same time, and a tough choice needs to be made. What I learnt here was that it pays to do your homework - research the topic presented, and what the presenter has written about it prior.

While attending the presentations are what you will spend most of your time doing, it is important not to neglect the other parts. In between the presentations, there will be time to mingle, and that should be used well. Spend it talking to the presenters and the other attendees; usually they are looking to do the same themselves!

Oh yes. Make sure to remember to bring an extra long power cord!

As a speaker

Speaking is hard, mostly because of the need to prepare. Once at the conference, prepare to completely rework your slide deck, because new ideas will occur; as will last minute feel-the-need-for-improvement frenzies. In fact, I redid half of my presentation the day before I spoke.

On my first day in Auckland, I was a little lost walking around the city, and asked for directions from a stranger, who was happy to walk with me as he was going in the same general direction. Turned out he was a budding web developer, and I told him about OSDC - he had not heard of it - and he bought a single day ticket, and came to see my talk.

Something that I thought I did quite well (if I do not say so myself) was to use the breaks in between presentations, and other opportunities, to talk to other attendees, and mention what I was going to talk about to the other attendees and speakers. That gathered quite a bit of interest, and resulted in a full house during my talk, and even had some expressions of interest in using and porting qryq.

Another thing, which I have learnt from one of the other speakers was to bring marketing materials. He handed out one page print-outs of the software he was speaking about. I thought that that was a brilliant idea - so much better than just a name card - keep that in mind for the next time.

Watch this space

More to come on OSDC2013 and WDS2013 soon.

BackboneJs Grouped Collection Techniques - Four Approaches

We start off with a standard Backbone model. Owing to my creative streak, I have decided to give it the exciting name of Foo.

var Foo = Backbone.Model.extend({
    /* some code here */
});

The next thing that we do is to define a collection of Foo models.

Foo.Collection =  Backbone.Collection.extend({
    model: Foo,
    /* some code here */
});

This is important to do because we will be:

  • fetching multiple Foos in a single HTTP request
  • displaying mutliple Foos in a single Backbone view

Spanner in the works

Next we add an additional requirement to the above. We are no longer satisified with displaying Foos in a flat list in the views. We want them to be grouped according to a particular attribute, bar that every Foo has.

There are several ways to do this:

//alternative #1
Foo.Collection =  Backbone.Collection.extend({
    model: Foo,
    initialize: function(initialModels, options) {
        this.listenTo(this, 'add remove sync', this._regroup);
        this._groupedData = [];
    },
    _regroup: function() {
        //TODO parse collection and group by bar
    },
    getGroupedModels: function() {
        return this._groupedData;
    }
});

In alternative #1, the collection listens to any changes on itself. As soon as one occurs, the regroup function is run. The view that wishes to display the grouped collection of Foos calls getGroupedModels, and the grouping is always up to date.

//alternative #2
Foo.Collection =  Backbone.Collection.extend({
    model: Foo,
    initialize: function(initialModels, options) {
        this._groupedData = [];
    },
    _regroup: function() {
        //TODO parse collection and group by bar
    },
    getGroupedModels: function() {
        this._regroup();
        return this._groupedData;
    }
});

In alternative #2, the collection does not listen to changes on itself. Instead, only when the view calls getGroupedModels, does it run the regroup function. Thus the grouping is not always up to date, and is recomputed just in time for when it is needed.

//alternative #3
Foo.Collection =  Backbone.Collection.extend({
    model: Foo,
    initialize: function(initialModels, options) {
        this.listenTo(this, 'add remove sync', this._flagForRegroup);
        this._groupedData = [];
        this._needsRegroup = true;
    },
    _flagForRegroup: function() {
        this._needsRegroup = true;
    },
    _regroup: function() {
        this._needsRegroup = false;
        //TODO parse collection and group by bar
    },
    getGroupedModels: function() {
        if (this._needsRegroup) {
            this._regroup();
        }
        return this._groupedData();
    }
});

In alternative #3, the collection listens to changes on itself once more, same as in alternative #1. This time, however, the response to the change event is different: Instead of running the regroup function, as we did in alternative #1, we simply toggle a flag that indicates that a regroup needs to be done. When the view calls getGroupedModels, the regroup function is run only if the flag has been set, and of course, the flag is reset. Thus regroup is not run every time the collection is updated, and instead only when the collection is accessed, and is known to be out of date. This is done to ensure maximum laziness in computing the regroup.

//alternative #4
Foo.GroupedCollection = Backbone.Collection.extend({
    initialize(models, options) {
        this._origCollection = options.origCollection;
        this.listenTo(this._origCollection, 'add remove sync', this._regroup);
    },
    _regroup: function() {
        //parse this._origCollection and group by bar
    }
});

In alternative #4, the view requires a Backbone collection - a simple Javascript array will not suffice. So we leave Foo.Collection alone, and define another collection alongside it. We’ll call this one Foo.GroupedCollection. (My creativity strikes once again!) Foo.GroupedCollection expects to be passed a Foo.Collection in its options when initialized. The grouped collection listens for changes on the regular collection; whenever the regular collection changes, it runs the regroup function, keeping itself up to date.

Source

Github Gist with all the above code

Conclusion

Alternative #4 is the only option when the view displaying the grouped collection is expecting a Backbone collection. Otherwise, any of alternatives #1 through #3 will do the job:

  • Alternative #3 is the most efficient, but the code is slightly more complex.
  • Alternative #1 and #2 are equivalent, with #1 optimal when the collection gets modified rarely, or it gets read frequently; because it is updated upon each modification.
  • Alternative #2 is optimal when the collection gets modified frequently, or it gets read rarely; because it is updated upon each read.

A sneak peek from my talk about qryq at OSDC 2013

A comparison of async to qryq when specifying a compound query that is diamond-shaped.

Why diamond shaped? The diamond dependency problem is a not-so-simple problem to solve, and so I have chosen this as a litmus test for testing and demonstrating compound queries. Call it a SSCCE.

In the code snippet that I have linked above, the compound query where each of the queries is dependent upon the others in the shape of a diamond is used to as a point of comparison using a known-to-be-tricky problem.

An update on qryq

Some important changes to qryq since its first announcement:

  • Picked GPL v3 as the licence
  • Fully extracted as its own project
  • Inline referencing + property drilldown of the results of other qrys
  • Specifying depends for each qry is now optional, and will be inferred when not present
  • Unit tested using nodeunit

Qryq has also just been published as a node module. You can now get it using:

npm install qryq

Pull requests and suggestions are most welcome.

Happy coding!

To Tumblr, Love Pixel Union