Tuesday, May 12, 2009

Beholder: A Ruby Template Engine

I started up a new project to create a template engine for Ruby web apps. The beginnings of it are on github here. It's very, very rough, so don't judge yet. :-)

I know there are a ton of template engines out there. But here's my complaint with them: often the person developing the front end of an app is primarily an HTML/CSS/JavaScript developer. They may not know Ruby at all. So template engines like Markaby and Hoshi are out. ERB is the most HTML-like template engine, but a) it's still got Ruby mixed into it, so it isn't ideal for strictly front-end developers, and b) it's a mixture of Ruby and HTML, which is ugly and spaghetti-ish.

Enter Beholder.

Beholder is a template engine comprised of HTML tags. Dynamic behavior is accomplished through the use attributes. So, for example, if you have a page and you want to show a chunk of it conditionally, you could do something like this:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<span component="if" condition="true">
Body of 'if' component
</span>
<span component="elsif" condition="true">
Body of 'elsif' component
</span>
<span component="else">
Body of 'else' component
</span>
</body>
</html>
Which would be rendered as:
<html>
<head>
<title>Hello World</title>
</head>
<body>
Body of 'if' component
</body>
</html>
The 'component' attribute can either refer to a built in control flow structure, such as 'if', or 'foreach', or it can refer to a partial, so you can embed mini-beholder templates in your main template. There is also a 'yield' component, so each component can act like a layout, generating it's HTML, and then yielding the content within the component node in the template.

In addition, any attribute can be made dynamically by including the 'prop:' prefix. So if you have a template like this:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<span component="simple_component" message_class="beholder" />
</body>
</html>
And a partial called simple_component.beh like this:
<p class="prop:message_class">What's up, world?</p>
It would be rendered like this:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<p class="beholder">What's up, world?</p>
</body>
</html>
The 'prop:' prefixed attributes get evaluated as (in this order) a) the value of the parent component's attribute with that name, b) the value of a local variable of that name, or c) a method in the helper class. (Note that I've only implemented a) right now... so you'll just have to trust me that that's where I'm going.)

This is modeled after Tapestry templates (Java) and Kid templates (Python). Anyway, there's a lot of work to be done on it (particularly around the evaluation of 'prop:' attributes), but I like the idea of it a lot.

Sunday, May 3, 2009

Ruby HTML Template Engines

I've been thinking a bit about template engines in Ruby. There's a ton of them out there. Here's a good review of a bunch of them. We generally use either Hoshi or Markaby at my job right now. For our purposes, these have been great. We all work on all aspects of a project, from front to back, and we'd all rather write Ruby than HTML. However, in several jobs I've had, we've had a front-end developer doing all the HTML and CSS. The problem is that people who really specialize in front-end development often don't know Ruby. So Hoshi and Markaby are out. In those situations, we've used ERB templates. But then you've got Ruby and HTML mixed together, and that's never pretty. What I'd really like is a template engine that just looks like HTML, with no Ruby mixed into it. Something along the lines of Python's Kid, or Java's Tapestry templates. I've been looking around a bit and haven't found anything like that yet in Ruby. Sounds like time to spin up a new project! More to come...