wu

the engineless engine

wu does not exist. There's no package to download. No config file to set up. No dependencies. wu is nothing—but a few simple conventions that make it easy to replace your html templating engine with nothing but modern javascript.

wu is the perfect companion for mu the frameless framework for generating static sites. View the mu.js and wu.js files that I used to generate this site.

the basics

Each template is just a regular javascript function that returns a template literal.

layout = (page) => {
    return `
    <html>
        <head>
            <title>Welcome</title>
        </head>
        <body>
            ${page.content}
        </body>
    </html>
`
}
let page = {
    title: 'My Page',
    content: 'Lorem Ipsum'
}

let html = layout(page)

This isn't javscript inside a template; it's a native template inside javascript. Which means wu templates are more like components that can contain their own logic written in pure javascript.

layout = (page) => {
    const title = page.title || 'Welcome'

    return `
    <html>
        <head>
            <title>${title}</title>
        </head>
        <body>
            ${escapeHTML(page.content)}
        </body>
    </html>
    `
}

If you have multiple templates store them in their own wu.js module.

// wu.js

let wu = {}

wu.layout = (page) => {
    return `
<html>
    <head>
        <title>Welcome</title>
    </head>
    <body>
        ${page.content}
        ${wu.footer(page)}
    </body>
</html>
    `
}

wu.footer = (page) => {
    return ` Last updated: ${page.modified}`
}

module.exports = wu
wu = require('./wu.js')

let page = {
    title: 'My Page',
    content: 'Lorem Ipsum'
}

let html = layout(page)

Sometimes you need to pass global settings into all of your templates. If you're working in node.js and have to use require(), there's a simple trick that allows you to pass arguments into a module: just export a function that returns the contents of the module—in this case wu.

module.exports = function (settings) {

    wu = {}
    wu.layout = {...}
    wu.post = {...}
    wu.footer = {...}

    return wu
}

And then in the file that loads wu.js ...

settings = { ... }
wu = require('./wu.js')(settings)

But most of the time, I just pass additional data into my templates using a props object.

const wu = require('./wu.js')

const page = {
    title: 'My Page',
    content: 'Lorem Ipsum'
}

const props = {...}

page.content = layout(page, props)