Let's Make a Framework: Plugins Part 3
Welcome to part 52 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.
If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.
The init Method
In part 1 of the plugins section of this tutorial, I mentioned the concept of middleware. Middleware in libraries like Express is used to bridge client code with library code, and control flow (there’s usually a next() method passed in which you can call to propagate a value or continue execution).
In an Express app, it’s possible to provide a function to a route which will determine if the route is accessible. This is commonly used to load users from the session or forward them to a sign in page.
I’ve deliberately looked for a case in Turing that would benefit from a simplified middleware-inspired approach, and I decided to take a look at turing.init.
Less DOM Reliance
Right now, we can chain DOM-related code:
turing('.selector').click(function() { alert('clicked!'); });
And enumerable methods:
turing([1, 2, 3]).map(function(n) { return n * 10; });
But this is possible thanks to a slightly ugly hack residing in the DOM module:
// Chained calls
turing.init = function(arg) {
if (typeof arg === 'string' || typeof arg === 'undefined') {
// CSS selector
return new turing.domChain.init(arg);
} else if (arg && arg.length && turing.enumerable) {
// A list of some kind
return turing.enumerable.chain(arg);
}
};
I’ve never liked the way it checks if turing.enumerable is available, and how everything centres around the DOM module.
Function Registration
Instead, we can do this in turing.core.js:
var middleware = [];
function turing() {
if (arguments.length > 0) {
var result;
for (var i = 0; i < middleware.length; i++) {
result = middleware[i].apply(turing, arguments);
// If a value is returned, stop and return it, else keep looping
if (result) return result;
}
}
}
// This can be overriden by libraries that extend turing(...)
turing.init = function(fn) {
middleware.unshift(fn);
};
If a “middleware” function returns something, then execution will stop and this value will be returned from turing().
Because I’m using unshift to add the registered functions in reverse order, your own application code could extend turing() in some amusing ways:
turing.init(function(a) { if (a === 'hello') return 'world'; });
turing('hello');
// => "world"
The usefulness of this is highly debatable, however.
Built-in Module Extensions
Now each module can do this:
// DOM, which provides turing('.selector')
turing.init(function(arg) {
if (typeof arg === 'string' || typeof arg === 'undefined') {
// CSS selector
return turing.domChain.init(arg);
}
});
// DOM ready in the events module, which provides turing(function() {} );
turing.init(function(arg) {
if (arguments.length === 1
&& typeof arguments[0] === 'function') {
turing.events.ready(arguments[0]);
}
});
// Enumerable module, which provides turing([1, 2, 3]).map(function() {});
turing.init(function(arg) {
if (arg.hasOwnProperty.length && typeof arg !== 'string') {
return turing.enumerable.chain(arg);
}
});
Granted, this isn’t as sophisticated as the middleware provided by Connect and Express, but it does give us a neater way of extending turing() dynamically, and plugins or other code could also extend it.
Conclusion
Each module is now responsible for how it extends turing() by allowing it to look at the arguments. This has allowed me to tidy up Turing’s internal code, but I’m not convinced it’s useful outside of this. It did allow me to make an amusing Hello, World example, though.
References
Node Roundup: How To Module, Node Event Loops, The Node Ahead, Connect 1.0
Prepare your favourite Instapaper/Read It Later client for a whole bunch of Node articles!
How To Module
How To Module by Isaac Z. Schlueter (the npm guy!) is a detailed article about writing a Node module. It includes advice on npm, README, version control, testing, bindings, libraries, and a lot more. It covers the entire project lifecycle, so if you’re itching to release something but are fairly new to Node I recommending reading it.
Understanding the Node.js Event Loop
Understanding the node.js event loop by Mixu is an introduction to Node’s event loop. It’s the kind of thing that I like to bookmark the next time a potential client or boss asks, “why Node?”
Having asynchronous I/O is good, because I/O is more expensive than most code and we should be doing something better than just waiting for I/O.
The Node Ahead
In The Node Ahead: JavaScript leaps from browser into future, The Register author Cade Metz discusses the history of Node, from its inception to subsequent success.
The overarching point, however, is that Node is optimal for the new breed of real-time web apps. Yes, there are other means of building real-time tools, but Node lets you build real-time tools on the same platform that runs the rest of your site.
The article cites open source favourites LearnBoost, and Joyent’s upcoming cloud services.
Connect 1.0
Meanwhile in the last week, TJ Holowaychuk released Connect 1.0 which works with Node 0.4.×.
jQuery Roundup: jQuery 1.5.1, jQuery Conference, Screencasts
jQuery 1.5.1 Released
jQuery 1.5.1 has been released. This version supports IE9 as a “top level” browser, fixes a lot of bugs, and adds new options to jQuery.ajax() (isLocal, mimeType, and xhrFields).
There will be a meeting about 1.6 on noon EST, March 7th in #jquery-meeting on irc.freenode.net.
jQuery Conference 2011

jQuery Conference 2011 will be held at the Microsoft Silicon Valley Research Center in Mountain View, California on April 16th and 17th, 2011.
The jQuery blog has more details: San Francisco Bay Area Conference Announced.
jQuery Screencasts

Josh Timonen sent me these very professional jQuery screencasts: Introduction to jQuery and Using AJAX with jQuery.
The Introduction to jQuery video starts from the basics, even explaining the reasoning behind unobtrusive JavaScript.
Node Tutorial Part 15: Node Versions, npm Publishing
Welcome to part 15 of Let’s Make a Web App, a tutorial series about building a web app with Node. This series will walk you through the major areas you’ll need to face when building your own applications. These tutorials are tagged with lmawa.
Previous tutorials:
- Part 1: Introduction
- Part 2: Installation and Skeleton App, source code commit: 4ea936b
- Part 3: RESTful Methods and Testing, source code commit: 39e66cb
- Part 4: Templates, Partials, Creating and Editing Documents, source code commit: f66fdb
- Part 5: Authentication, Sessions, Access Control Middleware, source code commit: 03fe9b
- Part 6: Interface Basics, source code commit: f2261c
- Part 7: Node Library Versions, Jade Tricks, Error Pages, source code commit: 929f5
- Part 8: Flash Messages and Helpers, source code commit: 841a49
- Part 9: Remember Me, source code commit: 1904c
- Part 10: Markdown, source code commit: 11d33
- Part 11: Better Testing, source code commit: 6a269ce
- Part 12: Updating Mongoose, source code commit: 2a8725
- Part 13: Stylus, source code commit: 0a70e40
- Part 14: Email, source code commit: 2e81a7b
Switching Node Versions
People are starting to send in error reports when they try to run Nodepad with Node 0.4.×. I’ll migrate it to support that version soon, but before that we have a few loose ends to tie up. However, I realise that waiting a few weeks for me to catch up is annoying, so in the meantime I’ll demonstrate how to easily switch between versions of Node.
I’m going to use n to do this. It can be installed with:
npm install n
I still have Node 0.2.4 on my desktop where I write DailyJS articles. That version is pretty old now. Let’s switch to 0.2.6 using n:
n 0.2.6
It might take a while to build Node on your system, just about long enough to make a coffee.
Now node -v should show v0.2.6.
Publishing Packages with npm
jamesm-sitegen asked us if we could publish Nodepad to npm. It’s actually very easy to do this, so easy it isn’t even worth a full tutorial.
The key thing to know is npm comes with lots of man pages. If you’d like to work with npm and publish packages, npm-developers is like a getting started guide. Type:
man npm-developers
to read it. Another useful man page is npm-adduser which tells you how to register yourself with npm. The npm adduser command can be used to create a new account to publish packages, or to simply use existing credentials to add another computer. Just type:
npm adduser
and follow the prompts. The email address and other details will be stored in ~/.npmrc.
Next you need to write a package.json which fortunately isn’t too hard. You could copy an existing one from another project like Nodepad, but make sure you type man npm-json and learn the basics for yourself first.
Once you’ve got a file you’re happy with you can do a local dry-run before publishing the package:
npm install .
Publishing for real is easy. Run this from your project:
npm publish
To confirm it was published, I typed this:
npm ls nodepad
And I saw the following (notice the remote flag):
nodepad@0.0.1 A notepad written with Node =alexyoung installed latest remote
Making Binaries
Even better, we can make a little wrapper to allow people to launch Nodepad. I’ve added this to bin/nodepad.js:
#!/usr/bin/env node
var app = require('../app.js');
app.listen(3000);
And then in package.json I’ve got this:
"bin": {
"nodepad": "bin/nodepad.js"
}
The launcher script just requires our Express app — npm will wrap everything so the paths make sense. When writing binaries, use paths relative to bin/.
Conclusion
When following random tutorials written by gnarly old programmers on the Internet, it’s a good idea to pay attention to the version of everything in your environment. If your scripting language isn’t the same version, the tutorial probably won’t make sense. Tools like n make it easy for us Node programmers to switch between versions of Node without any fuss.
And publishing with npm is easy, you don’t even need to leave your shell.
The latest commit is 89abea1
TeleHash, Spark, brequire
TeleHash

