Starter template (RECOMMENDED):
npm i wolt; npx wolt
or just wolt package
npm i woltusing 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>
</htmlAdd 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.