Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
E

express-handlebars

> 编程语言
Open source

A Handlebars view engine for Express which doesn't suck.

2.3K stars0 likes0 views
WebsiteGitHub

About

A Handlebars view engine for Express which doesn't suck.

Express Handlebars ================== A [Handlebars][] view engine for [Express][] which doesn't suck. [![npm version][npm-badge]][npm] [![dependency status][dep-badge]][dep-status] **This package used to be named `express3-handlebars`. The previous `express-handlebars` package by @jneen can be found [here][jneen-exphbs].** [Express]: https://github.com/visionmedia/express [Handlebars]: https://github.com/wycats/handlebars.js [npm]: https://www.npmjs.org/package/express-handlebars [npm-badge]: https://img.shields.io/npm/v/express-handlebars.svg?style=flat-square [dep-status]: https://david-dm.org/ericf/express-handlebars [dep-badge]: https://img.shields.io/david/ericf/express-handlebars.svg?style=flat-square [jneen-exphbs]: https://github.com/jneen/express-handlebars ## Goals & Design I created this project out of frustration with the existing Handlebars view engines for Express. As of version 3.x, Express got out of the business of being a generic view engine — this was a great decision — leaving developers to implement the concepts of layouts, partials, and doing file I/O for their template engines of choice. ### Goals and Features After building a half-dozen Express apps, I developed requirements and opinions about what a Handlebars view engine should provide and how it should be implemented. The following is that list: * Add back the concept of "layout", which was removed in Express 3.x. * Add back the concept of "partials" via Handlebars' partials mechanism. * Support a directory of partials; e.g., `{{> foo/bar}}` which exists on the file system at `views/partials/foo/bar.handlebars`, by default. * Smart file system I/O and template caching. When in development, templates are always loaded from disk. In production, raw files and compiled templates are cached, including partials. * All async and non-blocking. File system I/O is slow and servers should not be blocked from handling requests while reading from disk. I/O queuing is used to avoid doing unnecessary work. * Ability to easily precompile templates and partials for use on the client, enabling template sharing and reuse. * Ability to use a different Handlebars module/implementation other than the Handlebars npm package. ### Package Design This package was designed to work great for both the simple and complex use cases. I _intentionally_ made sure the full implementation is exposed and is easily overridable. The package exports a function which can be invoked with no arguments or with a `config` object and it will return a function (closed over sensible defaults) which can be registered with an Express app. It's an engine factory function. This exported engine factory has two properties which expose the underlying implementation: * `ExpressHandlebars()`: The constructor function which holds the internal implementation on its `prototype`. This produces instance objects which store their configuration, `compiled` and `precompiled` templates, and expose an `engine()` function which can be registered with an Express app. * `create()`: A convenience factory function for creating `ExpressHandlebars` instances. An instance-based approach is used so that multiple `ExpressHandlebars` instances can be created with their own configuration, templates, partials, and helpers. ## Installation Install using npm: ```shell $ npm install express-handlebars ``` ## Usage This view engine uses sensible defaults that leverage the "Express-way" of structuring an app's views. This makes it trivial to use in basic apps: ### Basic Usage **Directory Structure:** ``` . ├── app.js └── views ├── home.handlebars └── layouts └── main.handlebars 2 directories, 3 files ``` **app.js:** Creates a super simple Express app which shows the basic way to register a Handlebars view engine using this package. ```javascript var express = require('express'); var exphbs = require('express-handlebars'); var app = express(); app.engine('handlebars', exphbs()); app.set('view engine', 'handlebars'); app.get('/', function (req, res) { res.render('home'); }); app.listen(3000); ``` **views/layouts/main.handlebars:** The main layout is the HTML page wrapper which can be reused for the different views of the app. `{{{body}}}` is used as a placeholder for where the main content should be rendered. ```handlebars Example App {{{body}}} ``` **views/home.handlebars:** The content for the app's home view which will be rendered into the layout's `{{{body}}}`. ```handlebars

Example App: Home

