New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

layouts

Package Overview
Dependencies
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

layouts - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

test/delimiters.js

75

index.js

@@ -39,6 +39,6 @@ /*!

this.cache = Object.create(opts.cache || null);
this.cache = opts.cache || {};
this.extend = opts.extend || _.extend;
this.defaultTag = this.makeTag(opts);
this.regex = this.makeRegex(opts);
this.defaultTag = this.makeTag(opts)
this.options = opts;
};

@@ -59,3 +59,3 @@

Layouts.prototype.makeTag = function (options) {
var opts = _.extend({}, options);
var opts = _.defaults({}, options, this.options);
return [

@@ -81,4 +81,5 @@ opts.delims[0],

Layouts.prototype.makeRegex = function (options) {
var opts = _.extend({sep: '\\s*'}, options);
return new RegExp(this.makeTag(opts), opts.flags);
var opts = _.extend({sep: '\\s*'}, this.options, options);
var tag = this.makeTag(opts).replace(/[\]()[{|}]/g, '\\$&');
return new RegExp(tag, opts.flags || 'g');
};

@@ -111,6 +112,9 @@

}
// if (arguments.length === 2 ) {
// }
this.cache[name] = {
layout: (data && data.layout) ? data.layout : data,
content: content,
content: (data && data.content) ? data.content : content,
data: data

@@ -158,7 +162,6 @@ };

Layouts.prototype.extendData = function (obj, data) {
if (typeof obj.data === 'object') {
this.extend(data, obj.data);
}
delete data.layout;
return data;
this.extend(data, obj, obj.data);
// Remove special properties
return _.omit(data, ['content', 'layout', 'data']);
};

@@ -227,12 +230,19 @@

Layouts.prototype.stack = function (name) {
Layouts.prototype.stack = function (name, options) {
var stack = this.createStack(name);
var opts = _.extend(this.options, options);
var data = {};
var tag = this.makeTag(opts) || this.defaultTag;
this.regex = this.makeRegex(opts);
return _.reduce(stack, function (acc, layout) {
var content = acc.content || tag;
var tmpl = this.cache[layout];
var content = acc.content || this.defaultTag;
return {
data: this.extendData(tmpl, data),
content: content.replace(this.regex, tmpl.content)
content: content.replace(this.regex, tmpl.content),
regex: this.regex,
tag: tag
};

@@ -244,5 +254,29 @@ }.bind(this), {});

/**
* ## .replaceTag
*
* Replace a `{{body}}` tag (or equivalent if custom delims are used) in `content`
* with the given `str`.
*
* **Example:**
*
* ```js
* console.log(layouts.replaceTag('ABC', 'Before {{body}} After'));
* //=> 'Before ABC After'
* ```
*
* @param {String} `str` The string to use as a replacement value.
* @param {String} `content` A string with a `{{body}}` tag where the `str` should be injected.
* @return {String} Resulting flattened content.
* @api public
*/
Layouts.prototype.replaceTag = function (str, content, options) {
return content.replace(this.makeRegex(options), str);
};
/**
* ## .inject
*
* Flatten nested layouts.
* Inject content into a layout stack.
*

@@ -256,9 +290,10 @@ * **Example:**

*
* @param {String} `str` The content to inject into the layout.
* @param {String} `name` The layout to start with.
* @return {String} Resulting flattened layout.
* @api private
* @api public
*/
Layouts.prototype.inject = function (str, name) {
var layout = this.stack(name);
Layouts.prototype.inject = function (str, name, options) {
var layout = this.stack(name, options);
if (layout.content) {

@@ -268,2 +303,2 @@ str = layout.content.replace(this.regex, str);

return {data: layout.data, content: str};
};
};
{
"name": "layouts",
"description": "Wrap templates with layouts. Layouts can use/refer to other layouts, allowing them to be nested.",
"version": "0.1.1",
"description": "Wrap templates with layouts. Layouts can be nested and optionally use other layouts.",
"version": "0.2.0",
"homepage": "https://github.com/jonschlinkert/layouts",

@@ -47,2 +47,4 @@ "author": {

"mustache",
"nest",
"nested",
"nunjucks",

@@ -52,2 +54,4 @@ "page",

"ractive",
"stack",
"stacked",
"swig",

@@ -62,3 +66,4 @@ "template",

"walrus",
"whiskers"
"whiskers",
"wrap"
],

@@ -81,5 +86,6 @@ "main": "index.js",

"dependencies": {
"debug": "^1.0.4",
"falsey": "^0.1.0",
"lodash": "^2.4.1"
}
}
}

