I've been working with other VersionOne developers and managers on what will become our App Catalog
. We intend to make the application itself open source. With it, you'll be able to easily showcase the add/ons, plugins, or just plain old resources you have related to your own applications. We're all familiar with this kind of interface. You see it in your phones, and in places like Mozilla Addons
, or the Visual Studio Gallery
App Catalog Prototype done with Twitter Bootstrap
I came across Adobe Technical Evangelist Christophe Coenraets' very illustrative Sample App with Backbone.js and Twitter Bootstrap
a couple of days ago and used it as a baseline for building this early prototype of an entry detail page for our App Catalog. This shows it rendering the data for our Clarity PPM integration.
Standing up straight with Backbone
For some time now, the VersionOne team has been using Backbone.js
in new features. Maybe that is because we've found new use for our own backbones with the awesome sit/stand GeekDesks we have in the VersionOne offices?
I digress. Anyway, it's very easy to use Backbone to consume and manipulate RESTful resources by extending
and overriding one or more of its functions. In this post, we'll examine that and a few other highlights. I encourage you to see the README.md for the code on GitHub
for an in/depth, sequential explanation.
Consuming a cloud/hosted resource with Backbone
We are hosting a Node.js based RESTful app on Windows Azure to store our catalog data. Internally, the app uses the awesome Mongoose JS
library to connect to MongoDB // itself hosted within MongoLabs. To expose our data as a Backbone model, all we have to do is extend it this way:
EntryModel model extending Backbone.Model in CoffeeScript
[gist id=5300295 file=EntryModel.coffee]
Painless AJAX with Backbone.Model
Now that we have a model that is easily consumable, we can use the
function to initiate an HTTP GET on that resource. Backbone will delegate to jQuery or zepto for AJAX support, and when finished will callback the function we pass as the second argument:
Using Backbone.Model.fetch function to get HTTP resource
Within the route handler for
, we instantiate the model with an id, and then simply call
, passing it a success callback function. By the time that function gets called, the
instance has been populated with all the attributes that came back from the JSON document returned by the remote HTTP response.
[gist id=5300295 file=Router.coffee]
Handlebars template with Bootstrap goodness
Another thing we've adopted at VersionOne is the elegant, simple, and extensible Handlebars.js templating engine. As you saw above, in the callback passed to
, we instantiate an
, passing it the model instance.
You should view my in/depth explanation of the code at GitHub in the README.md
file for the repository to understand the flow of execution in detail.
Here's a snippet from a sub/view,
, with Handlebars variable/interpolation syntax,
, and some of Bootstrap's CSS classes to make a stack of navigation button tabs painless and easy:
Replacing placeholders with model properties and tabbifying links with Bootstrap classes
class='textLinks nav nav/tabs nav/stacked'
classes there are part of Bootstrap, and they enable the links to look as the screenshot above depicts.
[gist id=5300295 file=EntryDetailsInfoView.html]
Rooting our Boots with RequireJS
Here's the gist:
HTML template contains only shell structure and one single script reference
The reference to
attribute tell RequireJS to load
as the entry point for the application.
[gist id=5300295 file=index.html]
The main.coffee file configures RequireJS and asks it to load dependencies
First note that when we compile the app with coffee/script,
. What happens in this file is that we first configure RequireJS to treat a handful of libraries with some shim, to make them behave as if they natively supported the AMD pattern. This lets the rest of our script modules import them without pain. The actual function call to
passes in an array of module names, and then a callback function. We only declare variables for four of those modules, because those are the ones we need to use in the initialization of the app within the callback.
[gist id=5300295 file=main.coffee]
Read more on GitHub
I hope this was helpful to you, even in its nascent state. There's a much more detailed, step/by/step explanation of how the App Catalog code works in the README.md over on GitHub
. Please check it out and let us know what you think so far.