express-handlebars
express-handlebars copied to clipboard
Handlebars 4.6.0+ breaks some functionality within Express-Handlebars; any way to run runtime options?
There are new access restrictions on Objects within Handlebars since 4.6 which was released in early January 2020. The only way to ignore these new restrictions is to include runtime options to ignore them, which express-handlebars doesn't support. Is there any plan to update so that exphbs allows for runtime options?
https://github.com/wycats/handlebars.js/pull/1633 https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access
Baring that, does anyone know of a method to force exphbs to use a specific version of Handlebars (namely 4.5.3, which is the most recent revision before these new restrictions went into effect.)
Second this, adding runtime options throws. I've been trying to use npm shrimkwrap
but I can't fully understand how to force handlebars' version after.
This is an issue, for all that are or will using (express-)handlebars in the newest versions.
As for my self I upgraded my kubuntu to 19.10 and with mongodb 3.6 I have had to update my npm resources because of mongoose. So with the updated express-handlebars and everything I now have the trouble of my software, based on express-handlebars, is not working anymore.
This fix referenced here is a temporary workaround. This fix was created as a fix to express-handlebars by the creators of handlebars.
https://www.npmjs.com/package/@handlebars/allow-prototype-access#usage--express-handlebars-and-mongoose-
https://github.com/wycats/handlebars.js/issues/1648
interesting approach
its a good way to revert the breaking changes, that way its update-save.
But I would really like to see an implementation of runtime options into express-handlebars so we can have the security buff the changes of handlebars brings.
ok, here is an other approach:
we can use the _renderTemplate hook quiet easily.
var expressHbs = require('express-handlebars');
var hbs = expressHbs.create({
defaultLayout: 'main',
layoutsDir: path.join(__dirname, 'views/layouts'),
extname: 'hbs',
partialsDir: [
path.join(__dirname, 'public/templates'),
path.join(__dirname, 'views/partials')
]
});
hbs._renderTemplate = function (template, context, options) {
options.allowProtoMethodsByDefault = true;
options.allowProtoPropertiesByDefault = true;
return template(context, options);
};
worked for me or did I missed something?
ok, here is an other approach:
we can use the _renderTemplate hook quiet easily.
var expressHbs = require('express-handlebars'); var hbs = expressHbs.create({ defaultLayout: 'main', layoutsDir: path.join(__dirname, 'views/layouts'), extname: 'hbs', partialsDir: [ path.join(__dirname, 'public/templates'), path.join(__dirname, 'views/partials') ] }); hbs._renderTemplate = function (template, context, options) { options.allowProtoMethodsByDefault = true; options.allowProtoPropertiesByDefault = true; return template(context, options); };
worked for me or did I missed something?
how to implement this on express?? just i missunderstand this
i have this code:
const express = require("express");
const path = require("path");
const hbs = require("express-handlebars");
const app = express();
app.engine('.hbs',hbs({
defaultLayout: 'main',
layoutsDir: path.join(app.get('views'), 'layouts'),
partialsDir: path.join(app.get('views'), 'partials'),
extname: '.hbs'
}));
app.set('view engine', '.hbs')
`
``
and my route:
const router = require("express").Router();
const anObject = {
foo: 'bar',
bar: 'foo'
}
router.get('/', (req, res) => {
res.render('index', {
anObject,
helpers: ifeqHelper
});
});
how to implement this on express?? just i missunderstand this
i have this code:
const express = require("express"); const path = require("path"); const hbs = require("express-handlebars"); const app = express(); app.engine('.hbs',hbs({ defaultLayout: 'main', layoutsDir: path.join(app.get('views'), 'layouts'), partialsDir: path.join(app.get('views'), 'partials'), extname: '.hbs' })); app.set('view engine', '.hbs') ` `` and my route: const router = require("express").Router(); const anObject = { foo: 'bar', bar: 'foo' } router.get('/', (req, res) => { res.render('index', { anObject, helpers: ifeqHelper }); });
Try the following:
const express = require("express");
const path = require("path");
const expressHandlebars = require("express-handlebars");
const app = express();
var hbs = expressHandlebars.create({
defaultLayout: 'main',
layoutsDir: path.join(app.get('views'), 'layouts'),
partialsDir: path.join(app.get('views'), 'partials'),
extname: '.hbs'
});
hbs._renderTemplate = function (template, context, options) {
options.allowProtoMethodsByDefault = true;
options.allowProtoPropertiesByDefault = true;
return template(context, options);
};
app.engine('.hbs',hbs);
app.set('view engine', '.hbs')
Should be something like that, have not tested it but you should get the gist of it.
Would also be possible to do everything within the ""app.engine('.hbs', hbs({"" block but I would have to test it.
Also, are you sure that
app.engine('.hbs'
is correct?
if there are further Problems try:
app.engine('hbs'
(without the . (dot))