December 2010 Archives

Using Sammy.js with MODx Revolution

For a recent project that we will announce and provide further blogging insights upon, we were presented with a particularly tought challenge. We had to build an ecommerce site where purchasing a product is a significant workflow for a user. This site is about purchasing custom tailored suits - it allows users to completely customise their suit; the fabric, number of buttons, type of pocket and so on. This does not lend itself to a simple checkout process, and having mind-mapped and wireframed out the process, it became apparent that the usual ecommerce 'formula' wasn't going to work.

In order to provide a quick, seamless checkout process we decided to build a completely ajax'd workflow. But one of the usual pitfalls of a javascript based workflow is that usability can suffer in places that we normally take for granted. Things like the browser back/forward buttons, bookmarking etc often get tossed to the side and users are expected to complete a workflow from start to finish without interruptions. We recognise that is not realistic, and for the best possible user experience, we weren't happy tossing aside functions for 'coolness' and speed alone.

So the research began and Sammy.js was brought to my attention. Having been introduced to, and subsequently falling in love with the connectors/processors/extJS setup that the backend of MODx Revolution ingeniously uses, I decided that this RESTful evented javascript framework could be what I was looking for.

First up, a little bit of background on sammy.js. An explanation of what Sammy.js is, by the author:

Sammy is a tiny javascript framework built on top of jQuery. It's RESTful Evented JavaScript.
... Working heavily with Sinatra, I realized that the simple route definitions and structure it provided could be a great fit with jQuery/JavaScript. Not only does it allow you to respond to specific URLs, but utilizing the URL hash (#) you can create single page applications that still respond to the back button in your browser (ala Gmail).[official website]

As it relates to the problem we were looking to solve, Sammy.js would allow us to handle all the routing of our workflow, and a user would be able to go back and forward through the workflow as they please using their browser history (e.g. #/start -> #/choose -> #/alter -> #/fitting -> #/checkout).

This demo isn't going to go into any detail on how we executed the online tailor website, that post will come later. For now, I've thrown together a 20 minute demo that demonstrates the most basic principle of how you can use Sammy.js with MODx Revolution.

What this demo does:

When the page loads, the highlighted div in the middle of this post with the ID #main-app will be injected with a link. Clicking on this link will execute a 'route' (#/start) which posts to a MODx connector that in turn returns a list of recent comments in JSON format that have been posted on this blog. Using the Sammy.Template.js plugin, each comment in the result set is formatted according to a preloaded template. Try clicking the back and forward buttons in your browser between clicking the link, and when the AJAX request has completed. This might be useful for someone who wants to have comments show on their site, but only when a user clicks 'see all comments'.

Toggle: Show Comments | Hide Comments

Load some stuff in here man!

What is so cool about that then?

Well, we now have bookmarkable links to different workflow states on this page. After clicking the link above to load blog comments, your window.location will update to http://www.butter.com.hk/blog/archives/#/start. If you reload the page with the hash inside the URL, Sammy.js will forward you to the corresponding UI state that you left the page on. When your workflow contains more than a handful of steps, this is incredibly useful. On top of that, since Sammy.js has formatted each of the comments for us, our http requests are smaller and the server has done less work.

The Code:

To get this demo up, you need to register a few javascripts in the head of your page. I've used a basic snippet to do this for each file in sequence, like so:

[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js`
]]
[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`demo-assets/sammy/blockui.js`
]]
[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`demo-assets/sammy/sammy.js`
]]
[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`demo-assets/sammy/sammy.template.js`
]]
[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`demo-assets/sammy/demo.js`
]]
[[include?
	&filename=`web_assets/snippets/loadAsset.php` 
	&path=`demo-assets/sammy/demo.css`
]]

The loadAsset.php file makes use of $modx->regClientStartUpScript($path); to throw each file into the head of the page. You could easily place these files in the head inline, if that makes sense for your site.

Sidenote - Jude is close to packaging up a more advanced version of this snippet which will compress the assets on the fly, retrieving from cache after the first load. More to come on that later.

The following four files are 'library' files. Unless you're a fan of core hacking, you won't be editing these files at all.

  • https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
  • demo-assets/sammy/blockui.js
  • demo-assets/sammy/sammy.js
  • demo-assets/sammy/sammy.template.js

The next few files are the ones to be concerned with for this demo.

Demo.js

;(function($) {

var app = $.sammy('#main', function() {
	this.debug = true;
	//open your firebug console for some debug awesomeness.
	this.element_selector = '#main-app'; 
	//which element are we rendering our 'app'?
	var baseURL = 'demo-assets/sammy/';
	var connectorURL = baseURL + 'connector.php';
	
	
	this.use(Sammy.Template);
	//we will be templating our comments using the sammy.template.js plugin, so declare usage here.
	
	var loading = '

Just a moment...

'; this.before(function(context){ $.blockUI({ message: loading }); //before any routes are executed, run some code in here if you like. How about a loading indicator? BlockUI is pretty nifty. }); this.get('#/start', function(context){ this.swap(''); //clear out the main app div. var params = { 'action': 'getcomments' ,'start': 0 ,'limit': 20 }; $.ajax({ url: connectorURL, data: params, async: false, success: function(items) { items = eval(items); //datatype: json would be tidier but this demo isn't perfect. comments = items.results; $.each(items.results, function(i, item) { //loop our result. context.render(baseURL + 'partials/comment.template', {item: item}, function(rendered){ context.$element().append(rendered); //append the comment to the main app div after it has been templated. }); }); $.unblockUI({}); //activity has finished, so let's unblock the UI. } }); }); this.get('#/', function(context) { //mirror of the function below, this shouldn't be required but for my shoddy demo it is =) var item = { url: window.location.href }; context.render(baseURL + 'partials/start.template', {item: item}, function(rendered){ context.swap(rendered); }); $.unblockUI({}); }); this.get('', function(context) { var item = { url: window.location.href }; context.render(baseURL + 'partials/start.template', {item: item}, function(rendered){ context.swap(rendered); //'swap' in the content retreived from the partial. }); $.unblockUI({}); }); }); $(function() { $.blockUI.defaults.css = {}; app.run(); //fire up the app on domReady, or any event you prefer. }); })(jQuery);

The concept of 'Routes'

As you'll see in the code above, events in the app are handled via routes. Routes directly mirror the URL hash tag, and will be executed upon a change to the window.location.hash. That will happen as soon as your user clicks a link that has a #/verb appended to it.

By declaring the following code in the this.before() function, a block of code will get executed regardless of the route. This could be useful for a number of reasons, I've used it here to display some UI feedback in the form of a loading message before any routes are executed. When routes finish executing, that loading message is then hidden to indicate that activity has finished.

this.before(function(context){		
	$.blockUI({ message: loading });
	//before any routes are executed, run some code in here if you like. How about a loading indicator? BlockUI is pretty nifty.	
});

Note that blockUI is not part of Sammy, it's a jQuery plugin that is documented here

Templating results

In the #/start route, we are sending an ajax request to a MODx connector that will serve comments in json format in the response. Each one of those will need to be formatted into HTML to make them readable on screen. Using Sammy.Template.js, we can do this with only a few lines of code. Each item within the json response will be applied into the following template file:

<%= item.name %>:
<%= item.ago %>

<%= item.body %>

Properties within each item are accessed in the following format: <%= object.fieldName %>

Get these files:

There's obviously tonnes of potential uses that you could dream up with MODx + Sammy.js - the fact that MODx Revolution has such things as connectors and processors only makes it easier.

- The Ninja

Tags: Sammy.js, MODx Revolution

Client Management – What do you do with difficult Clients?

At what point does our integrity fold over? How far does a company bend for a client in the name of a stronger portfolio? Are concessions provided to all with an unlimited supply of ‘condiments’?

These are examples of questions many web development companies, like ours, ask themselves on a daily basis. When a client asks for his website to ‘pop’ and when we don’t produce exactly what ‘pop’ means in the eyes of that ‘client’ because of that vague, poorly articulated, direction, we are coined incompetent. Or better yet, the client signs off on every design, font size, and layout provided - yet when their father–in-laws cousins boyfriend points out that they cannot read the font (because they are blind as a bat), the client changes their mind and all of a sudden need ‘a few minor changes’ (wtf do u know about minor changes?). Then comes the tipping point – 1 week before beta launch the ‘client’ feels as though the professionalism of the site has been compromised by the large font size – now we are on tilt.

Imagine – you are trying to be selective with clients. You meet them and they seem quite pleasant and reasonable - then comes the tipping point and their frustration gets poured on the messager. Their demanding and irrational behaviour comes out when they don’t know how to express their thoughts - much like a baby cries when they want something. Would we try, repeatedly, to decipher what they may want, to no avail, all on our tab? Or vice-versa – the client has been nothing but helpful and forgiving, producing what is agreed to and even creating a relationship that will last long past this particular project - would we grant concessions then?

Whether or not they are a good client, bad client, or friend is beside the point. It is a matter of principal, one that in the web-industry has been neglected for too long. Everybody knows somebody that can ‘build’ a website, you know, the friend of a friend – good, go use the ‘friend of a friend’ and see what happens. 

All too often service-based companies that pride themselves on client servicing in hopes of referral business get margins cut and integrity beaten by ‘the big guys’. Or maybe a better title is ‘the insecure guys’ who feel they need to prove their worth to the pay grade above them. Well I have a message for you, do yourself a favor and kick rocks!

Where do you draw the line? What is your company’s philosophy?

-The Suit


Code Jam: Part I - Front End Resource Editor for MODx Revolution

A couple of years ago in a previous job I had gathered a little momentum in my team for a code jam - the idea being that a few intense hours of collaboration on an otherwise ignored idea could be the springboard for a fun project. In the end it never happened, getting people together for a code jam on their own time isn't the simplest thing. As anyone in the web development industry knows, client projects always find a way to take precendence above unproven internal projects. I put the idea aside and forgot about it.

Having been inspired by Mark Zuckerburg's 'Face Mash' coding frenzy in The Social Network, this past month Jude and I started a little competition: Who can build a small scale MODx brochure site the quickest. We each picked a project and setup a time where everyone in the office knew we were 'wired in' and were not allowed to disturb us. We also picked forfeits for each of the losers. These were very small projects, they had a handful of templates and around 10 - 15 pages of content.

In the spirit of competition, I am going to rub it in Jude's face by telling everyone that I won. My time was 70 minutes, his time was 90. I will not be disclosing what his forfeit is, because it probably isn't suitable for this blog ;)

After we finished the competition, it became apparent that given that everything is in place, we can be remarkably efficient (e.g. in the context of our competition, those things were design, content, sitemap etc.)

So now we're ready to put the previously discarded code jamming concept to the test with a project that we hope will provide significant utility to anyone using MODx Revolution. We have many, many ideas bouncing around in our office, some would say too many. But given the restrictions we are placing on ourselves for this code jam, we were able to filter out a lot of those ideas and focus on one that is realistically acheivable in a day. Although we do not intend to finish the project in its' entirity in a single session, we will be tackling a request that we see a lot of in the MODx forums: A front end Resource editor for MODx Revolution.

First up, here's our rules for the code jam:

  • Each iteration of the project will be coded in a single non-work day, between 3 or 4 developers (whoeever wants to participate and work on a weekend). All phones are off, emails are unread/unanswered, and IM clients are switch off.
  • Each developer will be responsible for one part of the project. 
  • At the end of the day we will blog about our progress, and set another date for the next code jam. We will release our days work to the community on github. Depending on the state of it, we may submit it as a package.
  • Core hacking is not allowed.
  • We will start at 10AM, and finish at 7PM. Afterwards, we will gorge ourselves on food and beer as we celebrate what awesome ninja's we are.

Any breaking of the above rules will result in being Iced. Ice blocking is not allowed.

Here's our main set of features for the first release:

  • Allow editing of all core resource fields (e.g. pagetitle, longtitle).
  • Allow editing of all Template Variables.
  • Support form customisation.
  • Provide the full site tree within the editing interface.
  • Respect all access policies.
  • Reuse as much core code as possible, e.g. whatever can be sent to existing processors will be.
  • By the same logic, we will use ExtJS & MODext to render the interface.
  • Provide translation packages in English and Chinese.

End Goals:

  • As premiere partners of MODx, we intend to do our best to spread adoption of the best open source CMS in the world. We think that releasing a good front end editor for Revo would help with that.
  • To finally put the code jam concept to the test, hopefully along the way inspire others to finally start and finish the ideas that got lost along the way.
  • To familiarise ourselves with Git as we try to improve our internal workflow, and to release the code onto GitHub so that the community can continue to improve our initial offering.

If we get round to a second release, there's many features that we can add to make the front end editor a true alternative to the existing manager interface. To list a few: Preview mode (e.g. view changes on the page without saving), drag and drop of elements and files, custom tv types. We'll be taking suggestions after our first release.

Conceptual Wireframes:

(rollover for an expanded view).

Logged in as manager, code is injection via plugins and rendered on top of the page

Expanding the edit panel reveals the form fields for the current resource

Updates will be rendered live in place allowing for an on-page preview. This will be a 'poor mans' version of staging. We plan to handle this by appending output filters to any element tag that is deemed editable.

So - when is this happening? It's pencilled in for January the 8th, with christmas and new years out of the way, we'll have a clear road ahead to make this happen.

- The Ninja

Tags: MODx, MODx Revolution, CodeJam

12 Reasons Why Butter is Better


  1. Our employees were born on a computer that was designed, programmed and sold by our own hands.
  2. We had a programming competition with superman. The loser had to wear their underwear on the outside.
  3. Our design team also work as consultants. You may have heard a few of their clients: Da Vinci, Gaudi etc…
  4. We have a core belief of  “being porno.”
  5.  Side note “Knock Knock.” “Who’s there?” …….(very long pause)…. Flash.
  6.  When life gives us lemons, we create a spiritually uplifting website.
  7. When we look at code it gets smarter.
  8. We employed a ninja, and then fired him for not being awesome enough. (http://stephchev.posterous.com/i-am-a-digital-ninja-via-davideatslife-marcir)
  9. We are the life of the conferences we’ve never attended.
  10. We speak fluent code, in English.
  11. Our legend precedes us like the su precedes the do.
  12.  We won the best ever website award using a typewriter.

- The Heckler