Text

Jade & Stylus 0.16.0 released

Jade 0.16.0

This release of Jade adds quite a few new features such block support for include, and template inheritance!

Extended grammar

Jade currently allows you to use JavaScript all over the place, rather than restricting a subset, or implement its own grammar. While this is flexible it tends to make templates look less like … templates! In an effort to make Jade more declarative I’ve added literal support for if, unless, while, until, iteration, assignments and others.

For example I consider it bad practice to define vars in a template, however if you must, you may have previously done something like this:

  - var items = ['foo', 'bar', 'baz']

Jade now allows for assignment, where the right-hand operand is still a regular javascript expression:

   items = ['foo', 'bar', 'baz']

As mentioned if and unless and friends are supported, so the following:

 - if (!(foo && bar))
   p stuff

May now be defined as:

  unless foo && bar
    p stuff

This rule applies to else[ if] as well:

  if something
    p foo
  else if somethingElse
    p bar
  else
    p baz

And finally iteration where each and for are interchangeable:

 - items.forEach(function(item){
   li= item
 - }) 

each item in items
  li= item

for item in items
  li= item

each item, i in items
  li #{i}: #{item}

each val, key in obj
  li #{key}: #{val}

Include blocks

The include directive now supports blocks, so for example one could have head.jade defined as the following:

  head
    script(src='/javascripts/jquery.js')

Allowing you to either include the file as-is:

  html
    include head
    body
      h1 Title

or append to the last block defined, adding additional script tags:

  html
    include head
      script(src='/javascripts/caustic.js')
      script(src='/javascripts/app.js')
    body
      h1 Title

Template inheritance

Jade now supports template inheritance via the block and extends keywords. A block is simply a “block” (indented) of Jade that may be replaced within a child template, this process is recursive.

Jade blocks can provide default content if desired, however optional as shown below by block scripts, block content, and block foot.

// layout.jade
html
  head
    h1 My Site - #{title}
    block scripts
      script(src='/jquery.js')
  body
    block content
    block foot
      #footer
        p some footer content

Now to extend the layout, simply create a new file and use the extends directive as shown below, giving the path (with or without the .jade extension). You may now define one or more blocks that will override the parent block content, note that here the foot block is not redefined and will output “some footer content”.

// index.jade
extends layout

block scripts
  script(src='/jquery.js')
  script(src='/pets.js')

block content
  h1= title
  each pet in pets
    include pet

It’s also possible to override a block to provide additional blocks, as shown in the following example where content now exposes a sidebar and primary block for overriding, or the child template could override content all together.

// funky-layout.jade
extends layout

block content
  .sidebar
    block sidebar
      p nothing
  .primary
    block primary
      p nothing

For the rest of the changes and bug fixes check out the changelog.

Stylus 0.16.0

Fewer changes than the latest Jade however still some good ones!

:= operator

This new operator is an alias of ?= operator, because I think ?= is difficult to read in large quantities for configuration etc:

grid-columns ?= 16
grid-column-width ?= 40px
grid-gutter-width ?= 20px
extra-space ?= 40px

grid-columns := 16
grid-column-width := 40px
grid-gutter-width := 20px
extra-space := 40px

Adjusting color lightness

While the lighten(color, amount) and darken(color, amount) BIFs are still available, the + and - operators now provide the same functionality when used with percentages as illustrated below:

  lighten(black, 50%)
  // => #808080

  black + 50%
  // => #808080

fade-in() & fade-out() BIFs

These small built-in functions are defined in stylus as the following to adjust the opacity:

  // decerase opacity by amount

  fade-out(color, amount)
    color - rgba(black, amount)

  // increase opacity by amount

  fade-in(color, amount)
    color + rgba(black, amount)

For example:

