← Back to context

Comment by leafo

6 years ago

Hey, I'm the author of this blog post. Thanks for posting it whoever did.

I wrote this a long time ago, it's mostly targeted at Lua 5.1 but more recent versions of Lua approach function environments differently, so keep that in mind.

I've written & worked with quite a few HTML generation DSLs at this point. I put them into two groups:

1. Nested object return: the object is converted into HTML after executing the template

2. Evaluate and write to buffer: no return values, each "tag" is a function call that generates code in a background buffer (nested html typically accomplished by blocks or inline functions)

Approach 1 is what was used in this blog post. Approach 2 is what I ended up using for my web framework: https://leafo.net/lapis/reference/html_generation.html

Approach 1 is used by React. Approach 2 I first came across in a library called Erector: http://erector.github.io/erector/

I prefer approach 2. It lets you use your programming language constructs to do things conditionally, in loops, or whatever else your language provides.

I find that with approach 1 you tend to try to bend the language to convert everything into an expression that can be returned into the nested object you're building. The example I have off the top of my head is how React devs will write some pretty nasty ternary operator expressions just to write some HTML conditionally directly inside of a JSX chunk. (The alternative would be pulling things out into temporary variables, which just creates a lot of noise)

As a fun aside for how far you can take things, for my implementation of approach 2 in my web framework, I ended up writing a syntax transformer that could pre-render static HTML chunks to plain sting that can be appended to the output buffer. Essentially removing those function calls and any HTML escaping that would be necessary during evaluation time of the template.