Comparing version 0.10.5 to 0.10.6
131
index.js
@@ -38,9 +38,13 @@ 'use strict'; | ||
if (utils.isBuffer(str)) { | ||
str = str.toString(); | ||
str = String(str); | ||
} | ||
if (typeof str !== 'string') { | ||
throw new TypeError('layouts expects a string.'); | ||
throw new TypeError('expected content to be a string.'); | ||
} | ||
if (typeof name !== 'string') { | ||
throw new TypeError('expected layout name to be a string.'); | ||
} | ||
if (typeof opts === 'function') { | ||
@@ -58,7 +62,9 @@ fn = opts; | ||
var view = {options: {}, history: []}; | ||
name = assertLayout(name, opts.defaultLayout); | ||
// recursively resolve layouts | ||
while (name && (prev !== name) && (layout = layoutStack[name])) { | ||
prev = name; | ||
var delims = opts.layoutDelims; | ||
str = toString(str); | ||
@@ -72,23 +78,23 @@ // `data` is passed to `wrapLayout` to resolve layouts | ||
// get info about the current layout | ||
var obj = {}; | ||
obj.layout = layout; | ||
obj.layout.name = name; | ||
obj.before = str; | ||
obj.depth = depth++; | ||
var obj = new Layout({ | ||
name: name, | ||
layout: layout, | ||
before: str, | ||
depth: depth++ | ||
}); | ||
// get the delimiter regex | ||
var re = makeDelimiterRegex(delims); | ||
var re = makeDelimiterRegex(delims, tag); | ||
// ensure that content is a string | ||
var content = toString(layout.contents || layout.content); | ||
var content = String(layout.content); | ||
if (!re.test(content)) { | ||
throw new Error('cannot find layout tag "' + tag + '" in "' + name + '"'); | ||
throw error(re, name, tag); | ||
} | ||
// inject the string into the layout | ||
str = wrapLayout(content, data, re); | ||
str = wrapLayout(content, data, re, name, tag); | ||
obj.after = str; | ||
// if a (sync) callback is passed, allow it modify | ||
// the result in place | ||
// if a callback is passed, allow it modify the result | ||
if (typeof fn === 'function') { | ||
@@ -100,3 +106,2 @@ fn(obj, view, depth); | ||
view.history.push(obj); | ||
prev = name; | ||
@@ -108,2 +113,6 @@ // should we recurse again? | ||
if (typeof name === 'string' && prev !== name) { | ||
throw new Error('could not find layout "' + name + '"'); | ||
} | ||
view.options = opts; | ||
@@ -115,2 +124,17 @@ view.result = str; | ||
/** | ||
* Create a new layout in the layout stack. | ||
* | ||
* @param {Object} `view` The layout view object | ||
* @param {Number} `depth` Current stack depth | ||
*/ | ||
function Layout(view) { | ||
this.layout = view.layout; | ||
this.layout.name = view.name; | ||
this.before = view.before; | ||
this.depth = view.depth; | ||
return this; | ||
} | ||
/** | ||
* Assert whether or not a layout should be used based on | ||
@@ -142,5 +166,9 @@ * the given `value`. | ||
function wrapLayout(str, data, re) { | ||
function wrapLayout(str, data, re, name, tag) { | ||
return str.replace(re, function(_, tagName) { | ||
return data[tagName.trim()]; | ||
var m = data[tagName.trim()]; | ||
if (typeof m === 'undefined') { | ||
throw error(re, name, tag); | ||
} | ||
return m; | ||
}); | ||
@@ -156,4 +184,6 @@ } | ||
function makeDelimiterRegex(syntax) { | ||
if (!syntax) return /\{% ([^{}]+?) %}/g; | ||
function makeDelimiterRegex(syntax, tag) { | ||
if (!syntax) { | ||
syntax = makeTag(tag, ['{%', '%}']); | ||
} | ||
if (syntax instanceof RegExp) { | ||
@@ -169,5 +199,3 @@ return syntax; | ||
} | ||
if (Array.isArray(syntax)) { | ||
return (cache[syntax] = utils.delims(syntax)); | ||
} | ||
return (cache[name] = utils.delims(syntax)); | ||
} | ||
@@ -179,4 +207,59 @@ | ||
function toString(val) { | ||
return val == null ? '' : val.toString(); | ||
function makeTag(val, delims) { | ||
return delims[0].trim() | ||
+ ' (' | ||
+ String(val).trim() | ||
+ ') ' | ||
+ delims[1].trim(); | ||
} | ||
/** | ||
* Format an error message | ||
*/ | ||
function error(re, name, tag) { | ||
var delims = matchDelims(re, tag); | ||
return new Error('cannot find "' + delims + '" in "' + name + '"'); | ||
} | ||
/** | ||
* Only used if an error is thrown. Attempts to recreate | ||
* delimiters for the error message. | ||
*/ | ||
var types = { | ||
'{%=': function (str) { | ||
return '{%= ' + str + ' %}'; | ||
}, | ||
'{%-': function (str) { | ||
return '{%- ' + str + ' %}'; | ||
}, | ||
'{%': function (str) { | ||
return '{% ' + str + ' %}'; | ||
}, | ||
'{{': function (str) { | ||
return '{{ ' + str + ' }}'; | ||
}, | ||
'<%': function (str) { | ||
return '<% ' + str + ' %>'; | ||
}, | ||
'<%=': function (str) { | ||
return '<%= ' + str + ' %>'; | ||
}, | ||
'<%-': function (str) { | ||
return '<%- ' + str + ' %>'; | ||
} | ||
}; | ||
function matchDelims(re, str) { | ||
var ch = re.source.slice(0, 4); | ||
if (/[\\]/.test(ch.charAt(0))) { | ||
ch = ch.slice(1); | ||
} | ||
if (!/[-=]/.test(ch.charAt(2))) { | ||
ch = ch.slice(0, 2); | ||
} else { | ||
ch = ch.slice(0, 3); | ||
} | ||
return types[ch](str); | ||
} |
{ | ||
"name": "layouts", | ||
"description": "Wraps templates with layouts. Layouts can use other layouts and be nested to any depth. This can be used 100% standalone to wrap any kind of file with banners, headers or footer content. Use for markdown, HTML, handlebars views, lo-dash templates, etc. Layouts can also be vinyl files.", | ||
"version": "0.10.5", | ||
"version": "0.10.6", | ||
"homepage": "https://github.com/doowb/layouts", | ||
@@ -93,7 +93,6 @@ "author": "Brian Woodward (https://github.com/doowb)", | ||
"list": [ | ||
"template", | ||
"templates", | ||
"assemble", | ||
"verb", | ||
"handlebars-helpers", | ||
"template-helpers" | ||
"inject-snippet", | ||
"handlebars-layouts" | ||
] | ||
@@ -100,0 +99,0 @@ } |
@@ -141,6 +141,5 @@ # layouts [![NPM version](https://badge.fury.io/js/layouts.svg)](http://badge.fury.io/js/layouts) [![Build Status](https://travis-ci.org/doowb/layouts.svg)](https://travis-ci.org/doowb/layouts) | ||
* [assemble](https://www.npmjs.com/package/assemble): Static site generator for Grunt.js, Yeoman and Node.js. Used by Zurb Foundation, Zurb Ink, H5BP/Effeckt,… [more](https://www.npmjs.com/package/assemble) | [homepage](http://assemble.io) | ||
* [handlebars-helpers](https://www.npmjs.com/package/handlebars-helpers): 120+ Handlebars helpers in ~20 categories, for Assemble, YUI, Ghost or any Handlebars project. Includes… [more](https://www.npmjs.com/package/handlebars-helpers) | [homepage](https://github.com/assemble/handlebars-helpers) | ||
* [template](https://www.npmjs.com/package/template): Render templates using any engine. Supports, layouts, pages, partials and custom template types. Use template… [more](https://www.npmjs.com/package/template) | [homepage](https://github.com/jonschlinkert/template) | ||
* [template-helpers](https://www.npmjs.com/package/template-helpers): Generic JavaScript helpers that can be used with any template engine. Handlebars, Lo-Dash, Underscore, or… [more](https://www.npmjs.com/package/template-helpers) | [homepage](https://github.com/jonschlinkert/template-helpers) | ||
* [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://www.npmjs.com/package/verb) | [homepage](https://github.com/verbose/verb) | ||
* [handlebars-layouts](https://www.npmjs.com/package/handlebars-layouts): Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig. | [homepage](https://github.com/shannonmoeller/handlebars-layouts) | ||
* [inject-snippet](https://www.npmjs.com/package/inject-snippet): Inject a snippet of code or content into a string. | [homepage](https://github.com/jonschlinkert/inject-snippet) | ||
* [templates](https://www.npmjs.com/package/templates): System for creating and managing template collections, and rendering templates with any node.js template engine.… [more](https://www.npmjs.com/package/templates) | [homepage](https://github.com/jonschlinkert/templates) | ||
@@ -173,2 +172,2 @@ ## Running tests | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 08, 2015._ | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 02, 2015._ |
24
utils.js
@@ -1,4 +0,20 @@ | ||
var lazy = module.exports = require('lazy-cache')(require); | ||
lazy('falsey', 'isFalsey'); | ||
lazy('is-buffer', 'isBuffer'); | ||
lazy('delimiter-regex', 'delims'); | ||
'use strict'; | ||
/** | ||
* Lazily required module dependencies | ||
*/ | ||
var lazy = require('lazy-cache')(require); | ||
var fn = require; | ||
require = lazy; | ||
require('falsey', 'isFalsey'); | ||
require('is-buffer', 'isBuffer'); | ||
require('delimiter-regex', 'delims'); | ||
require = fn; | ||
/** | ||
* Expose `utils` | ||
*/ | ||
module.exports = lazy; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14386
231
171
2