@bark/koa-handlebars

1.0.1 • Public • Published

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}}

Package Sidebar

Install

npm i @bark/koa-handlebars

Weekly Downloads

1

Version

1.0.1

License

Apache-2

Unpacked Size

24.8 kB

Total Files

4

Last publish

Collaborators

  • louis*bark
  • commander-lol