TeleHash is a new wire protocol for real time, distributed communication with JSON and UDP. Running this from a shell prompt:
echo '{"+end":"3b6a6..."}' | nc -u telehash.org 42424
will return a response using TeleHash. There’s a TeleHash specification, and possibly more interesting to our readers is the TeleHash Node example.
The combination of JSON and UDP is very interesting and should enable JavaScript developers to make amazingly efficient low-level network applications.
Spark
Spark (GitHub: Wolfy87 / Spark, MIT License) by Oliver Caldwell is a client-side framework that provides DOM querying, HTML/CSS manipulation methods, Ajax, JSON encoding/decoding, animations, and possibly almost everything else jQuery does. The syntax will be familiar to jQuery users:
Spark('p').css({ color: '#ff0000'})
.animate({ opacity: 0.5 }, 2000);
Some of the internals remind me of jQuery a little bit, but it’s much simpler. If you’ve been following our framework series and find this type of project interesting, you’ll probably enjoying looking through the source.
Client/Server Code Sharing with brequire
Sharing JavaScript between client and server by Jonah Fox is a tutorial about his brequire library. It shows how code can be shared between Node and browsers.
The tutorial demonstrates what happens to your code after it’s run through the brequire command-line tool. This includes an example of making Node automatically filter files through brequire’s API.
Let's Make a Framework: Plugins Part 2
Welcome to part 51 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.
If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.
Implementing Plugins
For the basic jQuery-style plugin support we need to be able to insert a function so it can access Turing’s chained API. Remember that this is all DOM-oriented, so we can use domChain. Here’s a quick example:
turing.domChain.turnRed = function() {
this[0].style.backgroundColor = '#ff0000';
};
turing('#element').turnRed();
This would actually work given the correct markup. The turnRed method should work anywhere in a chain off turing(), just like jQuery!
A Public API
I don’t believe relying on domChain is a good idea — for a start it’s only named that way to make it clear for the tutorial series. It may change in the future. I’d prefer a plugin API that supports some metadata, like we looked at last week. This would enable us to do things like reflect on plugins, perhaps facilitating a lazy-loading dependency system.
So how about something like this?
turing.plugins.register('turnRed', {
name: 'Turn Things Red',
version: '1.0.0',
description: 'Turns the background red',
author: 'Alex Young <alex@example.com>',
licenses: [ { type: 'MIT' } ],
turnRed: function() {
this[0].style.backgroundColor = '#ff0000';
return this;
}
});
Returning this will allow subsequent chained calls, but this might not always be desired so it isn’t enforced.
Testing the Plugin API
Before getting into a mess with code, let’s write some plugin API tests. We know we need a register function, so given a function called registerExamplePlugin that creates a simple test plugin, this should pass:
exports.testPlugins = {
'test plugin registration and removal': function() {
registerExamplePlugin();
assert.ok(turing('#example').turnRed());
}
};
In this example, assert.ok should pass because I intend to return this from the example plugin.
What about removing plugins? Let’s test for that too:
exports.testPlugins = {
'test plugin registration and removal': function() {
registerExamplePlugin();
assert.ok(turing('#example').turnRed());
turing.plugins.remove('turnRed');
assert.ok(!turing.plugins.hasOwnProperty('turnRed'));
}
};
How about namespace collisions and removal of non-existent plugins? It would be nice if there were some exceptions for these, plugins.AlreadyRegistered and plugins.NotFound would make sense:
exports.testPlugins = {
'test plugin registration and removal': function() {
registerExamplePlugin();
assert.ok(turing('#example').turnRed());
turing.plugins.remove('turnRed');
assert.ok(!turing.plugins.hasOwnProperty('turnRed'));
},
'test AlreadyRegistered': function() {
registerExamplePlugin();
assert.throws(function() {
registerExamplePlugin();
}, turing.plugins.AlreadyRegistered);
},
'test removing a non-existent plugin': function() {
assert.throws(function() {
turing.plugins.remove('turnBlue');
}, turing.plugins.NotFound);
}
};
The Implementation
With full comments, this is what I came up with to make the tests pass:
/*!
* Turing Plugins
* Copyright (C) 2011 Alex R. Young
* MIT Licensed
*/
/**
* The Turing plugin module.
*/
(function() {
var plugins = {};
plugins.registered = {};
plugins.AlreadyRegistered = Error;
plugins.NotFound = Error;
/**
* Registers a plugin, making it available for
* chained DOM calls.
*
* Throws turing.plugins.AlreadyRegistered if a
* plugin with the same name has been registered.
*
* @param {String} The name of your plugin method
* @param {Object} Your plugin
*/
plugins.register = function(methodName, metadata) {
if (plugins.registered[methodName]) {
throw new plugins.AlreadyRegistered('Already registered a plugin called: ' + methodName);
}
plugins.registered[methodName] = metadata;
turing.domChain[methodName] = metadata[methodName];
};
/**
* Removes a plugin. Throws turing.plugins.NotFound if
* the plugin could not be found.
*
* @param {String} The name of the plugin
*/
plugins.remove = function(methodName) {
if (!plugins.registered.hasOwnProperty(methodName)) {
throw new plugins.NotFound('Plugin not found: ' + methodName);
} else {
delete plugins.registered[methodName]
delete turing.domChain[methodName];
}
};
turing.plugins = plugins;
})();
This implementation doesn’t force too much structure on people — you can build plugins with whatever tools you want, as long as a single function can invoke it. This was inspired by jQuery. What’s slightly different to jQuery is you’re forced to include some machine-readable metadata. I might even force inclusion of properties like licenses and author because it drives me nuts when people email me jQuery plugins to review on DailyJS with little more than a crappy bit of code hanging off jQuery.fn.
Conclusion
The metadata I mocked up last week included properties like engines (for determining if a plugin can be run in a browser or server-side interpreter), and cdn. I’m hinting at a dependency loading system here, which I’d like to go over in a future tutorial.
The commit for this week was d5de1c0.
Node Roundup: Node 0.4.1, Weld, Cluster
Node 0.4.1
Node 0.4.1 has been released. This version updates V8 to 3.1.5, and includes fixes for HTTPS, Cygwin, and more.
Download Node 0.4.1 here, or read the documentation.
If you ever want to view older API documentation and can’t find it locally, you can view a list at nodejs.org/docs.
Weld
Weld by Elijah Insua and hij1nx is a library for turning data into markup. It works with both Node and browsers.
To get your head around how it works, consider this HTML:
<ul class="contacts">
<li class="contact">
<span class="name">Hello my name is <span class="firstAndLast">My Name</span></span>
<p class="title">Leet Developer</p>
</li>
</ul>
We want to add values to the elements represented by the .name and .firstAndLast selectors. The data we have looks like this:
var data = [{ name: 'hij1nx', title: 'code exploder' },
{ name: 'tmpvar', title: 'code pimp' }];
Weld can map this data to the HTML like this:
weld('.contact', data, { bind: { 'name': '.firstAndLast', 'title': '.title' } });
The first parameter is the container selector, and the third parameter helps Weld map the data to the HTML.
Cluster
In the comments for Node Tutorial 13, Johan Steenkamp had loads of tips for deploying Node apps to Amazon EC2. I’ve also been playing with this lately, and I thought I’d try Cluster (MIT License) by TJ Holowaychuk. Cluster is a multi-core server manager. It’ll work with Node 0.2.x, but it’s a bit more convenient to use it with 0.4.×.
If you’ve used Spark before, then you should be fairly comfortable with Cluster. If not, Cluster is a tool for managing Node servers and utilizing multi-core systems. It provides features that make managing your servers more seamless — reload workers when files change, zero-downtime reload, and even a repl for real-time administration.
All you need to do is call Cluster where you’d usually set up a server to listen on a port.
This is an Express app set up to use Cluster:
var app = require('express').createServer(),
cluster = require('cluster');
app.get('/', function(req, res){
res.send('hello world');
});
cluster(app)
.use(cluster.repl(8888))
.listen(3000);
More examples can be found in the Cluster documentation.
jQuery Roundup: jQuery 1.5.1 RC 1, betterflow.js, domsearch.js
jQuery 1.5.1 RC 1 Released
jQuery 1.5.1 RC 1 is out, with over 30 bug fixes and improvements.
One fix that caught my eye was #8245: Ajax now ensures header names are capitalized so that non-compliant xhr implementations don’t override them — when writing the DailyJS framework tutorials I noticed that jQuery had these headers in lowercase, but other implementations capitalised them.
betterflow.js

