Skip to content

Commit

Permalink
Partials support for Handlebars engine (#121)
Browse files Browse the repository at this point in the history
* Partials support for Handlebars engine

* Fix test object.entries to object.keys

* Separate tests into multiple files (#122)

* Separate tests into multiple files

* Fix npm scripts and add snapshot

* Pass J flag to tap

* Partials support for Handlebars engine

* Fix lint
  • Loading branch information
amer8 authored and mcollina committed May 27, 2019
1 parent 9f9cca7 commit 3abf840
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 13 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ To use partials in mustache you will need to pass the names and paths in the opt
}
```

To use partials in handlebars you will need to pass the names and paths in the options parameter:
```js
options: {
partials: {
header: 'header.hbs',
footer: 'footer.hbs'
}
}
```

To configure nunjunks environment after initialisation, you can pass callback function to options:
```js
options: {
Expand Down
46 changes: 33 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ function fastifyView (fastify, opts, next) {
}

let error = null
const partialsHtml = {}
Object.keys(partials).map((key, index) => {
readFile(join(templatesDir, partials[key]), 'utf-8', (err, data) => {
if (err) {
Expand All @@ -124,10 +125,11 @@ function fastifyView (fastify, opts, next) {
if (options.useHtmlMinifier && (typeof options.useHtmlMinifier.minify === 'function')) {
data = options.useHtmlMinifier.minify(data, options.htmlMinifierOptions || {})
}
partials[key] = data

partialsHtml[key] = data
if (--filesToLoad === 0) {
lru.set(`${page}-Partials`, partials)
callback(error, partials)
lru.set(`${page}-Partials`, partialsHtml)
callback(error, partialsHtml)
}
})
})
Expand Down Expand Up @@ -305,21 +307,35 @@ function fastifyView (fastify, opts, next) {
return
}

const options = Object.assign({}, opts.options)
data = Object.assign({}, defaultCtx, data)
// append view extension
page = getPage(page, 'hbs')
getTemplateString(page, (err, templateString) => {
if (err) {
this.send(err)
return
}

const toHtml = lru.get(page)
getPartials(page, options.partials || {}, (err, partialsObject) => {
if (err) {
this.send(err)
return
}

if (toHtml && prod) {
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(toHtml(data))
return
}
Object.keys(partialsObject).forEach((name) => {
engine.registerPartial(name, engine.compile(partialsObject[name]))
})

readFile(join(templatesDir, page), 'utf8', readCallback(this, page, data))
const template = engine.compile(templateString)
const html = template(data)

if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
})
})
}

function viewMustache (page, data, opts) {
Expand All @@ -343,7 +359,11 @@ function fastifyView (fastify, opts, next) {
return
}
let html = engine.render(templateString, data, partialsObject)
this.header('Content-Type', 'text/html; charset=' + charset).send(html)

if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
})
})
}
Expand Down
1 change: 1 addition & 0 deletions templates/body.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>{{ text }}</p>
7 changes: 7 additions & 0 deletions templates/index-with-partials.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
{{> body }}
</body>
</html>
35 changes: 35 additions & 0 deletions test/test-handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,38 @@ test('fastify.view with handlebars engine and callback in production mode', t =>
})
})
})

test('reply.view with handlebars engine with partials', t => {
t.plan(6)
const fastify = Fastify()
const handlebars = require('handlebars')
const data = { text: 'text' }

fastify.register(require('../index'), {
engine: {
handlebars: handlebars
},
options: {
partials: { 'body': './templates/body.hbs' }
}
})

fastify.get('/', (req, reply) => {
reply.view('./templates/index-with-partials.hbs', data)
})

fastify.listen(0, err => {
t.error(err)
sget({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port
}, (err, response, replyBody) => {
t.error(err)
t.strictEqual(response.statusCode, 200)
t.strictEqual(response.headers['content-length'], '' + replyBody.length)
t.strictEqual(response.headers['content-type'], 'text/html; charset=utf-8')
t.strictEqual(handlebars.compile(fs.readFileSync('./templates/index-with-partials.hbs', 'utf8'))(data), replyBody.toString())
fastify.close()
})
})
})

0 comments on commit 3abf840

Please sign in to comment.