Reputation: 127
I am currently trying to use handlebars where I can reference multiple themes/layouts easily. My intention is for example, when rendering a new page I can choose which layout. Each layout links to a different set of JS/CSS files. For Example: I would be able to do:
router.get('/bootstrap', function (req, res){
res.render('general', {layout: bootstrap, data: variables});
});
---or --
router.get('/semantic', function(req,res){
res.render('general', {layout: semantic, data: variables});
I thought that this could be easily achieved by simply creating (bootstrap/semantic.hbs) templates like this in my /views/layouts directory and typing
res.render('general', {layout: 'bootstrap', data: variables});
However this doesnt seem to work
// bootstrap_layout.hbs
<html>
<head>
<link ref....to bootstrap css>
<body>
{{{body}}}
<script src...to jquery>
<script src...to bootstrap js>
{{> Footer }}
</body>
<html>
My app.js file looks like this:
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
var hbs = exphbs.create({
layoutsDir: /views/layouts });
// Register `hbs.engine` with the Express app.
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
The problem is when I try to do this, I cannot seem to load the layout/template when calling it in {layout: bootstrap} or {layout: semantic}. I run into errors where the layout cannot be found, vs other ENOENT errors. I also tried changing this:
Remove: var hbs = exphbs.create({
layoutsDir: /views/layouts });
--------------------------------
Remove: hbs. engine, and replace with exphbs:
app.engine('handlebars', exphbs({layoutDir: __dirname+'/views/layouts'}));
app.set('view engine', 'handlebars');
I have had no luck in figuring out why I am running into so much difficulty calling a new layout. Does anyone have any advice on where I may be going wrong or if I am missing something essential?
Thanks!
Upvotes: 1
Views: 2558
Reputation: 9003
One suggestion I have is that the extension on your layout files is incompatible with your configuration.
You have specified that your layouts have paths like views/layouts/semantic.hbs
. However, I believe that express-handlebars expects the extension ".handlebars" by default. (You can override this in your exphbs.create
, like exphbs.create({ extname: '.hbs' })
)
In summary, please try using the ".handlebars" extension for your view files. The resultant paths would look like:
./views/general.handlebars
./views/layouts/bootstrap.handlebars
./views/layouts/semantic.handlebars
A basic example of the express code is:
const express = require("express");
const exphbs = require("express-handlebars");
const path = require("path");
const app = express();
const port = 3000;
const hbs = exphbs.create({
layoutsDir: path.join(__dirname, "/views/layouts"),
});
app.engine("handlebars", hbs.engine);
app.set("view engine", "handlebars");
const variables = {
foo: "bar",
};
app.get("/bootstrap", function (req, res) {
res.render("general", { layout: "bootstrap", data: variables });
});
app.get("/semantic", function (req, res) {
res.render("general", { layout: "semantic", data: variables });
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Upvotes: 0
Reputation: 1
If you store your [bootstrap/semantic] layouts under views/layouts, it will work. So,
app.set('view engine', 'handlebars');
app.set('views', './views');
and then
res.render('general', {layout: 'bootstrap', data: variables});
Upvotes: 0
Reputation: 1634
Using single quote in the name of layout that you choose when you call render method:
res.render('general', {layout: 'bootstrap', data: variables});
Upvotes: 0