``` #### Running the Example The above example is bundled in this package's [examples directory][], where it can be run by: ```shell $ cd examples/basic/ $ npm install $ npm start ``` ### Using Instances Another way to use this view engine is to create an instance(s) of `ExpressHandlebars`, allowing access to the full API: ```javascript var express = require('express'); var exphbs = require('express-handlebars'); var app = express(); var hbs = exphbs.create({ /* config */ }); // Register `hbs.engine` with the Express app. app.engine('handlebars', hbs.engine); app.set('view engine', 'handlebars'); // ...still have a reference to `hbs`, on which methods like `loadPartials()` // can be called. ``` **Note:** The [Advanced Usage][] example demonstrates how `ExpressHandlebars` instances can be leveraged. ### Template Caching This view engine uses a smart template caching strategy. In development, templates will always be loaded from disk, i.e., no caching. In production, raw files and compiled Handlebars templates are aggressively cached. The easiest way to control template/view caching is through Express' [view cache setting][]: ```javascript app.enable('view cache'); ``` Express enables this setting by default when in production mode, i.e.: ``` process.env.NODE_ENV === "production" ``` **Note:** All of the public API methods accept `options.cache`, which gives control over caching when calling these methods directly. ### Layouts A layout is simply a Handlebars template with a `{{{body}}}` placeholder. Usually it will be an HTML page wrapper into which views will be rendered. This view engine adds back the concept of "layout", which was removed in Express 3.x. It can be configured with a path to the layouts directory, by default it's set to relative to `express settings.view` + `layouts/` There are two ways to set a default layout: configuring the view engine's `defaultLayout` property, or setting [Express locals][] `app.locals.layout`. The layout into which a view should be rendered can be overridden per-request by assigning a different value to the `layout` request local. The following will render the "home" view with no layout: ```javascript app.get('/', function (req, res, next) { res.render('home', {layout: false}); }); ``` ### Helpers Helper functions, or "helpers" are functions that can be [registered with Handlebars][] and can be called within a template. Helpers can be used for transforming output, iterating over data, etc. To keep with the spirit of *logic-less* templates, helpers are the place where logic should be defined. Handlebars ships with some [built-in helpers][], such as: `with`, `if`, `each`, etc. Most application will need to extend this set of helpers to include app-specific logic and transformations. Beyond defining global helpers on `Handlebars`, this view engine supports `ExpressHandlebars` instance-level helpers via the `helpers` configuration property, and render-level helpers via `options.helpers` when calling the `render()` and `renderView()` methods. The following example shows helpers being specified at each level: **app.js:** Creates a super simple Express app which shows the basic way to register `ExpressHandlebars` instance-level helpers, and override one at the render-level. ``` … ``` **views/home.handlebars:** The app's home view which uses helper functions to help render the contents. ```handlebars Example App - Home {{#if showTitle}}

Home

{{/if}}

{{foo}}

{{bar}}

``` #### More on Helpers Refer to the [Handlebars website][] for more information on defining helpers: * [Expression Helpers][] * [Block Helpers][] ### Metadata Handlebars has a data channel feature that propagates data through all scopes, including helpers and partials. Values in the data channel can be accessed via the `{{@variable}}` syntax. Express Handlebars provides metadata about a template it renders on a `{{@exphbs}}` object allowing access to things like the view name passed to `res.render()` via `{{@exphbs.view}}`. The following is the list of metadata that's accessible on the `{{@exphbs}}` data object: * `cache`: Boolean whether or not the template is cached. * `view`: String name of the view passed to `res.render()`. * `layout`: String name of the layout view. * `data`: Original data object passed when rendering the template. * `helpers`: Collection of helpers used when rendering the template. * `partials`: Collection of partials used when rendering the template. [examples directory]: https://github.com/ericf/express-handlebars/tree/master/examples [view cache setting]: http://expressjs.com/api.html#app-settings [Express locals]: http://expressjs.com/api.html#app.locals [registered with Handlebars]: https://github.com/wycats/handlebars.js/#registering-helpers [built-in helpers]: http://handlebarsjs.com/#builtins [Handlebars website]: http://handlebarsjs.com/ [Expression Helpers]: http://handlebarsjs.com/expressions.html#helpers [Block Helpers]: http://handlebarsjs.com/block_helpers.html ## API ### Configuration and Defaults There are two main ways to use this package: via its engine factory function, or creating `ExpressHandlebars` instances; both use the same configuration properties and defaults. ```javascript var exphbs = require('express-handlebars'); // Using the engine factory: exphbs({ /* config */ }); // Create an instance: exphbs.create({ /* config */ }); ``` The following is the list of configuration properties and their default values (if any): #### `handlebars=require('handlebars')` The Handlebars module/implementation. This allows for the `ExpressHandlebars` instance to use a different Handlebars module/implementation than that provided by the Handlebars npm package. #### `extname=".handlebars"` The string name of the file extension used by the templates. This value should correspond with the `extname` under which this view engine is registered with Express when calling `app.engine()`. The following example sets up an Express app to use `.hbs` as the file extension for views: ```javascript var express = require('express'); var exphbs = require('express-handlebars'); var app = express(); app.engine('.hbs', exphbs({extname: '.hbs'})); app.set('view engine', '.hbs'); ``` **Note:** Setting the app's `"view engine"` setting will make that value the default file extension used for looking up views. #### `layoutsDir` Default layouts directory is relative to `express settings.view` + `layouts/` The string path to the directory where the layout templates reside. **Note:** If you configure Express to look for views in a custom location (e.g., `app.set('views', 'some/path/')`), and if your `partialsDir` is not relative to `express settings.view` + `layouts/`, you will need to reflect that by passing an updated path as the `layoutsDir` property in your configuration. #### `partialsDir` Default partials directory is relative to `express settings.view` + `partials/` The string path to the directory where the partials templates reside or object with the following properties: * `dir`: The string path to the directory where the partials templates reside. * `namespace`: Optional

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言