@@ -13,53 +13,34 @@ /*!

var layouts = new Layouts({
cache: {
a: { layout: 'b', content: 'A above\n{{body}}\nA below' },
b: { layout: 'c', content: 'B above\n{{body}}\nB below' },
c: { layout: 'd', content: 'C above\n{{body}}\nC below' },
d: { layout: 'e', content: 'D above\n{{body}}\nD below' },
base: { layout: undefined, content: 'base!\n{{body}}\nbase!' },
e: { layout: 'f', content: 'E above\n{{body}}\nE below' },
f: { layout: 'base', content: 'F above\n{{body}}\nF below' },
foo: { layout: 'a', content: 'I\'m a <%= title %>' },
simple: { layout: 'base', content: 'I\'m a simple page.' },
}
});
describe('layouts cache', function () {
describe('.cache()', function () {
it('should recursively inject content from each file into its layout.', function () {
// Define the name of the cached template to start with
var actual = layouts.stack('simple');
var expected = [
'base!',
'I\'m a simple page.',
'base!'
].join('\n');
actual.content.should.eql(expected);
it('should add layouts to the cache when passed to `new Layouts`.', function () {
var layouts = new Layouts({
cache: {
first: { layout: 'a', content: 'I\'m a <%= title %>' },
a: { layout: 'b', content: 'A above\n{{body}}\nA below' },
b: { layout: 'c', content: 'B above\n{{body}}\nB below' },
c: { layout: 'd', content: 'C above\n{{body}}\nC below' },
d: { layout: 'e', content: 'D above\n{{body}}\nD below' },
e: { layout: 'f', content: 'E above\n{{body}}\nE below' },
f: { layout: 'last', content: 'F above\n{{body}}\nF below' },
last: { layout: undefined, content: 'last!\n{{body}}\nlast!' }
}
});
Object.keys(layouts.cache).length.should.eql(8);
});
it('should extend the `cache`.', function () {
var actual = layouts.stack('foo');
var expected = [
'base!',
'F above',
'E above',
'D above',
'C above',
'B above',
'A above',
'I\'m a <%= title %>', // should not be compiled
'A below',
'B below',
'C below',
'D below',
'E below',
'F below',
'base!'
].join('\n');
it('should add layouts to the cache when using `.set()`.', function () {
var layouts = new Layouts();
actual.content.should.eql(expected);
});
layouts.set('first', 'a', 'I\'m a <%= title %>');
layouts.set('a', 'b', 'A above\n{{body}}\nA below');
layouts.set('b', 'c', 'B above\n{{body}}\nB below');
layouts.set('c', 'd', 'C above\n{{body}}\nC below');
layouts.set('d', 'e', 'D above\n{{body}}\nD below');
layouts.set('e', 'f', 'E above\n{{body}}\nE below');
layouts.set('f', 'last', 'F above\n{{body}}\nF below');
layouts.set('last', undefined, 'last!\n{{body}}\nlast!');
Object.keys(layouts.cache).length.should.eql(8);
});
});

@@ -14,3 +14,4 @@ /*!

describe('layouts data', function () {
describe('.data()', function () {
layouts.set('first', 'a', '{{body}}');
layouts.set('a', {layout: 'b', xyz: 'aaa', one: 'two'}, 'A above\n{{body}}\nA below');

@@ -20,11 +21,10 @@ layouts.set('b', {layout: 'c', xyz: 'bbb', three: 'four'}, 'B above\n{{body}}\nB below');

layouts.set('d', 'e', 'D above\n{{body}}\nD below');
layouts.set('base', {xyz: 'zzz'}, 'base!\n{{body}}\nbase!');
layouts.set('e', 'f', 'E above\n{{body}}\nE below');
layouts.set('f', 'base', 'F above\n{{body}}\nF below');
layouts.set('foo', 'a', 'I\'m a <%= title %>');
layouts.set('f', 'last', 'F above\n{{body}}\nF below');
layouts.set('last', {xyz: 'zzz'}, 'last!\n{{body}}\nlast!');
it('should return an extended data object from the flattened layouts.', function () {
var actual = layouts.stack('foo');
var actual = layouts.stack('first');
var expected = [
'base!',
'last!',
'F above',

@@ -36,3 +36,3 @@ 'E above',

'A above',
'I\'m a <%= title %>', // should not be compiled
'{{body}}', // should not be compiled
'A below',

@@ -44,3 +44,3 @@ 'B below',

'F below',
'base!'
'last!'
].join('\n');

@@ -47,0 +47,0 @@ actual.content.should.eql(expected);

@@ -17,17 +17,17 @@ /*!

var layouts = new Layouts();
layouts.set('first', 'a', '{{body}}');
layouts.set('a', {layout: 'b', xyz: 'aaa', one: 'two'}, 'A above\n{{body}}\nA below');
layouts.set('b', {layout: 'base', xyz: 'bbb', three: 'four'}, 'B above\n{{body}}\nB below');
layouts.set('base', {xyz: 'zzz'}, 'base!\n{{body}}\nbase!');
layouts.set('foo', 'a', 'I\'m a <%= title %>');
layouts.set('b', {layout: 'last', xyz: 'bbb', three: 'four'}, 'B above\n{{body}}\nB below');
layouts.set('last', {xyz: 'zzz'}, 'last!\n{{body}}\nlast!');
it('should merge the context so that the inner-most templates context wins.', function () {
var actual = layouts.stack('foo');
var actual = layouts.stack('first');
var expected = [
'base!',
'last!',
'B above',
'A above',
'I\'m a <%= title %>',
'{{body}}',
'A below',
'B below',
'base!'
'last!'
].join('\n');

@@ -42,16 +42,16 @@ actual.content.should.eql(expected);

layouts.set('a', {layout: 'b', xyz: 'aaa', one: 'two'}, 'A above\n{{body}}\nA below');
layouts.set('b', {layout: 'base', xyz: 'bbb', three: 'four'}, 'B above\n{{body}}\nB below');
layouts.set('base', {xyz: 'zzz'}, 'base!\n{{body}}\nbase!');
layouts.set('foo', 'a', 'I\'m a <%= title %>');
layouts.set('b', {layout: 'last', xyz: 'bbb', three: 'four'}, 'B above\n{{body}}\nB below');
layouts.set('last', {xyz: 'zzz'}, 'last!\n{{body}}\nlast!');
layouts.set('first', 'a', '{{body}}');
it('should change the order in which the context is merged.', function () {
var actual = layouts.stack('foo');
var actual = layouts.stack('first');
var expected = [
'base!',
'last!',
'B above',
'A above',
'I\'m a <%= title %>',
'{{body}}',
'A below',
'B below',
'base!'
'last!'
].join('\n');

@@ -58,0 +58,0 @@ actual.content.should.eql(expected);

@@ -19,11 +19,11 @@ /*!

layouts.set({d: { layout: 'e', content: 'D above\n{{body}}\nD below' }});
layouts.set({base: { layout: undefined, content: 'base!\n{{body}}\nbase!' }});
layouts.set({last: { layout: undefined, content: 'last!\n{{body}}\nlast!' }});
layouts.set({e: { layout: 'f', content: 'E above\n{{body}}\nE below' }});
layouts.set({f: { layout: 'base', content: 'F above\n{{body}}\nF below' }});
layouts.set({foo: { layout: 'a', content: 'I\'m a <%= title %>' }});
layouts.set({f: { layout: 'last', content: 'F above\n{{body}}\nF below' }});
layouts.set({first: { layout: 'a', content: 'I\'m a <%= title %>' }});
it('should extend the `cache`.', function () {
var actual = layouts.stack('foo');
var actual = layouts.stack('first');
var expected = [
'base!',
'last!',
'F above',

@@ -42,3 +42,3 @@ 'E above',

'F below',
'base!'
'last!'
].join('\n');

@@ -50,2 +50,3 @@ actual.content.should.eql(expected);

describe('when layouts are defined with string values:', function () {
layouts.set('first', 'a', 'I\'m a <%= title %>');
layouts.set('a', 'b', 'A above\n{{body}}\nA below');

@@ -55,11 +56,10 @@ layouts.set('b', 'c', 'B above\n{{body}}\nB below');

layouts.set('d', 'e', 'D above\n{{body}}\nD below');
layouts.set('base', undefined, 'base!\n{{body}}\nbase!');
layouts.set('e', 'f', 'E above\n{{body}}\nE below');
layouts.set('f', 'base', 'F above\n{{body}}\nF below');
layouts.set('foo', 'a', 'I\'m a <%= title %>');
layouts.set('f', 'last', 'F above\n{{body}}\nF below');
layouts.set('last', undefined, 'last!\n{{body}}\nlast!');
it('should extend the `cache`.', function () {
var actual = layouts.stack('foo');
var actual = layouts.stack('first');
var expected = [
'base!',
'last!',
'F above',

@@ -78,3 +78,3 @@ 'E above',

'F below',
'base!'
'last!'
].join('\n');

@@ -84,2 +84,70 @@ actual.content.should.eql(expected);

});
describe('when an object is passed as the second parameter:', function () {
describe('when a `layout` propery is defined:', function () {
layouts.set('first', {layout: 'a'}, 'I\'m a <%= title %>');
layouts.set('a', {layout: 'b'}, 'A above\n{{body}}\nA below');
layouts.set('b', {layout: 'c'}, 'B above\n{{body}}\nB below');
layouts.set('c', {layout: 'd'}, 'C above\n{{body}}\nC below');
layouts.set('d', {layout: 'e'}, 'D above\n{{body}}\nD below');
layouts.set('e', {layout: 'f'}, 'E above\n{{body}}\nE below');
layouts.set('f', {layout: 'last'}, 'F above\n{{body}}\nF below');
layouts.set('last', {layout: undefined}, 'last!\n{{body}}\nlast!');
it('should extend the `cache` with the layout', function () {
var actual = layouts.stack('first');
var expected = [
'last!',
'F above',
'E above',
'D above',
'C above',
'B above',
'A above',
'I\'m a <%= title %>', // should not be compiled
'A below',
'B below',
'C below',
'D below',
'E below',
'F below',
'last!'
].join('\n');
actual.content.should.eql(expected);
});
});
describe('when a `content` propery is defined:', function () {
layouts.set('first', {layout: 'a', content: 'I\'m a <%= title %>'});
layouts.set('a', {layout: 'b', content: 'A above\n{{body}}\nA below'});
layouts.set('b', {layout: 'c', content: 'B above\n{{body}}\nB below'});
layouts.set('c', {layout: 'd', content: 'C above\n{{body}}\nC below'});
layouts.set('d', {layout: 'e', content: 'D above\n{{body}}\nD below'});
layouts.set('e', {layout: 'f', content: 'E above\n{{body}}\nE below'});
layouts.set('f', {layout: 'last', content: 'F above\n{{body}}\nF below'});
layouts.set('last', {layout: undefined, content: 'last!\n{{body}}\nlast!'});
it('should extend the `cache` with the layout', function () {
var actual = layouts.stack('first');
var expected = [
'last!',
'F above',
'E above',
'D above',
'C above',
'B above',
'A above',
'I\'m a <%= title %>', // should not be compiled
'A below',
'B below',
'C below',
'D below',
'E below',
'F below',
'last!'
].join('\n');
actual.content.should.eql(expected);
});
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc