Skip to content

Commit dd68e6f

Browse files
authored
Merge pull request #1 from fastify/first-implementation
First implementation
2 parents 9cc4348 + 3467047 commit dd68e6f

File tree

8 files changed

+420
-1
lines changed

8 files changed

+420
-1
lines changed

README.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,59 @@
11
# point-of-view
2-
Template plugin for Fastify
2+
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
3+
[![Build Status](https://travis-ci.org/fastify/point-of-view.svg?branch=master)](https://travis-ci.org/fastify/point-of-view)
4+
5+
Templates rendering plugin support for Fastify.
6+
7+
`point-of-view` decorates the reply interface with the `view` method for manage view engines that can be used to render templates responses.
8+
9+
Currently supports the following templates engines:
10+
- [`ejs`](http://www.embeddedjs.com/)
11+
- [`pug`](https://pugjs.org/api/getting-started.html)
12+
- [`handlebars`](http://handlebarsjs.com/)
13+
14+
In `production` mode, `point-of-view` will heavily cache the templates file and functions, while in `development` will reload every time the template file and function.
15+
## Install
16+
17+
```
18+
npm install point-of-view --save
19+
```
20+
<a name="usage"></a>
21+
## Usage
22+
```js
23+
const fastify = require('fastify')()
24+
25+
fastify.register(require('point-of-view'), {
26+
engine: {
27+
ejs: require('ejs')
28+
}
29+
})
30+
31+
fastify.get('/', (req, reply) => {
32+
reply.view('/templates/index.ejs', { text: 'text' })
33+
})
34+
35+
fastify.listen(3000, err => {
36+
if (err) throw err
37+
console.log(`server listening on ${fastify.server.address().port}`)
38+
})
39+
```
40+
41+
If you want to set a fixed templates folder, or pass some options to the template engines:
42+
```js
43+
fastify.register(require('point-of-view'), {
44+
engine: {
45+
ejs: require('ejs')
46+
},
47+
templates: '/templates',
48+
options: {}
49+
})
50+
```
51+
## Acknowledgements
52+
53+
This project is kindly sponsored by:
54+
- [nearForm](http://nearform.com)
55+
- [LetzDoIt](http://www.letzdoitapp.com/)
56+
57+
## License
58+
59+
Licensed under [MIT](./LICENSE).

example.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict'
2+
3+
const fastify = require('fastify')()
4+
5+
fastify.register(require('./index'), {
6+
engine: {
7+
ejs: require('ejs')
8+
}
9+
})
10+
11+
fastify.get('/', (req, reply) => {
12+
reply.view('/templates/index.ejs', { text: 'text' })
13+
})
14+
15+
fastify.listen(3000, err => {
16+
if (err) throw err
17+
console.log(`server listening on ${fastify.server.address().port}`)
18+
})

index.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict'
2+
3+
const fp = require('fastify-plugin')
4+
const fs = require('fs')
5+
const path = require('path')
6+
const HLRU = require('hashlru')
7+
const supportedEngines = ['ejs', 'pug', 'handlebars']
8+
9+
function fastifyView (fastify, opts, next) {
10+
fastify.decorateReply('view', view)
11+
12+
if (!opts.engine) {
13+
next(new Error('Missing engine'))
14+
return
15+
}
16+
17+
const type = Object.keys(opts.engine)[0]
18+
if (supportedEngines.indexOf(type) === -1) {
19+
next(new Error(`'${type}' not yet supported, PR? :)`))
20+
return
21+
}
22+
23+
const engine = opts.engine[type]
24+
const options = opts.options || {}
25+
const templatesDir = path.join(process.cwd(), opts.templates || './')
26+
const lru = HLRU(opts.maxCache || 100)
27+
const prod = process.env.NODE_ENV === 'production'
28+
29+
function view (page, data) {
30+
if (!page || !data) {
31+
this.send(new Error('Missing data'))
32+
return
33+
}
34+
35+
const toHtml = lru.get(page)
36+
37+
if (toHtml && prod) {
38+
this.header('Content-Type', 'text/html').send(toHtml(data))
39+
return
40+
}
41+
42+
fs.readFile(path.join(templatesDir, page), 'utf8', readCallback(this, page, data))
43+
}
44+
45+
function readCallback (that, page, data) {
46+
return function _readCallback (err, html) {
47+
if (err) {
48+
that.send(err)
49+
return
50+
}
51+
52+
lru.set(page, engine.compile(html, options))
53+
that.header('Content-Type', 'text/html').send(lru.get(page)(data))
54+
}
55+
}
56+
57+
next()
58+
}
59+
60+
module.exports = fp(fastifyView, '>=0.13.1')

package.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "point-of-view",
3+
"version": "0.1.0",
4+
"description": "Template plugin for Fastify",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "standard && tap test.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/fastify/point-of-view.git"
12+
},
13+
"keywords": [
14+
"fastify",
15+
"template",
16+
"view",
17+
"speed",
18+
"ejs",
19+
"pug",
20+
"handlebars"
21+
],
22+
"author": "Tomas Della Vedova - @delvedor (http://delved.org)",
23+
"license": "MIT",
24+
"bugs": {
25+
"url": "https://github.com/fastify/point-of-view/issues"
26+
},
27+
"homepage": "https://github.com/fastify/point-of-view#readme",
28+
"dependencies": {
29+
"fastify-plugin": "^0.1.0",
30+
"hashlru": "^2.1.0"
31+
},
32+
"devDependencies": {
33+
"ejs": "^2.5.6",
34+
"fastify": "^0.13.1",
35+
"handlebars": "^4.0.6",
36+
"pre-commit": "^1.2.2",
37+
"pug": "^2.0.0-beta11",
38+
"request": "^2.81.0",
39+
"standard": "^9.0.2",
40+
"tap": "^10.3.0"
41+
}
42+
}

templates/index.ejs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head></head>
4+
<body>
5+
<p><%= text %></p>
6+
</body>
7+
</html>

templates/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head></head>
4+
<body>
5+
<p>{{ text }}</p>
6+
</body>
7+
</html>

templates/index.pug

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
doctype html
2+
html
3+
head
4+
body
5+
p #{text}

0 commit comments

Comments
 (0)