Starter template (RECOMMENDED):
npm i wolt; npx wolt
or just wolt package
npm i wolt
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(7500);
Template:
// index.jsx
<h1>Hello, {name}</h1>
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>
It is recommended to use jsx files, but it is not necessary, you can use any files, the script only processes plain text.
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>)
<p>
$(link_about)
</p>
The HTML needs to be wrapped in (...) to convert to string only. $(...) function that adds to the HTML at this point.
You can 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"}
You can transpose tags this way, it won't be an error:
<p>
hello
</p>
But to do something like this, you have to wrap the text in backticks:
<p>
`after`
<span>hello</span>
`before`
</p>
Backticks do add content to this location, for example this is how you can add a doctype that gives an error in a JSX file:
`<!DOCTYPE html>`
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/>
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'
Now the slot can be multi-line
<inc href="file.jsx">
multi line
text
</inc>
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>
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}`}>
wolt includes some handy helpers you can use in templates:
Accumulates final HTML output:
$html += (<div>)
$html += 'Hello'
$html += (</div>)
Alias for $html to append to HTML output:
$(<div>)
$(Hello)
$(</div>)
Makes AJAX requests:
let data = await $fetch.json('/api/users');
for(let user of data) {
<p>{user.name}</p>
}
Delays execution:
await $timeout(1000); // wait 1 second
<p>Done!</p>
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>);
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>
Server return <script> that render in browser
await render(file, data, { mode: "client" });
WoltJs is released under the MIT License.