My views folder structure
view
-->layouts
---->main.hbs
-->partials
---->header.hbs
---->footer.hbs
-->pages
---->user
------>includes
-------->list.hbs
---->index.hbs
I can import partials files like header and footer in main.hbs
but have no idea about including list.hbs into pages/user/index.hbs.
This is my handlebars configuration
const path = require('path');
const exphbs = require('express-handlebars');
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'hbs');
app.engine(
'hbs',
exphbs.engine({
extname: 'hbs',
layoutsDir: path.join(__dirname, '../views', 'layouts'),
partialsDir: path.join(__dirname, '../views', 'partials'),
defaultLayout: 'main'
}),
);
Related
I was doing a nodejs based project using express and when I was adding partials to the app.js file. I got a type error: TypeError: hbs is not a function. I installed npm express-handlebars module. then also showing error again. how to fix it.
i also add this code: 'var hbs=require('express-handlebars');'https://i.stack.imgur.com/4hMtT.png
this is my code:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.engine('hbs', hbs({extname: 'hbs', defualtLayout : 'layout' , layoutsDir: __dirname + '/views/layouts',partialsDir:__dirname+'/views/partials/'}));
Looking at the documentation, it doesn't look that you are initializing it in the right way cf.https://www.npmjs.com/package/express-handlebars
I had the same problem.
Try this:
change hbs({extname: to hbs.engine({extname:
Change this
app.engine('hbs', hbs({extname: 'hbs', defualtLayout : 'layout' , layoutsDir: __dirname + '/views/layouts',partialsDir:__dirname+'/views/partials/'}));
To this:
app.engine('hbs', hbs.engine({extname: 'hbs', defualtLayout : 'layout' , layoutsDir: __dirname + '/views/layouts',partialsDir:__dirname+'/views/partials/'}));
Have you any Idea what's wrong here? When I run a view file in a single page Its run fine but when I add external layout in this template its generate an error. What do you think what is the problem in this code?
const expressHbs = require('express-handlebars');
app.engine(
expressHbs({
extname: "hbs",
defaultLayout: "main-layouts",
layoutsDir: "views/layouts"
})
);
app.set('view engine', 'hbs');
Try this, hope your issue would be solved:
app.engine(
"hbs",
expressHbs({
extname: "hbs",
defaultLayout: "main-layouts",
layoutsDir: "views/layouts"
})
);
Handlebars template's filename extension
Hi,
my templates files got the extension .handlebars and I want to change it to .hbs
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
app.engine('handlebars', exphbs({defaultLayout: 'index'}));
app.set('view engine', 'handlebars');
when changing handlebars to hbs and renaming the files, errors appear. The files are not found anymore.
What is missing?
Try setting the following properties
const exphbs = require('express-handlebars');
const handlebars = exphbs.create({
// layoutsDir: path.join(__dirname, 'app/views/layouts'),
// partialsDir: path.join(__dirname, 'app/views/partials'),
defaultLayout: 'index',
extname: 'hbs'
});
app.engine('hbs', handlebars.engine);
app.set('view engine', '.hbs');
Change your code something like this:
`
const express = require('express');
var app = express();
const hbs = require('express-handlebars');
app.set('views', path.join(__dirname, 'views'));
app.engine('hbs', hbs({extname : 'hbs', defaultLayout: 'index', layoutsDir: __dirname+'/views/layouts'}));
app.set('view engine', 'hbs');
Change your file's extentions from
.hanlebars
to
.hbs and put your index.hbs file inside path/to/project/views/layouts and rest of the .hbs file should remain in path/to/project/views/.
I have the following Express 4 view engine setup:
var handlebars = require('express-handlebars').create({
layoutsDir: path.join(__dirname, "views/layouts"),
partialsDir: path.join(__dirname, "views/partials"),
defaultLayout: 'layout',
extname: 'hbs'
});
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, "views"));
I have the following file structure:
/views
error.hbs
index.hbs
/partials
menu.hbs
/layouts
layout.hbs
And finally in my route: res.render('index');
And visiting my site, it loads only my index.hbs template. It does not use my layout.hbs. I don't get any errors or anything. It just doesn't use the layout even though layout is set as my default layout in the handlebars config.
Next I tried to change my code to this:
res.render('index', {layout: 'layout'});
Now I get the error:
Error: ENOENT: no such file or directory, open '/.../views/layout.hbs'
So it's like it's not finding my layoutsDir... What am I missing here?
Next I changed it to this:
res.render('index', {layout: 'layouts/layout'});
Okay so that worked. My layout is now loaded. But then I added in a partial to my layout:
{{> menu }}
Now I get: /.../views/index.hbs: The partial menu could not be found
So what is going on here? How come Handlebars isn't recognizing my layoutsDir or partialsDir? It's just not seeing them at all or something. And how come defaultLayout wasn't being used? I had to specify the layout.
According to the API documentation for express-handlebars if you are changing the file extension from the default .handlebars then when you set the view engine, all occurrences of handlebars should be replaced with the new extension you wish to use.
So your express setup will need to be updated to:
app.engine('hbs', handlebars.engine);
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, "views"));
Note: the documentation uses a period before the extension e.g. .hbs but it seems to work without this.
Full code:
var path = require('path');
var express = require('express');
var app = express();
var http = require('http').Server(app);
var handlebars = require('express-handlebars').create({
layoutsDir: path.join(__dirname, "views/layouts"),
partialsDir: path.join(__dirname, "views/partials"),
defaultLayout: 'layout',
extname: 'hbs'
});
app.engine('hbs', handlebars.engine);
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, "views"));
app.get('/', function(req, res){
res.render('index');
});
http.listen(3000, function(){
console.log("Server running");
});
In the new handlebars in your use partials you dont have to include its directory in server.js
The partials are included in "express-handlebars"
The first line in view engine setup is responsible for the above
Take note of these.
const hbs = require('hbs');
const expressHbs = require('express-handlebars');
//view engine setup
app.engine('.hbs', expressHbs({ defaultLayout: 'layout', extname: '.hbs' }));
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, '../views'));
app.use(express.static(path.join(__dirname, '../public')));
Try to use wildcard on your Dependencies to make sure you match the latest version
"dependencies": {
"express": "*",
"express-handlebars": "^3.0.0",
"hbs": "*"
},
I am new to node.js and I'd like to use handlebars template engine but with a shorten extension hbs.
Here is the original code (source):
var handlebars = require('express3-handlebars')
.create({ defaultLayout: 'main' });
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
It worked fine with templates with handlebars extension, but I changed it to:
var handlebars = require('express3-handlebars')
.create({ defaultLayout: 'main' });
app.engine('hbs', handlebars.engine);
app.set('view engine', 'hbs');
And change all the template extentions to hbs.
However, now I get this error:
Error: ENOENT: no such file or directory, open '/path/to/node/myproject/views/layouts/main.handlebars'
at Error (native)
I also tried
var handlebars = require('express3-handlebars')
.create({ defaultLayout: 'main' , extname : '.hbs'});
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
as per answer here,
but I results in:
Error: Failed to lookup view "500" in views directory "/path/to/myproject/views"
at EventEmitter.render (/path/to/myproject/node_modules/express/lib/application.js:579:17)
at ServerResponse.render (/path/to/myproject/node_modules/express/lib/response.js:961:7)
at /path/to/myproject/app.js:96:6
at Layer.handle_error (/path/to/myproject/node_modules/express/lib/router/layer.js:71:5)
at trim_prefix (/path/to/myproject/node_modules/express/lib/router/index.js:310:13)
at /path/to/myproject/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/path/to/myproject/node_modules/express/lib/router/index.js:330:12)
at next (/path/to/myproject/node_modules/express/lib/router/index.js:271:10)
at Layer.handle_error (/path/to/myproject/node_modules/express/lib/router/layer.js:67:12)
at trim_prefix (/path/to/myproject/node_modules/express/lib/router/index.js:310:13)
I tried other things too but none worked so wondering how can I fix this?
This did the trick:
exphbs = require('express3-handlebars'),
app.engine('hbs', exphbs({defaultLayout: 'main', extname: '.hbs'}));
app.set('view engine', 'hbs');
You can use express-hbs instead of express3-handlebars.
Simply, you can do:
var hbs = require('express-hbs');
/*
...
*/
app.engine('hbs', hbs.express4({
partialsDir : __dirname +'/views/partials',
defaultLayout : __dirname +'/views/layouts/default',
extname : '.hbs',
layoutsDir : __dirname +'/views/layouts',
}));
app.set('view engine', 'hbs');
app.set('views', __dirname + '/views');
'express3-handlebars' package is deprecated now(2020). So you can try this out
const handlebarOptions = {
viewEngine: {
extName: '.hbs',
partialsDir: 'views',//your path, views is a folder inside the source folder
layoutsDir: 'views',
defaultLayout: ''//set this one empty and provide your template below,
},
viewPath: 'views',
extName: '.hbs',
};
mailTransport.use('compile', hbs(handlebarOptions));
const mailOptions = {
from: '"Spammy Corp." <ad.timely#gmail.com>',
to: 'nipunkavishka#gmail.com',
template: 'index',//this is the template of your hbs file
};
There is nothing wrong with your code, you just need to create a folder within the views folder and name it to layouts, and then move your defaultLayout = main.hbs to it .
If you've got :
Error : The partial header could no be found .
Go create another file within the views folder again and name it to partials and then put all your partials there __Like the header file and so on ... .