Why No External Templates?

I was asked on Twitter:

Could you expand in why [Swiccup] versus a template language?

I gave a brief answer there, but I think it’s worth talking about a bit more. Many of the HTML templating languages out there are simply trying to solve the problem that crafting HTML in code (or crafting HTML in general) can be a real pain.

As an example, the desired output might be this:

<b>resque</b>
<b>hub</b>
<b>rip</b>

You have the data structure of:

"repo": [
  { "name": "resque" },
  { "name": "hub" },
  { "name": "rip" }
]

Using HTML libraries in code are generally a huge pain. But if you can have a file that simply describes this as (in mustache):

{{#repo}}
  <b>{{name}}</b>
{{/repo}}

Or in Leaf, maybe it looks like this:

#loop(repo, "name") {
  <b>#(name)</b>
}

This is so much easier to read, understand, maintain, and author than authoring this by hand which might look something like:

for repo in repos {
  output.writeln("<b>\(repo)</b>")
}

Of if you’re using a typical HTML library:

for repo in repos {
  parent.addChild(HtmlBoldElement(repo))
}

The templates are just better.

So what’s the problem?

The problem is that they still come at a cost. Maybe times we’re moving from a typed system to an untyped system, so typos are easy to have happen. Most of the time there are no tools to help ensure that the templates are actually structured properly. This makes everything a runtime validation check.

The other problem is that we are introducing another language to understand, and in many normal use cases, figure out the interop between the host and the templating language for custom formatting or serialization of data.

The question is then: is there some tradeoffs that we can make to get the majority of the benefits from both sides? That is, more type safety and language similarity without the horrendous code that we typically write when authoring our templates in code?

Yes, but you need a language that is “powerful” enough to be able to create mini-DSLs.

Instead of writing the #loop from above, we could do something like:

repros.map { name in
  b |> name
}

Now we can leverage many of the benefits of using our compiled language while still getting the the vast majority of the benefits from our template system. The really awesome thing is that extensibility is already built in. If you need to format the name in a specific way, you just need to call your function. Depending on the template system you are using, this could actually be a fairly difficult and time consuming thing to get done.

So, why don’t I use external template? I find them redundant and don’t add much to solving the problem.

Why No External Templates?