twig-layout
twig-layout is a layout system based on twig.
Instalation
$ npm install twig-layout
Exemple:
This exemple use express and express-twig-layout
install express and express-twig-layout
$ npm install --save express
$ npm install --save express-twig-layout
index.js
Create a simple express app with two route: /home and /test
var express = require('express')
var layout = require('express-twig-layout')
var app = express()
app.set('view', './views')
app.use(layout())
app.get('/home', function (req, res) {
req.layout.loadTemplate('home.html').then(() => {
req.layout.render().then((html) => {
res.send(html)
})
})
})
app.get('/test', function (req, res) {
req.layout.loadTemplate('test.html').then(() => {
req.layout.getBlock('head').data.title = 'Test page'
req.layout.render().then((html) => {
res.send(html)
})
})
})
app.get('*', function (req, res) {
res.redirect('/home')
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
/views/page/default.html
The template for the page
For the template syntax read the twig js documentation
<template>
<!doctype html>
<html lang="en">
{{blocks.head}}
<body>
<header>
<nav>
<ul>
<li>
<a href="/home">Home</a>
</li>
<li>
<a href="/test">Test</a>
</li>
</ul>
</nav>
</header>
<main role="main">
{{blocks.content}}
</main>
<footer>
<p>footer</p>
</footer>
</body>
</html>
</template>
<script>
var Block = require('node-twig-layout/block')
class Default extends Block {
init () {
this.name = 'page'
this.addBlock({name: 'head', template: 'page/head.html'})
this.addBlock({name: 'content', script: 'container'})
}
beforeRender () {
this.layout.getBlock('head').addCss('https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css', -10)
}
}
module.exports = Default
</script>
/views/page/head.html
template for the head block define in the file views/page/default.html
<template>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>{{title}}</title>
{% for file in css %}
<link rel="stylesheet" href="{{file}}">
{% endfor %}
{% for file in js %}
<script src="{{file}}"></script>
{% endfor %}
</head>
</template>
<script>
var Block = require('node-twig-layout/block')
class Head extends Block {
init() {
this._css = []
this._js = []
this.data.css = []
this.data.js = []
}
addCss (cssFiles, weight = 0) {
if (Array.isArray(cssFiles)) {
for (var key in cssFiles) {
this._css.push({weight: weight, file: cssFiles[key]})
}
} else if (typeof cssFiles === 'string') {
this._css.push({weight: weight, file: cssFiles})
} else {
throw Error('Invalid addCss argument')
}
}
addJs (jsFiles) {
if (Array.isArray(jsFiles)) {
for (var key in jsFiles) {
this._js.push({weight: weight, file: jsFiles[key]})
}
} else if (typeof jsFiles === 'string') {
this._js.push({weight: weight, file: jsFiles})
} else {
throw Error('Invalid addJs argument')
}
}
beforeRender() {
var sort = function(a, b) {
return a.weight - b.weight
}
this._css.sort(sort);
for (const key in this._css)
this.data.css.push(this._css[key].file)
this._js.sort(sort);
for (const key in this._js)
this.data.js.push(this._js[key].file)
}
}
module.exports = Head
</script>
/views/home.html
The template for the /home route
<template>
<div>
<h1>Home page</h1>
</div>
</template>
<script>
var Block = require('node-twig-layout/block')
class Home extends Block {
init () {
this.page ='page/default.html'
this.parent = 'content'
}
beforeRender() {
this.layout.getBlock('head').data.title = 'Home page'
}
}
module.exports = Home
</script>
/views/test.html
The template for the /test route
<template>
<div class="test">
<h1>Test</h1>
</div>
</template>
<script>
var Block = require('node-twig-layout/block')
class Test extends Block {
init () {
this.page ='page/default.html'
this.parent= 'content'
}
}
module.exports = Test
</script>
Run:
$ node index.js