betterflow.js (MIT License) by Rui Lopes is a coverflow-inspired plugin. The betterflow.js demo works pretty well with the mouse and keyboard shortcuts. It even works with horizontal mousewheel movements, which surprised me because this is what I instinctively tried to do when I loaded the page.
It expects some simple markup (Rui’s example uses an unordered list with divs and images), and then just a call to $("#example").betterflow();.
domsearch.js

domsearch.js (GitHub: juliocesar / jquery-domsearch, MIT License) by Julio Cesar Ody makes searching elements like tables very simple.
I’ve written things like this before, but with pretty basic search/sort algorithms. This plugin uses LiquidMetal:
Applications like Quicksilver, LaunchBar, and Launchy have made this method of keyboard entry a popular one. It’s time to bring this same functionality to web controls. LiquidMetal makes scoring long strings against abbreviations easy.
Given a set of elements, domsearch can be invoked like this:
$('#search').domsearch('table#fruits', {criteria: ['td.price', 'td.weight']});
This searches on two columns in the table.
There’s a lot of places where I could use this plugin, and it looks like the LiquidMetal author (Ryan McGeary) put some effort into performance.
Node Tutorial Part 14: Email
Welcome to part 14 of Let’s Make a Web App, a tutorial series about building a web app with Node. This series will walk you through the major areas you’ll need to face when building your own applications. These tutorials are tagged with lmawa.
Previous tutorials:
- Part 1: Introduction
- Part 2: Installation and Skeleton App, source code commit: 4ea936b
- Part 3: RESTful Methods and Testing, source code commit: 39e66cb
- Part 4: Templates, Partials, Creating and Editing Documents, source code commit: f66fdb
- Part 5: Authentication, Sessions, Access Control Middleware, source code commit: 03fe9b
- Part 6: Interface Basics, source code commit: f2261c
- Part 7: Node Library Versions, Jade Tricks, Error Pages, source code commit: 929f5
- Part 8: Flash Messages and Helpers, source code commit: 841a49
- Part 9: Remember Me, source code commit: 1904c
- Part 10: Markdown, source code commit: 11d33
- Part 11: Better Testing, source code commit: 6a269ce
- Part 12: Updating Mongoose, source code commit: 2a8725
- Part 13: Stylus, source code commit: 0a70e40
Nodepad should send customer support emails — sign up notifications, password resets — that kind of thing. So far I haven’t touched on email in this tutorial series, but it’s required by most web applications.
Node already has a few SMTP libraries and the two most active ones have very similar APIs and names. I have no particular preference because I haven’t done anything complicated with them. If you have in-depth experience with SMTP and Node, readers may enjoy to hear from you in the comments.
I’ve decided to use node_mailer by Marak Squires. It can be installed with npm:
npm install mailer@0.4.52
As of today, mailer is at version 0.4.52. I’ve updated Nodepad’s package.json and the app.js require to reflect this.
SMTP API
Sending an email looks like this:
var mailer = require('mailer');
mailer.send({
// node_mailer supports authentication,
// docs at: https://github.com/marak/node_mailer
host: 'localhost',
port: '25',
to: 'alex@example.com',
from: 'nodepad@example.com',
subject: 'Welcome to Nodepad',
body: 'All work and no play makes DailyJS pretty dull'
},
// Your response callback
function(err, result) {
if (err) {
console.log(err);
}
}
);
If you’ve got a local SMTP daemon running, this code should work. Of course, you’ll need to change the to parameter to actually receive an email.
Development Mode
I thought it would be wise to only send mails when running in production mode, and I wanted to render mails using Jade. My example will be a plain text email for now, but using Jade should simplify HTML emails later.
The mail settings can be put in the app.configure function:
app.configure(function() {
app.set('mailOptions', {
host: 'localhost',
port: '25',
from: 'nodepad@example.com',
});
// ... snip ...
You could override this with development and production email server settings.
Simulating SMTP Locally
By the way, node_mailer comes bundled with stubSMTP. This script will allow you to receive mails and view them. The results look like this:
---------- MESSAGE FOLLOWS ----------
From: nodepad@example.com
To: alex@example.com
Subject: Welcome to Nodepad
Content-Type: text/plain
X-Peer: 127.0.0.1
Dear alex@example.com,
Welcome to Nodepad!
Regards,
The Nodepad Mail Robot
------------ END MESSAGE ------------
It would be nice if node_mailer included this as a binary in its package.json, then we could easily fire it up for local testing.
Email Object
I made an emails object to manage sending mail:
emails = {
send: function(template, mailOptions, templateOptions) {
mailOptions.to = mailOptions.to;
jade.renderFile(path.join(__dirname, 'views', 'mailer', template), templateOptions, function(err, text) {
// Add the rendered Jade template to the mailOptions
mailOptions.body = text;
// Merge the app's mail options
var keys = Object.keys(app.set('mailOptions')),
k;
for (var i = 0, len = keys.length; i < len; i++) {
k = keys[i];
if (!mailOptions.hasOwnProperty(k))
mailOptions[k] = app.set('mailOptions')[k]
}
console.log('[SENDING MAIL]', sys.inspect(mailOptions));
// Only send mails in production
if (app.settings.env == 'production') {
mailer.send(mailOptions,
function(err, result) {
if (err) {
console.log(err);
}
}
);
}
});
},
sendWelcome: function(user) {
this.send('welcome.jade', { to: user.email, subject: 'Welcome to Nodepad' }, { locals: { user: user } });
}
};
Just in case you’ve forgotten, app.set(name) returns a configuration value. A second option would set it. I’ve put that option merging loop in there to make it easy to support more options in the future; it probably doesn’t really need it.
Additional emails could be created by adding a template to views/mailer/ and adding a method that uses emails.send. The sendWelcome method is very simple, most emails will probably look a bit like this. The two sets of options send accepts are for the node_mailer send method and Jade’s renderFile.
Here we’ve actually created a little email management class simply by relying on everything Express, Jade, and node_mailer gives us. The emails object is just a simple way to wrap up our email management requirements.
The Jade template looks like this:
| Dear #{user.email},
|
| Welcome to Nodepad!
|
| Regards,
|
| The Nodepad Mail Robot
The Jade template isn’t actually very nice, I had to escape each line because we’re generating plain text rather than HTML. A “real” email management object, something more generic, might detect if a template is plain text (perhaps based on file name), and then render it appropriately. In this case, ejs might be better for plain text emails.
Sending Emails
Now the user creation action, app.post('/users.:format?', ... just does this when a user is saved:
emails.sendWelcome(user);
Conclusion
Sending emails is fairly easy, but dealing with templates and appropriate behaviour based on environment (development, testing, production) takes a bit of thought.
The current commit of Nodepad is 2e81a7b
References
Minimal.js, Treesaver, Respond
minimal.js
minimal.js by Rui Lopes is a HTML/JSON template engine, for use with client-side JavaScript or Node. In minimal.js there’s no new template language to learn — the templates are HTML and the data is JSON. It doesn’t depend on frameworks like jQuery, but can work alongside them.
<h1></h1>
<p></p>
<p id="footer"></p>
Which gets populated by using minimal.js like this:
$m({
h1: "this is a title",
p: "this is a paragraph",
footer: "this is a footer"
});
Iteration can be used, there’s a good example of this using unordered lists:
<ul>
<li></li>
</ul>
And:
$m({
ul: ["foo", "bar", "baz"]
});
Results in:
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
This library has a lot more features, but the simple idea of cleanly separating templates from data got me wondering about combining it with Backbone.js.
Treesaver

Treesaver (GitHub: Treesaver / treesaver, MIT and GPLv2) by Filipe Fortes and Bram Stein is a framework for creating magazine-style layouts. There’s a Treesaver tutorial which demonstrates creating the above example.
Respond
Respond (MIT or GPL Version 2) by Scott Jehl helps with creating responsive web designs — essentially CSS3 media query support for Internet Explorer 8 and under. Scott has worked at making the script fast and lightweight.
JavaScript is typically my ultimate solution for fixing IE6+ behaviour, so I don’t have a problem with Respond sitting in my toolkit next to Modernizr.
Let's Make a Framework: Plugins
Welcome to part 50 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.
If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing.
Plugins
Why directly support plugins? Why not just distribute libraries that are compatible with particular frameworks?
It turns out it can be incredibly useful to directly extend frameworks to provide new features that work with their familiar APIs. I think the best example of this is jQuery, but other frameworks also have some form of plugin support. It actually varies — some have particular components designed with plugin APIs, and others just have community supported plugin repositories.
I started thinking about this back when we were adding the DOM selector engine. There’s special handling for the DOM module to allow other parts of the framework to work with chained calls off selector results. So for example, the following is possible:
turing('p')
.fadeIn(2000)
.animate(1000, { color: '#ff0000' })
.click(function() { alert('clicked'); });
The first method returns an object that has aliases to the animation and events modules. These modules are mostly self-contained, and their methods accept an element as the first parameter. The chaining is facilitated simply by wrapping the original calls. This is a little bit like jQuery.
jQuery Plugins
A jQuery plugin is just a function:
jQuery.fn.myPlugin = function(options) {
var settings = {
defaultValue: true
};
if (options) {
jQuery.extend(settings, options);
}
};
Inside the myPlugin function, this refers to the jQuery object the function was called from. And depending on the type of plugin, jQuery objects can be returned so the results can be chained. Settings can be handled with jQuery.extend.
The jQuery Plugin Authoring documentation has examples of namespacing events, data, and some best practice guidelines.
The important question, however, is what is jQuery.fn? Take a look at this code from core.js:
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
// ... Snip ...
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// etc.
It’s jQuery’s prototype object — the code that gets instantiated with your selector and the results of a query. That’s how plugins can appear potentially anywhere in the chain: $('selector').myPlugin.
Middleware
The idea of middleware seems to be catching on in the Node community. We’ve seen this on DailyJS in Express’ Connect middleware. Some of the library’s functions accept a parameter that is a user-supplied function. This function has two or three parameters — the last one is a method (next()) that can be called to pass execution on to the next piece of middleware.
This approach means user-supplied functions can be injected into key areas of the library. It also works well with asynchronous code.
Dependencies and Namespacing
jQuery doesn’t specifically prevent plugins from overriding each other. I’ve tried to keep Turing’s modules self-contained, so it might be useful to be able to express and manage dependencies. A simple format like NPM’s package.json could be used to express a plugin’s requirements:
{
"name": "My Plugin",
"version": "1.0.0",
"description": "A useful plugin",
"author": "Name <email>",
"cdn": [
"https://ajax.googleapis.com/ajax/libs/..."
],
"repository": {
"type": "git",
"url": "http://..."
},
"engines": {
"node": ">= 0.2.4",
"browsers": [
// Does this make sense?
]
},
"bugs": {
"url": "http://..."
},
"licenses": [
{
"type": "MIT",
"url": "http://..."
}
]
}
As you might have seen on DailyJS, I often get annoyed at the amount of jQuery plugins that come without licensing information, tests, and documentation. Encouraging plugin authors to include this kind of metadata from the start is a good idea.
Turing’s Implementation
jQuery’s simple plugin approach will play nicely with the chaining API that we’ve been building for Turing. The idea of middleware interests me as well — it might be useful in areas where the framework needs to be extended internally. As a bonus, I think we’ll be able to use the plugin system to fix some of the chaining code I’ve written internally in Turing.
Node Roundup: bigint, mingy, kyoto-client, Blagovest's NPM Search
bigint
bigint by James Halliday is an arbitrary precision arithmetic library for Node. Large integers can be defined with strings, then manipulated with the library’s methods:
var bigint = require('bigint');
var b = bigint('782910138827292261791972728324982')
.sub('182373273283402171237474774728373')
.div(8);
Note that there’s also a destroy method:
Destroy a bigint. This module is using node-ffi so I can’t hook onto the GC easily. You only need to call this if you’re creating bigints in a loop.
Other methods include rand, pow, and more. This library can be installed with npm install bigint.
I actually have some experience in working with arbitrary precision arithmetic from back in my university days — I wrote a distributed fractal generator with various numerical libraries. In Ada… This sounds like a lot more fun!
Mingy
I like writing CLI stuff, so I thought Mingy by Mike Cantelon sounded pretty cool. He describes it as a “cheap and cheerful command parser/server for node.js”, perfect for creating command-line tools, text adventure games, and even MUDs.
It can run as a server (hence the MUD reference), copes with multiple users, includes validation support, and even has Expresso tests.
kyoto-client
kyoto-client (GitHub: wezm / kyoto-client, BSD License) by Wesley Moore is a Kyoto Tycoon client library. Kyoto Tycoon is a lightweight database server, from FAL Labs, who also created the older Tokyo Cabinet key value database.
The kyoto-client module has some good documentation on the site and seems straightforward to use. It can be installed with npm install kyoto-client.
Blagovest’s NPM Search

Blagovest’s NPM Search by Blagovest Dachev is a convenient (and fast) way to browse npm. In fact, it’s exactly the kind of thing I need to find things to write about for DailyJS. Thanks Blagovest!
jQuery Roundup: jquery-mobile-960, Easy WebSocket, mapKey, bValidator
jquery-mobile-960

jquery-mobile-960 (GitHub: jeromeetienne / jquery-mobile-960) by Jerome Etienne is a port of 960 grid to jQuery Mobile. By combining 960.gs with jQuery Mobile the author aims to offer more flexible layout options, which makes supporting tablets easier:
jQuery mobile layout is currently rather raw. They only split the width in even parts, providing little controls to the designer. It uses an custom API with names ending with a, b, c or d, ui-block-a for example. Not the classic grid-4 or span-3, so it feel awkward. […] 960 grids are flexible and well known. So i used ported 960 grids to see if it helps.
Easy WebSocket
Easy WebSocket (GitHub: jeromeetienne / EasyWebsocket, MIT License) also by Jerome Etienne is an effort to remove servers from the WebSocket equation. It appears to use iframes and a small Python App Engine script to make accessing resources as easy as this:
<script src="http://EasyWebsocket.org/easyWebSocket.min.js"></script>
<script>
var socket = new EasyWebSocket('ws://example.com/resource');
socket.onopen = function() {
socket.send('hello world.')
}
socket.onmessage = function(event) {
alert('received: ' + event.data);
}
</script>
So technically it still depends on a server, but it could make the lives of front-end developers simpler who aren’t used to messing around with server-side code.
mapKey
mapKey (GitHub: pixelmatrix / mapkey, MIT License) by Josh Pyles is a jQuery keyboard shortcut plugin that has aliases for a lot of keys. Rather than working out the key codes for arrow keys, left and up can be used instead:
$.mapKey('down', function() {
// Keyboard shortcut event support goes here
});
I always try to add keyboard shortcuts to my apps, so rather than my hokey homebrew keyboard code I might give this a try. One thing to remember when supporting hotkeys is to be specific — if a letter key is pressed should this still trigger when the shift or metakeys are held down?
bValidator

bValidator is a client-side validation library with extensive form control support and configuration options. Custom attributes can be used to define the required validations on a field:
<input type="text" data-bvalidator="alpha,minlength[10],required">
This can be changed when setting up the plugin:
('#form').bValidator({ validateActionsAttr: 'class' })
Node Tutorial Part 13
Welcome to part 13 of Let’s Make a Web App, a tutorial series about building a web app with Node. This series will walk you through the major areas you’ll need to face when building your own applications. These tutorials are tagged with lmawa.
Previous tutorials:
- Part 1: Introduction
- Part 2: Installation and Skeleton App, source code commit: 4ea936b
- Part 3: RESTful Methods and Testing, source code commit: 39e66cb
- Part 4: Templates, Partials, Creating and Editing Documents, source code commit: f66fdb
- Part 5: Authentication, Sessions, Access Control Middleware, source code commit: 03fe9b
- Part 6: Interface Basics, source code commit: f2261c
- Part 7: Node Library Versions, Jade Tricks, Error Pages, source code commit: 929f5
- Part 8: Flash Messages and Helpers, source code commit: 841a49
- Part 9: Remember Me, source code commit: 1904c
- Part 10: Markdown, source code commit: 11d33
- Part 11: Better Testing, source code commit: 6a269ce
- Part 12: Updating Mongoose, source code commit: 2a8725
Stylus
I wanted to improve Nodepad’s interface, but seeing as there’s been a lot of interest in Stylus lately I thought it might be good to switch to that while I was at it. Stylus is a CSS shorthand language, with many powerful features like variables, interpolation, mixins, and nested selectors.
Stylus can be installed with npm:
npm install stylus
Actually using it is fairly easy, it comes bundled with a middleware layer for Connect:
var stylus = require('stylus');
app.configure(function() {
// ...
app.use(stylus.middleware({ src: __dirname + '/public' }));
Writing Stylus
In Stylus, white space is significant, but this allows us to drop braces, colons, and semi-colons. That means our body style can be rewritten like this:
body
padding 0
margin 0
font 14px "Lucida Grande", "Helvetica Nueue", Arial, sans-serif
Another useful feature is variables. I looked through the file to find repeated chunks of CSS and replaced them with variables. Variables are written as variable-name = style:
active-colour = #dfe3ea
highlight-colour = #c5c5c5
faded-white = #f0f0f0
light-grey = #f6f6f6
medium-grey = #999
dark-grey = #666
black = #111
selected-colour = #8897ba
These are the colours that I pulled out of our original stylesheet. Now we can write styles with these variables:
.outline-view
position absolute
width 250px
background-color active-colour
In cases where we want to reuse variables and replace entire lines, we can use functions:
glass-background()
background light-grey url('/images/glass.png') repeat-x 50% 50%
grey-border()
border-top 1px solid highlight-colour
#controls
position absolute
left 252px
bottom 0
height 30px
grey-border()
glass-background()
Functions can accept parameters as well:
centre-shadow(size, colour)
-moz-box-shadow 0 0 size colour
-webkit-box-shadow 0 0 size colour
box-shadow 0 0 size colour
.flash .ui-corner-all
width 300px
margin 50px auto 0 auto
padding 0 5px
opacity 0.9
font-weight bold
centre-shadow(8px, light-grey)
Functions work as expected and can easily be combined with variables.
Bug Fixes
Meanwhile, EirĂkur Heiðar Nilsson helped improve the LoginToken model. The save middleware always replaced both the token and the series value were being updated, instead of just the token:
LoginToken.pre('save', function(next) {
// Automatically create the tokens
this.token = this.randomToken();
// This is eirikurn's modification:
if (this.isNew)
this.series = this.randomToken();
next();
});
This is in reference to part 9 of the Nodepad tutorials where we implemented “remember me” for the login form.
Conclusion
I think Stylus is a great way to make CSS more efficient. Take a look at commit 0a70e40 to see how I switched to Stylus (the diffs will help). And, just so you know, switching to Stylus wasn’t too hard — I basically did g/[{};:]/s///g in vim!
Making Games with JavaScript and Crafty
The day has come where JavaScript games are possible and not only possible but simple. This article will show you how easy it is to create games in JavaScript using the canvas tag and even basic divs with the help of a new game engine called Crafty.
This tutorial will demonstrate how to build a Pokemon-style RPG with Crafty. You’ll be able to add your own features once you learn the basics. If you’d like to see the what we’ll be building, view the demo.
Before we get started there are some key concepts to learn which may differ to what you are used to. Crafty uses something called an Entity Component system. Entities are your game objects (players, enemies, walls, balls) and Components are objects or a set of functions and properties that can be applied to any entity which will inherit the functionality.
If you are used to Object Oriented programming, this is similar to one level of multiple inheritance. This is useful in game development because it avoids long chains of inheritence and messy polymorphism.
Crafty uses syntax similar to jQuery by having a selector engine to select entities by their components:
Crafty("mycomponent")
Crafty("hello 2D component")
Crafty("hello, 2D, component")
The first selector will return all entities that has the component mycomponent. The second will return all entities that has hello and 2D and component whereas the last will return all entities that has at least one of those components.
If you are a bit confused, fear not, first hand experience will make it click. So let’s dive in!
Supplies
![]()
We need to setup our Crafty game. The skeleton of a Crafty game is a single HTML file with a script tag pointing to the Crafty JS file and another script tag for the game logic — in this example it’s game.js:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="http://craftyjs.com/release/0.3/crafty.js"></script>
<script type="text/javascript" src="game.js"></script>
<title>My Crafty Game</title>
<style>
body, html { margin:0; padding: 0; overflow:hidden; font-family:Arial; font-size:20px }
#cr-stage { border:2px solid black; margin:5px auto; color:white }
</style>
</head>
<body>
</body>
</html>
Here’s a simple Crafty game skeleton:
window.onload = function() {
//start crafty
Crafty.init(50, 400, 320);
Crafty.canvas();
};
When the window object is loaded, initialize Crafty with a frames per second of 50, a width and height of 400 and 320 respectively, and create a Canvas element. In case you’re wondering, the reason for these dimensions is so 25 16×16 tiles can fit horizontally and 20 vertically.
Note: Crafty.canvas() is required for any canvas drawing. It can be left out if all drawing is done with DOM.
Now we have the basics of a Crafty game! Every game you create with Crafty will have generally the same skeleton code so feel free to use this as a template. Next up is setting up scenes.
Scenes
Scenes in Crafty are a quick way to organise game objects and easily change between screens or levels. In our RPG we want a loading scene and the main scene which will be the game.
window.onload = function() {
// Start crafty
Crafty.init(50, 400, 320);
Crafty.canvas();
// The loading screen that will display while our assets load
Crafty.scene("loading", function() {
// Load takes an array of assets and a callback when complete
Crafty.load(["sprite.png"], function() {
Crafty.scene("main"); //when everything is loaded, run the main scene
});
// Black background with some loading text
Crafty.background("#000");
Crafty.e("2D, DOM, text").attr({w: 100, h: 20, x: 150, y: 120})
.text("Loading")
.css({"text-align": "center"});
});
// Automatically play the loading scene
Crafty.scene("loading");
};
Whoa, where did all that code come from? First we declare the loading scene and tell it what to display when it is played then run it straight away. Crafty.scene() is used to declare a scene as well as play it. In the loading scene we pre-load some assets, set the background to black and add some loading text. Crafty.load() is used to pre-load assets such as sounds or images and once completed, call a function. In our game we want to play the main scene as soon as the assets are loaded.
Note: If you need an entity to persist through changing scenes, simply add a component called persist.
Sprites
Remember that sprite map from earlier? It’s time to use that in the game and get some visuals here. Crafty has an inbuilt method to splice sprite maps into individual components that can be applied to any 2D entity.
window.onload = function() {
// Start crafty
Crafty.init(50, 400, 320);
Crafty.canvas();
// Turn the sprite map into usable components
Crafty.sprite(16, "sprite.png", {
grass1: [0,0],
grass2: [1,0],
grass3: [2,0],
grass4: [3,0],
flower: [0,1],
bush1: [0,2],
bush2: [1,2],
player: [0,3]
});
// The loading screen that will display while our assets load
Crafty.scene("loading", function() {
// Load takes an array of assets and a callback when complete
Crafty.load(["sprite.png"], function() {
Crafty.scene("main"); //when everything is loaded, run the main scene
});
// Black background with some loading text
Crafty.background("#000");
Crafty.e("2D, DOM, text").attr({w: 100, h: 20, x: 150, y: 120})
.text("Loading")
.css({"text-align": "center"});
});
// Automatically play the loading scene
Crafty.scene("loading");
};
The first argument is the tile size (in our case is 16 pixels by 16 pixels). This defaults to 1 if left out. The next argument is the path to the sprite map. Finally the last argument is an object where the key is the label and the value is an array for where the particular sprite is located in the image.
The values are multiplied by 16 so you need only give the amount of tiles from the top left. If a sprite takes up a width or height greater than one tile, simply add it to the array following this format:
[x, y, w, h]
You may notice that not all of the sprites in the sprite map have been labelled. This is because the sprites form an animation which we will add later.
window.onload = function() {
// Start crafty
Crafty.init(50, 400, 320);
Crafty.canvas();
// Turn the sprite map into usable components
Crafty.sprite(16, "sprite.png", {
grass1: [0,0],
grass2: [1,0],
grass3: [2,0],
grass4: [3,0],
flower: [0,1],
bush1: [0,2],
bush2: [1,2],
player: [0,3]
});
// Method to randomy generate the map
function generateWorld() {
// Generate the grass along the x-axis
for (var i = 0; i < 25; i++) {
// Generate the grass along the y-axis
for (var j = 0; j < 20; j++) {
grassType = Crafty.randRange(1, 4);
Crafty.e("2D, canvas, grass" + grassType)
.attr({x: i * 16, y: j * 16});
// 1/50 chance of drawing a flower and only within the bushes
if (i > 0 && i < 24 && j > 0 && j < 19 && Crafty.randRange(0, 50) > 49) {
Crafty.e("2D, DOM, flower, animate")
.attr({x: i * 16, y: j * 16})
.animate("wind", 0, 1, 3)
.bind("enterframe", function() {
if (!this.isPlaying())
this.animate("wind", 80);
});
}
}
}
// Create the bushes along the x-axis which will form the boundaries
for (var i = 0; i < 25; i++) {
Crafty.e("2D, canvas, wall_top, bush"+Crafty.randRange(1,2))
.attr({x: i * 16, y: 0, z: 2});
Crafty.e("2D, canvas, wall_bottom, bush"+Crafty.randRange(1,2))
.attr({x: i * 16, y: 304, z: 2});
}
// Create the bushes along the y-axis
// We need to start one more and one less to not overlap the previous bushes
for (var i = 1; i < 19; i++) {
Crafty.e("2D, canvas, wall_left, bush" + Crafty.randRange(1,2))
.attr({x: 0, y: i * 16, z: 2});
Crafty.e("2D, canvas, wall_right, bush" + Crafty.randRange(1,2))
.attr({x: 384, y: i * 16, z: 2});
}
}
// The loading screen that will display while our assets load
Crafty.scene("loading", function() {
// Load takes an array of assets and a callback when complete
Crafty.load(["sprite.png"], function() {
Crafty.scene("main"); //when everything is loaded, run the main scene
});
// Black background with some loading text
Crafty.background("#000");
Crafty.e("2D, DOM, text").attr({w: 100, h: 20, x: 150, y: 120})
.text("Loading")
.css({"text-align": "center"});
});
// Automatically play the loading scene
Crafty.scene("loading");
};
generateWorld() is a function that will create entities to fill up the stage. This is the first time we have created an entity so I will go over that first. The function to create an entity is simply Crafty.e(). That’s it. You can also pass a string of components to add which will just call the .addComponent() method. Have a look at the following lines of code:
grassType = Crafty.randRange(1, 4);
Crafty.e("2D, canvas, grass" + grassType)
.attr({x: i * 16, y: j * 16});
When we spliced the sprite map, we had four types of grass components/labels: grass1, grass2, grass3 and grass4. Using a little helper method, Crafty.randRange(), we generate a random number between 1 and 4 to decide which grass tile to use and apply it to the entity.
You will notice we are also adding some odd-looking components: 2D and canvas. 2D is a very important component which gives the entity and x and y position, width and height (called .w and .h), rotation, alpha and some basic rectangle calculations. The other component, canvas, tells Crafty how to draw the entity and with this component obviously on the canvas element. You can just as easy use the DOM component and it will instead draw it as a <div>.
Tip: DOM is usually always faster than canvas and if you notice sluggish performance in a canvas entity, try using DOM. It will look and act no different.
The rest of the method generates a boundary around the stage so the player can’t walk off. This uses the bush sprite. These boundary entities have a component, either wall_left, wall_right, wall_up or wall_down. The only purpose they serve is as a label — there is no inherited functionality.
Entities
Let’s create the player entity already! The source code is getting quite large so I will just show the code from the main scene.
Crafty.scene("main", function() {
generateWorld();
// Create our player entity with some premade components
var player = Crafty.e("2D, DOM, player, controls, animate, collision")
.attr({x: 160, y: 144, z: 1})
.animate("walk_left", 6, 3, 8)
.animate("walk_right", 9, 3, 11)
.animate("walk_up", 3, 3, 5)
.animate("walk_down", 0, 3, 2);
});
We call the generateWorld() function from earlier and create a player entity with some premade components: animate, controls and collision. Animate is a component to create animations for sprites. Similar to Crafty.scene(), you add an animation and play it with the same method with different arguments. The first argument is the name of the animation, the x position in the sprite map, y position in the sprite map and then the x position of the last frame in the sprite map (assuming the sprites all have the same y; if they don’t pass an array of arrays similar to the Crafty.sprite() method).
The controls component transforms keyboard input into Crafty events. Use .bind() to listen to an event. The events triggered in the controls component are keyup</codE> and <code>keydown. The collision component is a very basic method of calling a function if an entity intersects another entity with a specific component (this is where the labels come in handy such as wall_left, wall_right, etc.).
Note: The .attr() method is used to modify properties of the entity. In this case we position the player in the middle of the screen.
Components
It’s about time we really utilise the Entity Component system and create our first component. The component we need right now is something to control movement. There already exists two components for movement (twoway and fourway) but we want finer control and don’t want diagonal movement.
To create a component use the function Crafty.c(), where the first argument is the name of the component and the second is an object with properties and functions. To have a function execute as soon as it is added to an entity, create a function called init. If you need more information before initialising, best practice is to create a function with the same name as the component (commonly known as a constructor).
Crafty.scene("main", function() {
generateWorld();
Crafty.c('CustomControls', {
__move: {left: false, right: false, up: false, down: false},
_speed: 3,
CustomControls: function(speed) {
if (speed) this._speed = speed;
var move = this.__move;
this.bind('enterframe', function() {
// Move the player in a direction depending on the booleans
// Only move the player in one direction at a time (up/down/left/right)
if (move.right) this.x += this._speed;
else if (move.left) this.x -= this._speed;
else if (move.up) this.y -= this._speed;
else if (move.down) this.y += this._speed;
}).bind('keydown', function(e) {
// Default movement booleans to false
move.right = move.left = move.down = move.up = false;
// If keys are down, set the direction
if (e.keyCode === Crafty.keys.RA) move.right = true;
if (e.keyCode === Crafty.keys.LA) move.left = true;
if (e.keyCode === Crafty.keys.UA) move.up = true;
if (e.keyCode === Crafty.keys.DA) move.down = true;
this.preventTypeaheadFind(e);
}).bind('keyup', function(e) {
// If key is released, stop moving
if (e.keyCode === Crafty.keys.RA) move.right = false;
if (e.keyCode === Crafty.keys.LA) move.left = false;
if (e.keyCode === Crafty.keys.UA) move.up = false;
if (e.keyCode === Crafty.keys.DA) move.down = false;
this.preventTypeaheadFind(e);
});
return this;
}
});
// Create our player entity with some premade components
var player = Crafty.e("2D, DOM, player, controls, CustomControls, animate, collision")
.attr({x: 160, y: 144, z: 1})
.CustomControls(1)
.animate("walk_left", 6, 3, 8)
.animate("walk_right", 9, 3, 11)
.animate("walk_up", 3, 3, 5)
.animate("walk_down", 0, 3, 2);
});
Our component has two properties: __move and _speed. The first is an object of booleans used to indicate which direction the player should be moving. The second is how many pixels the character should move by or speed. We then just have one function, the constructor. We could easily just use an init method here and assume a speed of 3, but we want a speed of 1 so a constructor is needed to indicate that.
We use the .bind() method a fair bit in this component. The enterframe event is called on every frame (depending on the FPS) so when the callback is triggered, it will move the player in a direction depending on which direction is true and by the amount/speed we previously decided.
The other two events, keydown and keyup, simply check which key has been pressed (derived from the event object passed as an argument) and then set the movement boolean. There is a reason why we don’t simply move the player as soon as the key is down. The keydown event will trigger once then have a short pause before calling it over and over until a key is up. We don’t want that pause so we use the enterframe event to continuously move the player. The keyup callback does the same as keydown but in reverse, sets the movement booleans to false if the key has been released.
You will also notice our player entity has our new component in the component list as well as calling the constructor. Our player should be able to move now.
Note: Using an underscore before property or function names is the convention we’re using to convey that it is private.
Animation
Now that the player can move, we want to play the animation we setup earlier.
// Create our player entity with some premade components
var player = Crafty.e("2D, DOM, player, controls, CustomControls, animate, collision")
.attr({x: 160, y: 144, z: 1})
.CustomControls(1)
.animate("walk_left", 6, 3, 8)
.animate("walk_right", 9, 3, 11)
.animate("walk_up", 3, 3, 5)
.animate("walk_down", 0, 3, 2)
.bind("enterframe", function(e) {
if (this.__move.left) {
if (!this.isPlaying("walk_left"))
this.stop().animate("walk_left", 10);
}
if (this.__move.right) {
if (!this.isPlaying("walk_right"))
this.stop().animate("walk_right", 10);
}
if (this.__move.up) {
if (!this.isPlaying("walk_up"))
this.stop().animate("walk_up", 10);
}
if (this.__move.down) {
if (!this.isPlaying("walk_down"))
this.stop().animate("walk_down", 10);
}
}).bind("keyup", function(e) {
this.stop();
});
On the enterframe event we want to know the direction the player is moving (using the movement booleans created in our component) and play the appropriate animation. We don’t want to play it if it is already playing however, so we use the .isPlaying() function. If it isn’t playing, stop whatever animation is playing with the .stop() function and play the correct one. Playing an animation is a matter of calling .animate() with the name of the animation and a duration in frames. Because we only have 3 frames for the animation, we want it to be fairly quick. We also want to stop any animation if a key is up.
Collision
Crafty provides collision detection between any two convex polygons. A collision exists when two entities intersect each other. We use the pre-made collision component to detect collisions with the boundary so the player can’t leave the stage.

// Create our player entity with some premade components
var player = Crafty.e("2D, DOM, player, controls, CustomControls, animate, collision")
.attr({x: 160, y: 144, z: 1})
.CustomControls(1)
.animate("walk_left", 6, 3, 8)
.animate("walk_right", 9, 3, 11)
.animate("walk_up", 3, 3, 5)
.animate("walk_down", 0, 3, 2)
.bind("enterframe", function(e) {
if (this.__move.left) {
if (!this.isPlaying("walk_left"))
this.stop().animate("walk_left", 10);
}
if (this.__move.right) {
if (!this.isPlaying("walk_right"))
this.stop().animate("walk_right", 10);
}
if (this.__move.up) {
if (!this.isPlaying("walk_up"))
this.stop().animate("walk_up", 10);
}
if (this.__move.down) {
if (!this.isPlaying("walk_down"))
this.stop().animate("walk_down", 10);
}
}).bind("keyup", function(e) {
this.stop();
}).collision()
.onhit("wall_left", function() {
this.x += this._speed;
this.stop();
}).onhit("wall_right", function() {
this.x -= this._speed;
this.stop();
}).onhit("wall_bottom", function() {
this.y -= this._speed;
this.stop();
}).onhit("wall_top", function() {
this.y += this._speed;
this.stop();
});
Remember those labels we put on the bushes earlier? Now is when they become useful. The function .collision() is the constructor and accepts a polygon object (see Crafty.polygon) or if empty will create one based on the entity’s x, y, w and h values.
.onhit() takes two arguments, the first is the component to watch for collisions and the second is the function called if a collision occurs. If the player collides with any entity with the component wall_left, we need to move the player away from the wall at the same speed it is moving towards it. We need to do this for all other walls so depending on the direction, move the player in the opposite direction at the same speed. I also added the .stop() function so that it doesn’t keep animating when it isn’t moving.
Final Code
Putting together everything we learnt, we should have the following: crafty-demo.js.
Now you should have the basics of an RPG!
If you need any support using Crafty, please visit the Crafty forums and Crafty documentation.
Node 0.4
The second stable branch of Node, 0.4, has been announced. The 0.4 announcement has an overview of the changes, and there’s a GitHub Node wiki page about migrating from 0.2 to 0.4.
A lot of the changes are relatively low-level. However, libraries and frameworks like Express may require updating. From what I’ve learned by watching the 0.3 changes on the nodejs Google Group, it sounds like the 0.4 changes are positive — a cleaner HTTP client API, better HTTPS support, and a more efficient Buffer.
It’s also interesting to see npm mentioned in the release announcement:
In particular, NPM was forced to resort to deep symlinks and “shim” modules to work around missing features in
require().
These changes include require() awareness of package.json, and the relative path node_modules/ being searched for modules. This will make it very easy to bundle modules with apps, potentially simplifying deployment and distribution.
You may also be interested in reading the pertinent V8 change log.
Node Roundup: 0.3.8, node-database-cleaner, node-config
Welcome to the Node Roundup. Send in your apps and libraries using our contact form or @dailyjs.
Node 0.3.8
Node 0.3.8 is out. Here’s the change log with some annotations:
- Add
req.abort()for client side requests - Add
exception.codefor easy testing. For example:if (err.code == 'EADDRINUSE'); - Add
process.stderr require.mainis the main module. (Isaac Schlueter)- dgram:
setMulticastTTL,setMulticastLoopbackandaddMembership. (Joe Walnes) - Fix throttling in TLS connections
- Add
socket.bufferSize - MinGW improvements (Bert Belder)
- Upgrade V8 to 3.1.1
Download: nodejs.org/dist/node-v0.3.8.tar.gz
Website: nodejs.org/docs/v0.3.8
Documentation: nodejs.org/docs/v0.3.8/api
node-database-cleaner
node-database-cleaner (MIT Licensed) by Emerson Macedo knows how to wipe databases. This is useful for writing tests that test against a test database — you might have seen me do something similar in our Node tutorials. It currently works with Mongo.
node-config
node-config (Apache License 2.0) by Loren West is a configuration management library for Node. It can be used to provide consistent access to configuration variables, but also makes it easy to override defaults with values from command-line options or configuration files.
Defining configurations looks like this:
// Customers.js - Customer management utilities
// Configuration parameters and default values
var config = require('config')('Customers', {
dbHost: 'localhost',
dbPort: 5984,
dbName: 'customers',
syncFrequency: 60
});
Which makes this possible:
$ node billing.js -config smokeTest.js -Customers.dbPort 5985
One useful trick Loren points out in the README is programmatic configuration through argv:
process.argv.push('-Customers.dbPort', 5994);
require('Customers');
jQuery Roundup: Isotope, Query, 1.5 Changes, File Upload
Isotope

Isotope (GitHub: desandro / isotope) by David DeSandro and Metafizzy is a layout plugin with lots of options and elegant animations. The basic Isotope demo repositions elements (literally) when the browser is resized. Elements can also be filtered, and it can cope with resized elements using the reLayout method.
Query
Query by TJ Holowaychuk is jQuery for the command-line. It uses Node and jsdom to provide nifty shell access to jQuery selectors and DOM traversal features:
curl http://twitter.com | query 'a#logo' | query img attr alt
# Returns 'Twitter'
Node is required, and Query can be installed using npm with npm install query.
jQuery 1.5 Changes
jQuery 1.5 Changes Part I by Garrett from Red Ventures discusses the new Ajax module in jQuery 1.5 with some details on $.Deferred(), which while incredibly useful, may seem confusing at first.
jQuery File Upload
jQuery File Upload (GitHub: blueimp / jQuery-File-Upload) by Sebastian Tschan is a jQuery file upload plugin that handles multiple files, drag and drop, progress bars, cancelled uploads, and a lot more features.
This plugin also optionally uses jQuery UI for additional interface features.
Node Tutorial Part 12
Welcome to part 12 of Let’s Make a Web App, a tutorial series about building a web app with Node. This series will walk you through the major areas you’ll need to face when building your own applications. These tutorials are tagged with lmawa.
Previous tutorials:
- Part 1: Introduction
- Part 2: Installation and Skeleton App, source code commit: 4ea936b
- Part 3: RESTful Methods and Testing, source code commit: 39e66cb
- Part 4: Templates, Partials, Creating and Editing Documents, source code commit: f66fdb
- Part 5: Authentication, Sessions, Access Control Middleware, source code commit: 03fe9b
- Part 6: Interface Basics, source code commit: f2261c
- Part 7: Node Library Versions, Jade Tricks, Error Pages, source code commit: 929f5
- Part 8: Flash Messages and Helpers, source code commit: 841a49
- Part 9: Remember Me, source code commit: 1904c
- Part 10: Markdown, source code commit: 11d33
- Part 11: Better Testing, source code commit: 6a269ce
Updating Mongoose
Mongoose 1.0.0 has been released, which changes the API quite significantly. In particular, model definitions are very different to the version we were using. I’ve updated the app to use Mongoose 1.0.7 so you’ll be able to learn how to use the new API.
Because we’ve locked all of our packages to versions using npm’s @version syntax, it’s easy to switch between versions of a package. The new version of Mongoose can be installed like this:
npm install mongoose@1.0.7
I then went through and updated the requires:
mongoose = require('mongoose@1.0.7')
The file that needs the most changes is models.js. Let’s look at the Document model to see how it can be defined with the new API.
Document Model
Mongoose 1.0 models are defined using Schema objects. Once they’ve been defined it’s possible to decorate them with virtual attributes and middleware. Virtual attributes are getters and setters, and middleware is a convenient way of injecting functions into key lifecycle events.
The schema just defines attributes and their associated properties — validations can even be defined. Nodepad’s Document model is actually very simple:
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
Document = new Schema({
'title': { type: String, index: true },
'data': String,
'tags': [String],
'user_id': ObjectId
});
I’ve defined an index on the title attribute, and told Mongoose what types I want to use. Notice that the tag array (which is currently unused) is defined using [String] rather than Array or some other collection type.
Once a schema has been defined it’s important to tell Mongoose about it:
mongoose.model('Document', Document);
Now the Document model can be used like this:
mongoose.model('Document');
All of these commands will be queued if there isn’t a database connection yet.
User Model
The User schema is a bit more complicated. We need to validate the presence of an email address and password. It’s easy for email addresses:
function validatePresenceOf(value) {
return value && value.length;
}
User = new Schema({
'email': { type: String, validate: [validatePresenceOf, 'an email is required'], index: { unique: true } },
'hashed_password': String,
'salt': String
});
Mongoose lets us define functions for validators. It’ll also accept a regular expression.
I haven’t defined a password attribute because we don’t want to store the plaintext password. Previously this was defined as a ‘getter’; now it needs to be a virtual attribute:
User.virtual('password')
.set(function(password) {
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
})
.get(function() { return this._password; });
There are a few interesting points here:
- The syntax for getters and setters requires a call to
virtualfirst - The getter and setters are defined with
getandset - These definitions can be chained
The next thing we need to do is make sure this password is validated. We can’t do it with the schema definition because it’s a virtual attribute, so let’s use the new middleware feature instead:
User.pre('save', function(next) {
if (!validatePresenceOf(this.password)) {
next(new Error('Invalid password'));
} else {
next();
}
});
I’ve reused the function from the email validation. This function will run before save is called. Calling next() will move to the next middleware or save itself, but passing an Error will cause the error to be returned to the function passed to save from Nodepad’s app code:
user.save(function(err) {
if (err) return userSaveFailed();
// ...
The old API wasn’t as flexible as this, so I hope middleware makes switching to the new API worth the effort.
Instance Methods
One thing I couldn’t find in the Mongoose documentation was how to define instance methods. I tried calling Schema.method and it just happened to work, so for reference it looks like this:
User.method('authenticate', function(plainText) {
return this.encryptPassword(plainText) === this.hashed_password;
});
User.method('makeSalt', function() {
return Math.round((new Date().valueOf() * Math.random())) + '';
});
User.method('encryptPassword', function(password) {
return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
});
These are the methods we use to make dealing with passwords easier.
The other model in the project, LoginToken, just uses the same techniques discussed here.
Query Signature Changes
For a start, Model.find().first() no-longer works. We now need to use findOne:
app.post('/sessions', function(req, res) {
User.findOne({ email: req.body.user.email }, function(err, user) {
if (user && user.authenticate(req.body.user.password)) {
req.session.user_id = user.id;
// ...
Secondly, the query callback signature has changed to function(err, user). This makes error handling more convenient but meant I had to change every single finder in the entire project.
Conclusion
It took me about 3 hours to learn Mongoose 1.0 and port Nodepad to it. However, Nodepad is a pretty small project, so keep this in mind if you’d like to move your own projects to the newer API.
This week’s code is commit 2a8725.
Mongoose 1.0, Chrome WebGL, it-is
Mongoose 1.0

Mongoose 1.0 has been finally released by Guillermo Rauch, Nathan White, and Brian Noguchi. I’ve been watching their 1.0 branch for a while because the API looks improved over the older versions. Incidentally, the older API is what we’ve used for my Nodepad tutorials, so at some point I’ll update Nodepad to Mongoose 1.0.
There’s now a generic Schema class:
var Comments = new Schema({
title : String
, body : String
, date : Date
});
They’ve also added middleware, which is a very interesting feature for reducing nested callbacks. Middleware is defined on the Schema objects like this:
schema.pre('save', function (next) {
// something goes wrong
next(new Error('something went wrong'));
});
// later...
myModel.save(function (err) {
// err can come from a middleware
});
If you want to read more, there’s some nice documentation available for Mongoose on mongoosejs.com.
Chrome WebGL

Until now, Chrome had nascent support for WebGL which was enabled with a command line flag. Version 9 now includes it by default, and Google’s blog post about the update includes a link to some interesting WebGL demos.
it-is
Dominic Tarr said he got tired of typing should all the time, so he made it-is. It’s a very terse assertion library, which supports expressions like these:
it(actual).equal(10)
it({a:1, b: 3})
.has({
a: it.typeof('number').notEqual(3)
, b: it.equal(3)
})
It looks like Dominic is aiming to support Node with this library, so it might currently be more useful for server-side testing rather than client side. You should be able to get it with: npm install it-is.
