@bark/koa-handlebars
v1.0.1
Published
Render hbs files in your koa apps with autoloaded helpers and partials
Downloads
3
Readme
koa-handlebars
Render HBS files in your Koa apps with autoloaded helpers and partials
Install
npm i @bark/koa-handlebars handlebars fs-jetpack
koa-handlebars is BYOFS (Bring-your-own-file-system). If you have a different fs implementation that is api-compatible with fs-jetpack, you can use that instead and provide it to the jetpack
option when creating your renderer
Usage
Koa Middleware
The primary use case for this module is to act as a Koa middleware. This means that you will need to app.use
it somewhere in your middleware stack. This will add a ctx.render
function that can be used to render templates in one
of your app's controllers.
const Koa = require('koa')
const hbs = require('@bark/koa-handlebars')
const path = require('path')
const app = new Koa()
// ... Other Middleware ...
app.use(hbs(path.join(__dirname, 'views'))) // <-- Mount the middleware
// ... More Middleware ...
router.get('web.projects.list', '/projects', async ctx => {
const currentUser = await getCurrentUser()
const projects = await getProjectsSomehow(currentUser)
await ctx.render('projects/list-projects', { // <-- Call 'ctx.render' with your template name and data
user: currentUser,
projects,
})
})
Standalone
You might sometimes need to access the fully configured renderer outside of your request/response flow (e.g. async job queue handlers). Koa-handlebars exposes a method for creating a ctx
-independent renderer with the same set of options as the middleware version.
const path = require('path')
const { cwd } = require('process')
const { createRenderer } = require('@bark/koa-handlebars')
const renderer = createRenderer(path.join(cwd(), 'views')))
const output = await renderer.render('mailers/users/password-reset', {
name: 'Schmoopy',
token: '123',
action_url: 'https://example.com/reset-password?token=123'
})
API
This module exposes two functions, both of which have the same parameters. One function creates a koa middleware that attaches a render
method to ctx
(see above usage). The other creates a Renderer
object with a render
method. Both render
methods take the same parameters
createRenderer(rootPath: string, options: RendererOptions) -> Renderer
koaHandlebars(rootPath: string, options: RendererOptions) -> Koa.Middleware
rootPath
The base path that the render method will append template names to in order to find a template file. Unless the helper and partial paths are customised, koa-handlebars will expect the folder found at this path to also contain folders named helpers
and partials
RendererOptions
An object that can be used to customise the behaviour of the koa-handlebars renderer
RendererOptions.useCache: boolean
Default: process.env.NODE_ENV === 'production'
When set to true
, the renderer will store the parsed template file in an internal cache. This does not store the result
of using a template; rather, the file is loaded from disk, parsed by Handlebars and then stored in the cache before being used. Subsequent calls to render the same template will use the cached template instead of having to hit the filesystem and re-parse the template file.
This behaviour may be undesirable if you are iterating on your templates, or if you have a large number of templates that might take up a lot of memory when cached.
RendererOptions.extension: string
Default: ".hbs"
The extension that koa-handlebars will append to the name of a template in order to find the template file. Using the default settings, a call to renderer.render('users/profile')
would render <root>/users/profile.hbs
.
RendererOptions.partials: string
Default: "partials"
The name of the folder holding your partials, relative to the root path. Using the default settings, the following handlebars expression will render the template found at <root>/partials/user-footer.hbs
<!-- Some content -->
{{> user-footer }}
<!-- Some other content -->
RendererOptions.helpers: string
Default: "helpers"
The name of the folder holding your helper functions, relative to the root path. koa-handlebars will require
every file in this folder to look for helpers. See below for more information about how to write a helper file in a way that is compatible with koa-handlebars
RenderOptions.extend: Fn(instance: Handlebars) -> Handlebars
Default: (inst) => inst
A simple hook that allows you to directly access and modify the underlying Handlebars instance. This function is called at the end of the configuration process after partials and helpers have been registered. The extend
function must return a handlebars instance (or another api-compatible object), but this does not imply that it has to be the handlebars instance passed to the extend
function.
RenderOptions.jetpack: FsJetpack
Default: require('fs-jetpack')
The filesystem instance that koa-handlebars will use for all filesystem operations. This should either be an instance of fs-jetpack
, or some other api-compatible object. If you are providing your own implementation, you do not need to install the fs-jetpack
dependency.
ctx.render(template: string, data: Object, options: HandlebarsOptions) -> Promise
renderer.render(template: string, data: Object, options: HandlebarsOptions) -> Promise
template
This is the path to the template file, relative to the root
option provided to the constructor, and without the file extension. If the template does not exist, ctx.render
will set the response status to 404
with no response body; renderer.render
will simply return null
data
This object holds data that will be made available to the Handlebars template. This is passed directly to the Handlebars instance without modification.
options
This object holds options for the underlying Handlebars instance. This is passed directly to the Handlebars instance without modification; check the Handlebars documentation for more information.
Helpers
Helpers are javascript functions that can perform some sync processing and return data to be interpolated into a template. By default, koa-handlebars will look at every file in the <root>/helpers
directory for functions to load. Helpers can be exported in one of two ways: one helper per file, or helper bundles.
If you have one helper per file, the name of the file will be registered as the name of your helper function, and your file should look something like this:
// <root>/helpers/current_year.js
const Handlebars = require('handlebars')
module.exports = function showCurrentYear() {
const date = new Date()
return new Handlebars.SafeString(String(date.getFullYear()))
}
If you have multiple helpers per file, every exported name will be registered as a helper function, where the helper function name matches the exported name. You file should look something like this:
// <root>/helpers/utilities.js
const Handlebars = require('handlebars')
exports.current_year = function showCurrentYear() {
const date = new Date()
return new Handlebars.SafeString(String(date.getFullYear()))
}
exports.ifenv = function(name, compare, options) {
if (options == null) {
options = compare
compare = null
}
const value = process.env[name.toUpperCase()]
if (value === compare) {
return options.fn(this)
} else {
return options.inverse(this)
}
}
Both of the above ways of registering helpers will allow the following code to work:
<div class="footer">
Copyright 1970 - {{# current_year }}
</div>
The second example will also allow the following to work:
{{#ifenv "node_env" "production"}}
<script type="application/javascript" src="https://example.com/cdn/my-crm-widget.js"></script>
{{else}}
<script type="application/javascript" src="https://example.com/cdn/my-debug-tools.js"></script>
{{/ifenv}}