1.6.3 BSD License    
  not rated
A template language grammar that looks, feels, and works like Python




plywood is a template language grammar that looks, feels, and works like Python

 meta(name="viewport", content="width=device-width; initial-scale=1.0")
 if title:
 # docstrings *are* stripped of preceding whitespace (they must be
 # indented), and the first and last newline is removed.
 {title} |
 """ # string intepolation is a little more heavy-duty than `.format()`, but more similar than different.
 'Welcome' # string literals require quotes :-/ I *might* add another way to do this...
 link(rel='stylesheet', type='text/css', href=static('css/reset.css'))
 link(rel='stylesheet', type='text/css', href=static('css/welcome.css'))
 script(src="//", type="text/javascript")
 script(src=static("js/underscore.js"), type="text/javascript")
 script(src=static("js/backbone.js"), type="text/javascript")
 ieif 'lt IE 9':
 script(src="//", type="text/javascript")
 link(rel='stylesheet', type='text/css', href=static('css/ie.css'))
 block('extra_head') # blocks, and block inheritance? of course!
 div(class="wrapper", id="wrapper") # no shorthand for class and id (yet)
 if user:
 'Welcome, '{}'
 if current_member:
 "Welcome, {current_member.preferred_name}"
 a(href=url("logout")): 'Log Out'
 li: a(href=url("login")): 'Login'

 section class="breadcrumb":

 if messages:
 for message in messages:
 li(class=message.tags): '{message}'
 # code literals, so that savvy editors can color the source code

 var fade_out = _(function() {

 setTimeout(fade_out, 5000);
 $("ul.messages").bind("click", fade_out);

 # p:
 # 'These are comments.'
 # span: '|'
 # '©2012 CrossFit'


 pip install plywood
 ply < in.ply > out.html


Each line starts with a statement, which can either be a function (div, block) a literal (', '''), or a control statement (if, else, for).

Functions get called with the arguments and a "block":

# arguments are ((), {}), block is Block()
# arguments are ((), {'class': 'divvy'}), block is Block()
# arguments are (('autofocus'), {'id': 'bio'}), block is Block(Literal('This is my bio'),)
textarea(autofocus, id="bio"): 'This is my bio'

Even if there is no "block", you'll get at the least at empty block object that you can call block.render on. It will be "falsey", though, so you can check for the existence of a block. The minimum "truthy" block is an empty string. That means div '' will give you a "truthy" block, but div will be a "falsey" block.

You can extend the crap out of plywood, because div, if, block, the whole lot, are all written as plywood extensions. Without the builtin extensions, the language couldn't actually do anything, because it is at its core just a language grammar.


I think there is room for another templating language.

Haml? Coffekup? Jade? They don't seem pythonic to me.

Plain-Jane HTML? Sure, if you want. That is, I think, the best alternative to plywood.

Even the great django template language is HTML made nastier by inserting additional markup. I looked at Jade and Haml as "yeah, you're getting there", but they didn't nail it.

I'm unapologettically a DIY-er. I think that sometimes wheels just need re-inventing! Plus, this gave me a chance to play with language grammars, which I think are fun. I'm using Modgrammar
Last updated on June 18th, 2012

0 User reviews so far.