ECMAScript Template is a solution to write template in JavaScript. It's based on JsonML and ES2015.
Maybe ECMAScript Template challenges traditional design of template engine, and at first glance some of the ideas may seem crazy. Give it five minutes while reading this documentation.
- Easy to learn. It is just JavaScript and some conventions.
- High-extensible.
- It is just JavaScript, and we can apply any JavaScript trick to it.
- JsonML is something like AST, and we can operate it easily.
- Mature ecosystem.
You can run the following code in CodePen.
const layout = (content) => (data) => {
return [
'html',
[
'head',
['title', 'ECMAScript Template'],
],
[
'body',
content(data),
],
];
}
function home({ name }) {
return [
'h1',
`Hello, ${name}!`,
];
}
home = layout(home);
const html = JsonML.toHTMLText(home({ name: 'Benjy' }));
console.log(html);
// Output
// <html>
// <head>
// <title>ECMAScript Template</title>
// </head>
// <body>
// <h1>Hello, Benjy!</h1>
// </body>
// </html>
Note: To simplify examples, we just use jsonml-html to convert JsonML to HTML. However, we can use any library to convert JsonML to any format.
Version: 0.1.0-beta.0
An HTML element will be represented as an array, and the first item is tag name.
['br']
// =>
<br />
If the second item in array is an object, it will be treated as attributes.
['a', { class: 'link', href: 'google.com' }, 'Google']
// =>
<a class='link' href='google.com'>Google</a>
// Attribute is not required
['h1', 'Hello world!']
// =>
<h1>Hello world!</h1>
The rest items in array will be treated as children.
['ul',
['li', 'First.'],
['li', 'Second.'],
['li', 'Third.'],
]
// =>
<ul>
<li>First.</li>
<li>Second.</li>
<li>Third.</li>
</ul>
const hour = 9;
['p',
hour < 12 ? 'Good morning! ' : 'Good afternoon! ',
'My friends',
]
// =>
<p>Good morning! My friends</p>
const child = 'boy';
['p', `A ${child} will grow up to be a ${child === 'boy' ? 'man' : 'woman'}.`]
// =>
<p>A boy will grow up to be a man.</p>
['ul',
...['First.', 'Second.', 'Third.'].map((item) => ['li', item]),
]
// =>
<ul>
<li>First.</li>
<li>Second.</li>
<li>Third.</li>
</ul>
A template is a function which receives data and return JsonML.
function greeting({ name }) {
return [
'h1',
`Hello, ${name}!`,
];
}
greeting({ name: 'Benjy' }); // => ['h1', 'Hello, Benjy']
Includes allow you to insert the contents into template.
function todoList({ todos}) {
return [
'ul',
...todos.map((todo) => ['li', todo]),
];
}
function todoApp(data) {
return [
'section',
todoList(data),
];
}
todoApp({
todos: [
'eat',
'sleep',
'beat Doudou',
],
});
A layout is a HOF which receives blocks and return a template.
// layout.js
export default const layout = (content) => (data) => {
return [
'html',
[
'head',
['title', 'ECMAScript Template'],
],
[
'body',
content(data),
],
];
}
To extends a layout, just pass blocks(templates) to layout.
// home.js
import layout from './layout';
function home(data) {
return [
'h1',
`Hello, ${data.name}!`,
];
}
// Extends layout.
home = layout(home);
home({ name: 'Benjy' });
MIT