fade-out(#eee, .5)
// => rgba(238,238,238,0.50);

fade-out(fade-out(#eee, .3), .5)
// => rgba(238,238,238,0.20);

Check out the changelog for the other bugfixes and additions.

Text

Stylus 0.15.1 - new property reference & @keyframes fabrication features

Stylus 0.15.x adds a bunch of cool new functionality as well as some important bug fixes.

@keyframes fabrication

The new keyframes fabrication support automatically duplicates your @keyframes definitions to support vendor prefixes. Note that this is only a default, as shown below:

@-moz-keyframes foo {
  0% {
    color: #000;
  }

  100% {
    color: #fff;
  }
}
@-webkit-keyframes foo {
  0% {
    color: #000;
  }

  100% {
    color: #fff;
  }
}
@keyframes foo {
  0% {
    color: #000;
  }

  100% {
    color: #fff;
  }
}

one can tweak this functionality using the vendors list as shown in the following snippet which will only expand to the -webkit- vendor prefix.

vendors = moz official

@keyframes foo {
  from {
    color: black
  }
  to {
    color: white
  }
}

The vendors property may be utilized more in the future, and perhaps in frameworks like “nib” to unify configuration.

Property reference

The syntax @<property> has been introduced to reference values of existing properties. For example if you want to re-use values, you may typically do something like below instead of typing the value several times, also allowing you to use functions with w.

.button
  width: w = 50px
  height: w

The new property reference syntax allows you to treat properties as variables, which can also be accessed within mixins:

.button
  width: 50px
  height: @width

Comment compilation

When the compress option is true Stylus will not output single-line nor multi-line comments, which are commonly found used for licensing in stylesheet frameworks etc, so it’s useful to strip these out however you can now force output with the ! character /*!.

New built-in functions

The math functions cos() and sin() were added, as well as exposing PI.

Bug fixes

  • Fixed @import on windows
Tags: stylus nodejs js
Text

Connect 1.7.0 - fast static file memory cache and more

Be sure to update Connect to the latest release 1.7.0 for the following goodies!

staticCache() middleware

1.7.0 now provides a new middleware named staticCache(), acting as a memory cache on top of the regular static() middleware. Older versions of Connect used to provide memory caching, however it was baked right into static(), bloating the middleware more than necessary.

Benchmarks

The test file for these benchmarks is a small 4kb readme:

$ du -h Readme.md 
4.0K    Readme.md

and the following ApacheBench command:

$ ab -n 5000 -c 50 -k http://local/Readme.md

First up we have Connect static(), which does not perform any caching, performing disk I/O each request, serving ~2400rps.

connect()
  .use(connect.static(__dirname))
  .listen(3000)

Next up we have node-static one of the other popular node solutions, serving ~3800rps

var static = require('node-static')
  , file = new static.Server(__dirname);

http.createServer(function(req, res){
  file.serve(req, res);
}).listen(3000);

Then we have the new staticCache() middleware paired with static() serving ~5000rps, a 24% increase over node-static (which also performs memory caching), and ~52% over static() alone.

connect()
  .use(connect.staticCache())
  .use(connect.static(__dirname))
  .listen(3000)

staticCache() is configurable, allowing you to specify the maximum number of cache objects to store, and the maximum size allowed, so you can cap resources appropriately. The middleware implements a Least Recently Used algorithm to prioritize popular files, knocking less popular objects out of the cache.

res.headerSent

Node core has a private flag named res._headerSent, allowing you to check if the header has been written or not, this is extremely useful in some cases, so Connect has publicized this property as res.headerSent until Node core does (if ever), using a getter to reference the private property.

logger() immediate option

The logger() middleware now provides { immediate: true }, as by default this middleware will log the response of a request, not when the request is first received, allowing logging of response-times etc.

Tags: connect nodejs
Text

Game prototyping with JavaScript & CSS3

I wanted to share a quick few-hour game prototype to hopefully inspire a few people! The industry let-alone browser-based games seem very lacking in imagination and storytelling, or maybe I’m just not looking hard enough ;) but I miss games like Grim Fandango.

Below is a screenshot of the demo, consisting of several DOM nodes to represent parts of the main character, the birds, and the scene. Most of the animation is performed with CSS transitions / animations, some of which are dynamic and use the move.js library.

I have yet to profile anything but it runs quite smooth on my machine, and there are many aspects that could be optimized, and some simple ones like ditching jQuery.

iPhone gaming

Back to the original plan, roughly two years ago before the Ipad came out, I was writing an Objective-C iPhone game with Cocos2d and Chipmunk physics, two really wicked libraries. The iPhone seemed too small, and at the time the resolution was not great either, not to mention the image size restraints that Apple enforced, so I gave up after a few prototypes, and one full-screen PC prototype.

Browser gaming

With the advent of modern browsers, browser gaming is already a lot less shitty than a year or two ago, and it’s only about to get much better with all the work browser vendors are putting into making sure canvas and friends run smooth as butter.

The first prototype I wrote was written entirely with Canvas. One of the main benefits of this is a certain level of control that you obtain, it’s extremely easy to implement features like pausing, to apply post-processing, or ad-hoc features that are difficult with the DOM.

At first I was pretty happy with the result, until I wrote the prototype using CSS3 and HTML, the performance impact was pretty significant (though I had not implemented dirty rects etc). Certain aspects of gaming are significantly easier using the DOM, for example leveraging z-index and CSS transitions, however contrasting canvas pausing and post-processing are more of a problem. At least with the currently state of browser technologies, it’s a good idea to mix and match. You can build a large portion of your game using the DOM, and canvas for aspects like particle emitters, or perhaps even WebGL shaders like this awesome demo.

Demo

The video below shows off some of the interactivity, as well as the tiny scene building tool.

The demo consists of ~200 lines of js and ~200 lines of CSS, using CSS for transformations, animations and obviously for styling, while the js performs some basic interactions like the eye-ball targeting, and randomized cat walk routine. The demo also has a small toolkit for creating scenes, but it’s certainly nothing robust.

Source

You can grab the source on Github. Ping me of you come up with some cool prototypes!

Concepts

Some more concepts:

Tags: game css js
Text

commander.js - nodejs command-line interfaces made easy

Commander.js is a small node.js module allowing you to define options and interacte with the user’s terminal in a simple and natural way, inspired by the Ruby library of the same name.

Features

  • self-documenting code
  • auto-generated help
  • combined short flags (“-abc” == “-a -b -c”)
  • option defaults
  • option coercion
  • command parsing
  • prompts

Example

A basic commander program looks something like the following (taken from serve). It’s extremely easy to see what’s going on, all the options provided by the executable are laid out infront of you.

program
  .version('0.0.1')
  .option('-p, --port <port>', 'specify the port [3000]', Number, 3000)
  .option('-H, --hidden', 'enable hidden file serving')
  .option('-I, --no-icons', 'disable file icons')
  .option('-L, --no-logs', 'disable request logging')
  .parse(process.argv);

In the previous example only --port accepts an argument, and the value of program.port defaults to 3000. The options --no-icons and --no-logs default their properties to true, only when --no-icons is specified will program.icons be false.

The usage information is free!:

$ serve --help

  Usage: serve [options]

  Options:

    -v, --version      output the version number
    -p, --port <port>  specify the port [3000]
    -H, --hidden       enable hidden file serving
    -I, --no-icons     disable file icons
    -L, --no-logs      disable request logging
    -h, --help         output usage information

Utilities

Commander is bundled with some utilities for prompting user input, confirmations, passwords, lists of choices etc. Most of these utilities will ask for input if the user simply hits enter and should respond.

Below is an example of asking for a name using a single-line input prompt:

program.prompt('name: ', function(name){
  console.log('hi %s', name);
});

Multi-line input is easy too, just leave out the trailing space in the message:

program.prompt('description:', function(name){
  console.log('hi %s', name);
});

Coercion is useful for dates, numbers etc:

 program.prompt('Age: ', Number, function(age){
  console.log('age: %j', age);
});

Password prompts masking off input:

program.password('Password: ', function(pass){
  console.log('got "%s"', pass);
});

Or providing a mask char:

program.password('Password: ', '*', function(pass){
  console.log('got "%s"', pass);
});

Confirmations require “yes” or “y” to result in true:

 program.confirm('continue? ', function(ok){
   console.log(' got %j', ok);
 });

There’s also choice support, so users can select from a list:

var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];

console.log('Choose the coolest pet:');
program.choose(list, function(i){
  console.log('you chose %d "%s"', i, list[i]);
});

presenting:

Choose the coolest pet:
  1) tobi
  2) loki
  3) jane
  4) manny
  5) luna

Commands

Though I haven’t had time to polish them up yet, commander supports the idea of .. well… “commands”. The “root” executable is an instanceof Command, and well you can recursively define these to create a rich interface. GIT is a great example of this, many larger utilities use sub-command such as git remote to accept arguments, and may all then have their own options etc, using the same API as the root command. The following is a simple example:

#!/usr/bin/env node

var program = require('../');

program
  .version('0.0.1')
  .option('-C, --chdir <path>', 'change the working directory')
  .option('-c, --config <path>', 'set config path [./deploy.conf]')
  .option('-T, --no-tests', 'ignore test hook')

// $ deploy setup stage
// $ deploy setup
program
  .command('setup [env]')
  .description('run setup commands for all envs')
  .action(function(env){
    env = env || 'all';
    console.log('setup for %s env(s)', env);
  });

// $ deploy stage
// $ deploy production
program
  .command('*')
  .action(function(env){
    console.log('deploying "%s"', env);
  });

program.parse(process.argv);

Moar Libraries!

Dont forget to check out these other great CLI-related libraries:

Text

Introducing Texty & Super Agent screencast

In this 20 minute screencast we dive into the full-text Redis search library reds for nodejs, an introduction to the canvas-only text editing library Texty, discussing how you can style canvas drawings with CSS, and the “ajax with less suck” library superagent.