express-hbs 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test.yml +1 -1
- package/README.md +3 -2
- package/example/app-layoutsDir.js +2 -1
- package/example/app.js +2 -1
- package/lib/hbs.js +9 -0
- package/lib/resolver.js +9 -4
- package/package.json +2 -3
- package/test/apps/async/index.js +2 -1
- package/test/apps/i18n/index.js +2 -1
- package/test/customExtension.js +2 -1
- package/test/helperSpecs.js +4 -2
- package/test/issues.js +48 -20
- package/test/layoutSpecs.js +18 -0
- package/test/localTemplateOptions.js +12 -4
- package/test/multiple.js +3 -1
- package/test/nonExpress.js +4 -2
- package/test/optionsSpecs.js +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,7 @@ hbs.express4({
|
|
|
43
43
|
partialsDir: "{String/Array} [Required] Path to partials templates, one or several directories",
|
|
44
44
|
|
|
45
45
|
// OPTIONAL settings
|
|
46
|
+
restrictLayoutsTo: "{String} Absolute path to a directory to restrict layout directive reading from",
|
|
46
47
|
blockHelperName: "{String} Override 'block' helper name.",
|
|
47
48
|
contentHelperName: "{String} Override 'contentFor' helper name.",
|
|
48
49
|
defaultLayout: "{String} Absolute path to default layout template",
|
|
@@ -99,9 +100,9 @@ There are three ways to use a layout, listed in precedence order
|
|
|
99
100
|
|
|
100
101
|
2. As an option to render
|
|
101
102
|
|
|
102
|
-
## ⚠️ This creates a potential security vulnerability
|
|
103
|
+
## ⚠️ This creates a potential security vulnerability if used without a `restrictLayoutsTo`:
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
The `restrictLayoutsTo` option will restrict reading layouts to a particular directory, if you do not pass this option then do not use the `layout` option in conjunction with passing user submitted data to res.render e.g. `res.render('index', req.query)`. This allows users to read arbitrary files from your filesystem!
|
|
105
106
|
|
|
106
107
|
```js
|
|
107
108
|
res.render('veggies', {
|
|
@@ -19,7 +19,8 @@ app.use(express.static(relative('public')));
|
|
|
19
19
|
app.engine('hbs', hbs.express4({
|
|
20
20
|
partialsDir: [relative('views/partials'), relative('views/partials-other')],
|
|
21
21
|
layoutsDir: relative('views/layout'),
|
|
22
|
-
defaultLayout: relative('views/layout/default.hbs')
|
|
22
|
+
defaultLayout: relative('views/layout/default.hbs'),
|
|
23
|
+
restrictLayoutsTo: relative('views/layout')
|
|
23
24
|
}));
|
|
24
25
|
app.set('view engine', 'hbs');
|
|
25
26
|
app.set('views', relative('views'));
|
package/example/app.js
CHANGED
|
@@ -20,7 +20,8 @@ function create(hbs, env) {
|
|
|
20
20
|
// Hook in express-hbs and tell it where known directories reside
|
|
21
21
|
app.engine('hbs', hbs.express4({
|
|
22
22
|
partialsDir: [relative('views/partials'), relative('views/partials-other')],
|
|
23
|
-
defaultLayout: relative('views/layout/default.hbs')
|
|
23
|
+
defaultLayout: relative('views/layout/default.hbs'),
|
|
24
|
+
restrictLayoutsTo: viewsDir
|
|
24
25
|
}));
|
|
25
26
|
app.set('view engine', 'hbs');
|
|
26
27
|
app.set('views', viewsDir);
|
package/lib/hbs.js
CHANGED
|
@@ -99,6 +99,13 @@ ExpressHbs.prototype.declaredLayoutFile = function(str, filename) {
|
|
|
99
99
|
ExpressHbs.prototype.cacheLayout = function(layoutFile, useCache, cb) {
|
|
100
100
|
var self = this;
|
|
101
101
|
|
|
102
|
+
if (this.restrictLayoutsTo) {
|
|
103
|
+
if (!layoutFile.startsWith(this.restrictLayoutsTo)) {
|
|
104
|
+
var err = new Error('Cannot read ' + layoutFile + ' it does not reside in ' + this.restrictLayoutsTo);
|
|
105
|
+
return cb(err, null);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
102
109
|
// assume hbs extension
|
|
103
110
|
if (path.extname(layoutFile) === '') layoutFile += this._options.extname;
|
|
104
111
|
|
|
@@ -254,6 +261,8 @@ ExpressHbs.prototype.express3 = function(options) {
|
|
|
254
261
|
// Absolute path to the layouts directory
|
|
255
262
|
this.layoutsDir = this._options.layoutsDir;
|
|
256
263
|
|
|
264
|
+
this.restrictLayoutsTo = this._options.restrictLayoutsTo;
|
|
265
|
+
|
|
257
266
|
// express passes this through ___express func, gulp pass in an option
|
|
258
267
|
this.viewsDir = null;
|
|
259
268
|
this.viewsDirOpt = this._options.viewsDir;
|
package/lib/resolver.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var Promise = require('bluebird');
|
|
4
|
-
|
|
5
3
|
var generateId = require('./generate-id');
|
|
6
4
|
|
|
7
5
|
var ID_LENGTH = 8;
|
|
@@ -28,9 +26,16 @@ function resolve(cache, fn, context) {
|
|
|
28
26
|
return id;
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
// cache is an object where the keys are cache keys and values are promises. See above.
|
|
31
30
|
function done(cache, callback) {
|
|
32
|
-
Promise.
|
|
33
|
-
|
|
31
|
+
return Promise.all(Object.values(cache))
|
|
32
|
+
.then(function(values) {
|
|
33
|
+
var resolvedCache = {};
|
|
34
|
+
var keys = Object.keys(cache);
|
|
35
|
+
values.forEach(function(value, index) {
|
|
36
|
+
resolvedCache[keys[index]] = value;
|
|
37
|
+
});
|
|
38
|
+
callback(null, resolvedCache);
|
|
34
39
|
}).catch(function(error) {
|
|
35
40
|
callback(error);
|
|
36
41
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-hbs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Express handlebars template engine complete with multiple layouts, partials and blocks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"express4",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"cookie-parser": "1.4.6",
|
|
33
|
-
"eslint": "8.
|
|
33
|
+
"eslint": "8.54.0",
|
|
34
34
|
"express": "4.18.2",
|
|
35
35
|
"i18n": "0.15.1",
|
|
36
36
|
"mocha": "10.2.0",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"supertest": "6.3.3"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"bluebird": "^3.5.3",
|
|
43
42
|
"handlebars": "^4.7.7",
|
|
44
43
|
"lodash": "^4.17.21",
|
|
45
44
|
"readdirp": "^3.6.0"
|
package/test/apps/async/index.js
CHANGED
|
@@ -65,7 +65,8 @@ function create(hbs, env) {
|
|
|
65
65
|
|
|
66
66
|
// Hook in express-hbs and tell it where known directories reside
|
|
67
67
|
app.engine('hbs', hbs.express4({
|
|
68
|
-
defaultLayout: path.join(viewsDir,
|
|
68
|
+
defaultLayout: path.join(viewsDir, 'layout.hbs'),
|
|
69
|
+
restrictLayoutsTo: viewsDir
|
|
69
70
|
}));
|
|
70
71
|
app.set('view engine', 'hbs');
|
|
71
72
|
app.set('views', viewsDir);
|
package/test/apps/i18n/index.js
CHANGED
|
@@ -31,7 +31,8 @@ function create(hbs, env) {
|
|
|
31
31
|
|
|
32
32
|
// Hook in express-hbs and tell it where known directories reside
|
|
33
33
|
app.engine('hbs', hbs.express3({
|
|
34
|
-
i18n: i18n
|
|
34
|
+
i18n: i18n,
|
|
35
|
+
restrictLayoutsTo: viewsDir
|
|
35
36
|
}));
|
|
36
37
|
app.set('view engine', 'hbs');
|
|
37
38
|
app.set('views', viewsDir);
|
package/test/customExtension.js
CHANGED
|
@@ -11,7 +11,8 @@ describe('custom extension for partials view', function() {
|
|
|
11
11
|
var dirname = path.join(__dirname, 'views/customExtension');
|
|
12
12
|
var render = hbs.create().express4({
|
|
13
13
|
extname: '.server.view.html',
|
|
14
|
-
partialsDir: dirname + '/partialsDir'
|
|
14
|
+
partialsDir: dirname + '/partialsDir',
|
|
15
|
+
restrictLayoutsTo: dirname
|
|
15
16
|
});
|
|
16
17
|
|
|
17
18
|
it('should allow rendering multiple partials with custom extension', function(done) {
|
package/test/helperSpecs.js
CHANGED
|
@@ -15,7 +15,8 @@ describe('helpers', function() {
|
|
|
15
15
|
var hb = hbs.create();
|
|
16
16
|
hb.registerHelper("sync", sync);
|
|
17
17
|
var render = hb.express3({
|
|
18
|
-
viewsDir: dirname
|
|
18
|
+
viewsDir: dirname,
|
|
19
|
+
restrictLayoutsTo: dirname
|
|
19
20
|
});
|
|
20
21
|
var locals = H.createLocals('express3', dirname);
|
|
21
22
|
|
|
@@ -38,7 +39,8 @@ describe('helpers', function() {
|
|
|
38
39
|
hb.registerAsyncHelper("async", async);
|
|
39
40
|
|
|
40
41
|
var render = hb.express3({
|
|
41
|
-
viewsDir: dirname
|
|
42
|
+
viewsDir: dirname,
|
|
43
|
+
restrictLayoutsTo: dirname
|
|
42
44
|
});
|
|
43
45
|
var locals = H.createLocals('express3', dirname);
|
|
44
46
|
|
package/test/issues.js
CHANGED
|
@@ -9,7 +9,9 @@ describe('issue-22 template', function() {
|
|
|
9
9
|
var dirname = path.join(__dirname, 'issues/22');
|
|
10
10
|
|
|
11
11
|
it('should use multiple layouts with caching', function(done) {
|
|
12
|
-
var render = hbs.create().express3({
|
|
12
|
+
var render = hbs.create().express3({
|
|
13
|
+
restrictLayoutsTo: dirname
|
|
14
|
+
});
|
|
13
15
|
var locals1 = H.createLocals('express3', dirname, { layout: 'layout1', cache: true });
|
|
14
16
|
var locals2 = H.createLocals('express3', dirname, { layout: 'layout2', cache: true });
|
|
15
17
|
|
|
@@ -30,7 +32,8 @@ describe('issue-23', function() {
|
|
|
30
32
|
|
|
31
33
|
it('should not pass an empty or missing partial to handlebars', function(done) {
|
|
32
34
|
var render = hbs.create().express3({
|
|
33
|
-
partialsDir: [dirname + '/partials']
|
|
35
|
+
partialsDir: [dirname + '/partials'],
|
|
36
|
+
restrictLayoutsTo: dirname
|
|
34
37
|
});
|
|
35
38
|
|
|
36
39
|
function check(err, html) {
|
|
@@ -43,7 +46,8 @@ describe('issue-23', function() {
|
|
|
43
46
|
|
|
44
47
|
it('should handle empty string', function(done) {
|
|
45
48
|
var render = hbs.create().express3({
|
|
46
|
-
partialsDir: [dirname + '/partials']
|
|
49
|
+
partialsDir: [dirname + '/partials'],
|
|
50
|
+
restrictLayoutsTo: dirname
|
|
47
51
|
});
|
|
48
52
|
|
|
49
53
|
function check(err, html) {
|
|
@@ -58,7 +62,8 @@ describe('issue-23', function() {
|
|
|
58
62
|
it('should register empty partial', function(done) {
|
|
59
63
|
var hb = hbs.create();
|
|
60
64
|
var render = hb.express3({
|
|
61
|
-
partialsDir: [dirname + '/partials']
|
|
65
|
+
partialsDir: [dirname + '/partials'],
|
|
66
|
+
restrictLayoutsTo: dirname
|
|
62
67
|
});
|
|
63
68
|
hb.handlebars.registerPartial('emptyPartial', '');
|
|
64
69
|
|
|
@@ -82,7 +87,8 @@ describe('issue-23', function() {
|
|
|
82
87
|
it('should register partial that results in empty string (comment)', function(done) {
|
|
83
88
|
var hb = hbs.create();
|
|
84
89
|
var render = hb.express3({
|
|
85
|
-
partialsDir: [dirname + '/partials']
|
|
90
|
+
partialsDir: [dirname + '/partials'],
|
|
91
|
+
restrictLayoutsTo: dirname
|
|
86
92
|
});
|
|
87
93
|
// this fails
|
|
88
94
|
//hb.handlebars.registerPartial('emptyComment', '{{! just a comment}}');
|
|
@@ -110,7 +116,8 @@ describe('issue-23', function() {
|
|
|
110
116
|
describe('issue-21', function() {
|
|
111
117
|
var dirname = path.join(__dirname, 'issues/21');
|
|
112
118
|
var render = hbs.create().express3({
|
|
113
|
-
layoutsDir: dirname + '/views/layouts'
|
|
119
|
+
layoutsDir: dirname + '/views/layouts',
|
|
120
|
+
restrictLayoutsTo: dirname
|
|
114
121
|
});
|
|
115
122
|
|
|
116
123
|
it('should allow specifying layouts without the parent dir', function(done) {
|
|
@@ -158,7 +165,9 @@ describe('issue-21', function() {
|
|
|
158
165
|
|
|
159
166
|
it('should treat layouts relative to views directory if layoutsDir is not passed', function(done) {
|
|
160
167
|
var dirname = path.join(__dirname, 'issues/21');
|
|
161
|
-
var render = hbs.create().express3(
|
|
168
|
+
var render = hbs.create().express3({
|
|
169
|
+
restrictLayoutsTo: dirname
|
|
170
|
+
});
|
|
162
171
|
|
|
163
172
|
function check(err, html) {
|
|
164
173
|
assert.ifError(err);
|
|
@@ -177,7 +186,9 @@ describe('issue-49', function() {
|
|
|
177
186
|
|
|
178
187
|
it('should report filename with error', function(done) {
|
|
179
188
|
var hb = hbs.create()
|
|
180
|
-
var render = hb.express3({
|
|
189
|
+
var render = hb.express3({
|
|
190
|
+
restrictLayoutsTo: dirname
|
|
191
|
+
});
|
|
181
192
|
var locals = H.createLocals('express3', dirname, {});
|
|
182
193
|
render(dirname + '/error.hbs', locals, function(err, html) {
|
|
183
194
|
assert(err.stack.indexOf('[error.hbs]') > 0);
|
|
@@ -187,7 +198,9 @@ describe('issue-49', function() {
|
|
|
187
198
|
|
|
188
199
|
it('should report relative filename with error', function(done) {
|
|
189
200
|
var hb = hbs.create()
|
|
190
|
-
var render = hb.express3({
|
|
201
|
+
var render = hb.express3({
|
|
202
|
+
restrictLayoutsTo: dirname
|
|
203
|
+
});
|
|
191
204
|
var locals = H.createLocals('express3', dirname, {});
|
|
192
205
|
render(dirname + '/front/error.hbs', locals, function(err, html) {
|
|
193
206
|
assert(err.stack.indexOf('[front/error.hbs]') > 0);
|
|
@@ -198,7 +211,8 @@ describe('issue-49', function() {
|
|
|
198
211
|
it('should report filename with partial error', function(done) {
|
|
199
212
|
var hb = hbs.create()
|
|
200
213
|
var render = hb.express3({
|
|
201
|
-
partialsDir: dirname + '/partials'
|
|
214
|
+
partialsDir: dirname + '/partials',
|
|
215
|
+
restrictLayoutsTo: dirname
|
|
202
216
|
});
|
|
203
217
|
var locals = H.createLocals('express3', dirname, {});
|
|
204
218
|
render(dirname + '/partial.hbs', locals, function(err, html) {
|
|
@@ -210,7 +224,8 @@ describe('issue-49', function() {
|
|
|
210
224
|
it('should report filename with layout error', function(done) {
|
|
211
225
|
var hb = hbs.create()
|
|
212
226
|
var render = hb.express3({
|
|
213
|
-
partialsDir: dirname + '/partials'
|
|
227
|
+
partialsDir: dirname + '/partials',
|
|
228
|
+
restrictLayoutsTo: dirname
|
|
214
229
|
});
|
|
215
230
|
var locals = H.createLocals('express3', dirname, {});
|
|
216
231
|
render(dirname + '/index.hbs', locals, function(err, html) {
|
|
@@ -231,7 +246,9 @@ describe('issue-53', function() {
|
|
|
231
246
|
resultcb(++res);
|
|
232
247
|
}, 1)
|
|
233
248
|
});
|
|
234
|
-
var render = hb.express3({
|
|
249
|
+
var render = hb.express3({
|
|
250
|
+
restrictLayoutsTo: dirname
|
|
251
|
+
});
|
|
235
252
|
var locals = H.createLocals('express3', dirname, {});
|
|
236
253
|
render(dirname + '/index.hbs', locals, function(err, html) {
|
|
237
254
|
assert.ifError(err);
|
|
@@ -253,7 +270,8 @@ describe('issue-59', function() {
|
|
|
253
270
|
hb.registerAsyncHelper("async", async);
|
|
254
271
|
|
|
255
272
|
var render = hb.express3({
|
|
256
|
-
viewsDir: dirname
|
|
273
|
+
viewsDir: dirname,
|
|
274
|
+
restrictLayoutsTo: dirname
|
|
257
275
|
});
|
|
258
276
|
var locals = H.createLocals('express3', dirname);
|
|
259
277
|
|
|
@@ -272,7 +290,8 @@ describe('issue-59', function() {
|
|
|
272
290
|
hb.registerAsyncHelper('async', async);
|
|
273
291
|
|
|
274
292
|
var render = hb.express3({
|
|
275
|
-
viewsDir: dirname
|
|
293
|
+
viewsDir: dirname,
|
|
294
|
+
restrictLayoutsTo: dirname
|
|
276
295
|
});
|
|
277
296
|
var locals = H.createLocals('express3', dirname);
|
|
278
297
|
|
|
@@ -290,6 +309,7 @@ describe('issue-73', function() {
|
|
|
290
309
|
var render = hb.express3({
|
|
291
310
|
viewsDir: dirname,
|
|
292
311
|
partialsDir: dirname + '/partials',
|
|
312
|
+
restrictLayoutsTo: dirname,
|
|
293
313
|
onCompile: function(eh, source, filename) {
|
|
294
314
|
var options;
|
|
295
315
|
if (filename && filename.indexOf('partials')) {
|
|
@@ -329,7 +349,8 @@ describe('issue-62', function() {
|
|
|
329
349
|
hb.registerAsyncHelper("async", async);
|
|
330
350
|
|
|
331
351
|
var render = hb.express3({
|
|
332
|
-
viewsDir: dirname
|
|
352
|
+
viewsDir: dirname,
|
|
353
|
+
restrictLayoutsTo: dirname
|
|
333
354
|
});
|
|
334
355
|
var locals = H.createLocals('express3', dirname);
|
|
335
356
|
|
|
@@ -359,7 +380,8 @@ describe('issue-62', function() {
|
|
|
359
380
|
hb.registerAsyncHelper("async", async);
|
|
360
381
|
|
|
361
382
|
var render = hb.express3({
|
|
362
|
-
viewsDir: dirname
|
|
383
|
+
viewsDir: dirname,
|
|
384
|
+
restrictLayoutsTo: dirname
|
|
363
385
|
});
|
|
364
386
|
var locals = H.createLocals('express3', dirname);
|
|
365
387
|
|
|
@@ -380,7 +402,8 @@ describe('issue-76', function() {
|
|
|
380
402
|
var hb = hbs.create();
|
|
381
403
|
|
|
382
404
|
var render = hb.express3({
|
|
383
|
-
partialsDir: dirname
|
|
405
|
+
partialsDir: dirname,
|
|
406
|
+
restrictLayoutsTo: dirname
|
|
384
407
|
});
|
|
385
408
|
|
|
386
409
|
hb.cachePartials(function (err) {
|
|
@@ -396,7 +419,8 @@ describe('issue-84', function () {
|
|
|
396
419
|
|
|
397
420
|
it('should render deeply nested partials', function (done) {
|
|
398
421
|
var render = hbs.create().express3({
|
|
399
|
-
partialsDir: [dirname + '/partials']
|
|
422
|
+
partialsDir: [dirname + '/partials'],
|
|
423
|
+
restrictLayoutsTo: dirname
|
|
400
424
|
});
|
|
401
425
|
|
|
402
426
|
function check(err, html) {
|
|
@@ -421,7 +445,9 @@ describe('issue-144', function() {
|
|
|
421
445
|
resultcb(new hbs.SafeString('<p><code>\'$example$\'</code> abcd</p>'));
|
|
422
446
|
}, 1)
|
|
423
447
|
});
|
|
424
|
-
var render = hb.express3({
|
|
448
|
+
var render = hb.express3({
|
|
449
|
+
restrictLayoutsTo: dirname
|
|
450
|
+
});
|
|
425
451
|
var locals = H.createLocals('express3', dirname, {});
|
|
426
452
|
render(dirname + '/index.hbs', locals, function(err, html) {
|
|
427
453
|
assert.equal('<div><p><code>\'$example$\'</code> abcd</p></div>\n', html);
|
|
@@ -441,7 +467,9 @@ describe('issue-153', function() {
|
|
|
441
467
|
done();
|
|
442
468
|
}
|
|
443
469
|
var hb = hbs.create()
|
|
444
|
-
var render = hb.express3({
|
|
470
|
+
var render = hb.express3({
|
|
471
|
+
restrictLayoutsTo: dirname
|
|
472
|
+
});
|
|
445
473
|
var locals = H.createLocals('express3', dirname, { });
|
|
446
474
|
render(dirname + '/index.hbs', locals, check);
|
|
447
475
|
});
|
package/test/layoutSpecs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var request = require('supertest');
|
|
2
2
|
var assert = require('assert');
|
|
3
|
+
var path = require('path');
|
|
3
4
|
var hbs = require('..');
|
|
4
5
|
|
|
5
6
|
|
|
@@ -65,6 +66,7 @@ describe('layouts', function() {
|
|
|
65
66
|
|
|
66
67
|
it ('should process template-specified layout without option', function(done) {
|
|
67
68
|
var render = hbs.create().express3({
|
|
69
|
+
restrictLayoutsTo: dirname
|
|
68
70
|
});
|
|
69
71
|
var locals = createLocals('express3', dirname);
|
|
70
72
|
|
|
@@ -76,6 +78,7 @@ describe('layouts', function() {
|
|
|
76
78
|
|
|
77
79
|
it ('should allow options.layout to be specified', function(done) {
|
|
78
80
|
var render = hbs.create().express3({
|
|
81
|
+
restrictLayoutsTo: dirname
|
|
79
82
|
});
|
|
80
83
|
var locals = createLocals('express3', dirname, { layout: 'layouts/default' });
|
|
81
84
|
|
|
@@ -85,8 +88,23 @@ describe('layouts', function() {
|
|
|
85
88
|
});
|
|
86
89
|
});
|
|
87
90
|
|
|
91
|
+
it('should error when using a layout outside of the restrictLayoutsTo', function(done) {
|
|
92
|
+
var render = hbs.create().express3({
|
|
93
|
+
restrictLayoutsTo: path.resolve(path.join(__dirname, '../'))
|
|
94
|
+
});
|
|
95
|
+
var locals = createLocals('express3', dirname, {layout: '/Users/egg/Code/Ghost/ghost/core/package.json'});
|
|
96
|
+
|
|
97
|
+
render(dirname + '/aside.hbs', locals, function (err, html) {
|
|
98
|
+
if (!err) {
|
|
99
|
+
return done(new Error('We expect an error when reading'));
|
|
100
|
+
}
|
|
101
|
+
return done();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
88
105
|
it ('should not process template-specified layout when options.layout is falsy', function(done) {
|
|
89
106
|
var render = hbs.create().express3({
|
|
107
|
+
restrictLayoutsTo: dirname
|
|
90
108
|
});
|
|
91
109
|
var locals = createLocals('express3', dirname, { layout: false });
|
|
92
110
|
|
|
@@ -11,7 +11,9 @@ describe('local template options', function () {
|
|
|
11
11
|
|
|
12
12
|
it('merges res.locals._templateOptions with the self._templateOptions', function (done) {
|
|
13
13
|
var instance = hbs.create();
|
|
14
|
-
var render = instance.express3({
|
|
14
|
+
var render = instance.express3({
|
|
15
|
+
restrictLayoutsTo: dirname
|
|
16
|
+
});
|
|
15
17
|
instance.updateTemplateOptions({
|
|
16
18
|
data: {
|
|
17
19
|
greeting: 'Hello,',
|
|
@@ -37,7 +39,9 @@ describe('local template options', function () {
|
|
|
37
39
|
|
|
38
40
|
it('removes _templateOptions from the locals data', function (done) {
|
|
39
41
|
var instance = hbs.create();
|
|
40
|
-
var render = instance.express3({
|
|
42
|
+
var render = instance.express3({
|
|
43
|
+
restrictLayoutsTo: dirname
|
|
44
|
+
});
|
|
41
45
|
instance.updateTemplateOptions({
|
|
42
46
|
data: {
|
|
43
47
|
greeting: 'Hello,',
|
|
@@ -66,7 +70,9 @@ describe('local template options', function () {
|
|
|
66
70
|
|
|
67
71
|
it('merges res.locals._templateOptions with the self._templateOptions', function (done) {
|
|
68
72
|
var instance = hbs.create();
|
|
69
|
-
var render = instance.express4({
|
|
73
|
+
var render = instance.express4({
|
|
74
|
+
restrictLayoutsTo: dirname
|
|
75
|
+
});
|
|
70
76
|
instance.updateTemplateOptions({
|
|
71
77
|
data: {
|
|
72
78
|
greeting: 'Hello,',
|
|
@@ -92,7 +98,9 @@ describe('local template options', function () {
|
|
|
92
98
|
|
|
93
99
|
it('removes _templateOptions from the locals data', function (done) {
|
|
94
100
|
var instance = hbs.create();
|
|
95
|
-
var render = instance.express3({
|
|
101
|
+
var render = instance.express3({
|
|
102
|
+
restrictLayoutsTo: dirname
|
|
103
|
+
});
|
|
96
104
|
instance.updateTemplateOptions({
|
|
97
105
|
data: {
|
|
98
106
|
greeting: 'Hello,',
|
package/test/multiple.js
CHANGED
|
@@ -10,7 +10,9 @@ describe('multiple directories', function() {
|
|
|
10
10
|
|
|
11
11
|
beforeEach(function() {
|
|
12
12
|
app = express();
|
|
13
|
-
app.engine('hbs', hbs.express3(
|
|
13
|
+
app.engine('hbs', hbs.express3({
|
|
14
|
+
restrictLayoutsTo: './test/views/multiple'
|
|
15
|
+
}));
|
|
14
16
|
app.set('view engine', 'hbs');
|
|
15
17
|
app.get('/test1', function (req, res) {
|
|
16
18
|
res.render('test1');
|
package/test/nonExpress.js
CHANGED
|
@@ -9,7 +9,8 @@ describe('non-express', function() {
|
|
|
9
9
|
|
|
10
10
|
it ('should use viewsDir options', function(done) {
|
|
11
11
|
var render = hbs.create().express3({
|
|
12
|
-
viewsDir: dirname
|
|
12
|
+
viewsDir: dirname,
|
|
13
|
+
restrictLayoutsTo: dirname
|
|
13
14
|
});
|
|
14
15
|
var locals = H.createLocals('express3', dirname);
|
|
15
16
|
|
|
@@ -22,7 +23,8 @@ describe('non-express', function() {
|
|
|
22
23
|
it ('should work with layoutsDir', function(done) {
|
|
23
24
|
var render = hbs.create().express3({
|
|
24
25
|
viewsDir: dirname,
|
|
25
|
-
layoutsDir: dirname + '/layouts'
|
|
26
|
+
layoutsDir: dirname + '/layouts',
|
|
27
|
+
restrictLayoutsTo: dirname
|
|
26
28
|
});
|
|
27
29
|
var locals = H.createLocals('express3', dirname, {layout: 'default.hbs'});
|
|
28
30
|
|
package/test/optionsSpecs.js
CHANGED
|
@@ -10,7 +10,7 @@ describe('options', function() {
|
|
|
10
10
|
|
|
11
11
|
it('should pretty print HTML', function(done) {
|
|
12
12
|
var hb = hbs.create();
|
|
13
|
-
var render = hb.express3({beautify: true});
|
|
13
|
+
var render = hb.express3({beautify: true, restrictLayoutsTo: dirname});
|
|
14
14
|
var locals = H.createLocals('express3', dirname, {});
|
|
15
15
|
|
|
16
16
|
render(dirname + '/index.hbs', locals, function(err, html) {
|