Origin of this story is me being lazy, using JS for every practical application because it's cheap.
Naturally, JS has the best template engine for the web (almost exclusively; Golang has an analog, but it’s painful to use).
The beauty of Pug/Jade is its YAML-like indentation-based structure, which guarantees valid HTML output.
The only way to break HTML in Pug is to render raw, unescaped output - a rare necessity if you know what you’re doing.
This is what stopped me from adopting Golang’s tmpl: I never figured out how to validate templates without resorting
to an overly costly e2e test suite.
Here is the essential example of how I'm using it:
// table.js
app.get('/:table', supa_read, (req, res) => {
if (req.query.type == 'part' || req.headers['hx-request'])
return res.render('part/table')
if (req.query.type == 'json' || req.headers.accept == 'application/json')
return res.json(res.locals.rows)
res.render('table')
}) // views/table.pug
html
body
div(hx-target="this" hx-indicator="#load")
include part/table.pug // views/part/table.pug
mixin a
a(
hx-get!=attributes.href
hx-push-url="true"
)&attributes(attributes)
block
table.table
tbody
each row in rows
tr
each key in shown
td #{row[key]}
caption
nav.ms-auto
ul.pagination
each n in [...Array(pages).keys()]
li.page-item(class=(n == page ? 'active' : ''))
+a.page-link(href=`/${table}?${sp({page: n})}`)= n+1part/table.pugcontains all representation logic for the region, eliminating the need for OOB hacks- It’s rendered both from a parent template and independently for HTMX, with little difference from standard template use cases.
- Data can be rendered as JSON if requested (this solved a major headache for me when adopting HTMX - lack of API-friendly output).
mixin aextracts href while preserving everithing else, reducing template wrighting overhead to a single+character (the same can be applied to forms)
I'm really happy with this setup: it's simplicity, universality and modern UX.
If you new to the concept please check pugjs.org and html2jade.org
Please share what do you think about it?