wolt
v1.2.7
Published
minimalist template engine for Node.js
Downloads
21
Maintainers
Readme
WOLT - minimalist template engine for Node.js.
It allows you to write HTML code directly inside JavaScript (like jsx).
Installation
Starter template (RECOMMENDED):
npm i wolt; npx wolt
or just wolt package
npm i wolt
Example
using with express.js:
// app.js
const { render } = require("wolt");
const app = require("express")();
app.get("/", async (req, res)=>{
const html = await render("index.jsx", {name: "John"})
res.send(html)
})
app.listen(8080);
Template:
// index.jsx
<h1>Hello, {name}</h1>
Usage
At the heart of wolt
is a very simple compiler, in short, it converts HTML tags into template string:
`<h1>Hello, ${name}</h1>`
You can use `{...}' anywhere in the tags, for example, to make dynamic tag names:
<{tag}>Hello, {name}</{tag}>
Inside {...}
you can put any JS expression:
<p>lorem { foo(5, 6) * 2 } ipsum</p>
JSX
It is recommended to use jsx files, but it is not necessary, you can use any files, the script only processes plain text.
Syntax:
Conditions:
if (user) {
<h2>My name is {user.name}</h2>
}
Iteration:
for (const i of arr) {
<p>item is {i}</p>
}
Function:
function foo(cnt) {
<p>{cnt}</p>
}
foo("hello world")
That is, you can use any JS, everything will work:
let link_about = (<a href="/about">about</a>) // html needs to be wrapped in (...) to convert to string only
<p>
$(link_about) // $(...) will replace and add to the main html
</p>
Update!
You can now pass data to the script with '% data %'
, only single or double quotes can be used before and after the % signs.
<script>
alert("'% some_data %'") // `alert("${ some_data }")`
</script>
In JSX files syntax is not highlighted inside the script tag, to avoid this you can use special tags.
{"script"}
alert("'% some_data %'") // `alert("${ some_data }")`
{"/script"}
Multiline text
You cannot simply move the tag content to a new line because the script processes the code line by line:
<p>
hello
</p>
// hello is not defined
To make multiline content, wrap your content in backticks:
<p>
`Hello, my name is {user.name}.
I live in {user.city}.`
</p>
Components
You can use the special <inc>
tag to insert code from another file.
<inc href="product.jsx"/>
If it is a jsx
file and it is located in the same folder, then you can use the short version, just the file name with a capital letter (the file itself should be lowercase, like product.jsx
).
<Product/>
Slot
You can transfer content to another file.
<inc href="text.jsx">some content</inc>
or
<Text>some content</Text>
// text.jsx
<h1>{$slot}</h1> // $slot will be replaced to 'some content'
Update!
Now the slot can be multi-line
<inc href="file.jsx">
multi line
text
</inc>
Props
You can also pass some parameters to another file.
<inc href="user.jsx" name="{user.name}" age="{user.age}"/>
or
<User name={user.name} age={user.age}/>
// or use shorthand
<User {...user}/>
// user.jsx
<h1>My name name is {$prop.name}, I'm {$prop.age} y.o.</h1>
Update!
There are 2 types of writing props:
Is converted to<inc user_id="user_{id}">
`user_${id}`
, which always returns the string
When using this type, you can transfer data of any type<inc user_id={`user_${id}`}>
Helpers
wolt includes some handy helpers you can use in templates:
$html
Accumulates final HTML output:
$html += (<div>)
$html += 'Hello'
$html += (</div>)
$
Alias for $html to append to HTML output:
$(<div>)
$(Hello)
$(</div>)
$fetch
Makes AJAX requests:
let data = await $fetch.json('/api/users');
for(let user of data) {
<p>{user.name}</p>
}
$timeout
Delays execution:
await $timeout(1000); // wait 1 second
<p>Done!</p>
Update!
Usually, to split a tag into several lines, back quotes are used
<p>
`multi-line`
</p>
But now you can use the $(...) helper
$(<div>
text
<a href="#{product.hash}">
link
</a>
<span>{some_variable}</span>
foo baz
</div>)
You can also use components inside this helper, the component must be wrapped in {...}
$(<div>
{<inc href="file.jsx" />}
or
{<File />}
</div>);
Using router
Wolt has a router based on expressjs.
To use it, first install expressjs npm i express
.
You also need to have a special structure.
pages
├─ index.jsx
├─ about.jsx
└─ user.jsx
index.html
app.js
There must be 1 index.html
file, it is a wrapper for pages (pages/*
), it contains an inc tag with a special key $page
, it will be replaced with the desired page.
<html>
<head></head>
<body>
<inc href="pages/$page"/>
</body>
</html
Add the following code to app.js
:
const { router } = require('wolt');
const app = require('express')();
router(app, {
"/": function(req, res) {
return { page: "index.jsx" }
},
"/about": function(req, res) {
return { page: "about.jsx", data: { cnt: "about page" } }
},
"/user/:id": function(req, res) {
return { page: "user.jsx" }
}
})
app.listen(8080)
Instead of function(req, res) {...}
you can use string "index.jsx"
, this entry is recommended if your script does not provide any parameters other than page: "..."
router(app, {
"/": "index.jsx",
"/about": "about.jsx",
"/user/:id": "user.jsx"
})
When using a router, you have access to additional helpers:
- $page - the page you passed in the object, for example:
"about.jsx"
- $path - the current url path, for example:
"user/10"
- $slug - dynamic parameters from the url, for example:
{ id: 10 }
So you can write some such template in user.jsx
:
let user = await $fetch.json('/api/user/' + $slug.id);
<p>{user.name}</p>
Client rendering
Server return that render in browser
await render(file, data, { mode: "client" });
License
WoltJs is released under the MIT License.