Huge News!Announcing our $40M Series B led by Abstract Ventures.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.9.0 to 0.10.0

130

index.js
'use strict';
var isFalsey = require('falsey');
var Buffer = require('buffer').Buffer;
var delims = require('delimiter-regex');

@@ -11,61 +12,90 @@ var get = require('get-value');

module.exports = layouts;
module.exports = renderLayouts;
/**
* Wrap a string one or more layouts.
* Cache compiled delimiter regex.
*
* @param {String} `str` The content string to be wrapped with a layout.
* @param {String} `key` The object key of the starting layout.
* @param {Object} `templates` Object of layouts.
* @param {Object} `options`
* @option {Object} [options] `layoutDelims` Custom delimiters to use.
* @option {Object} [options] `defaultLayout` The name (key) of the default layout to use.
* @return {String} String wrapped with a layout or layouts.
* If delimiters need to be generated, this ensures that
* runtime compilation only happens once.
*/
var cache = {};
/**
* Wrap one or more layouts around `string`.
*
* ```js
* renderLayouts(string, layoutName, layoutStack, options, fn);
* ```
*
* @param {String} `string` The string to wrap with a layout.
* @param {String} `layoutName` The name (key) of the layout object to use.
* @param {Object} `layoutStack` Object of layout objects.
* @param {Object} `options` Optionally define a `defaultLayout` (string), pass custom delimiters (`layoutDelims`) to use as the placeholder for the content insertion point, or change the name of the placeholder tag with the `tag` option.
* @param {Function} `fn` Optionally pass a function to modify the context as each layout is applied.
* @return {String} Returns the original string wrapped with one or more layouts.
* @api public
*/
function layouts(str, key, templates, opts, fn) {
function renderLayouts(str, name, layoutStack, opts, fn) {
if (isBuffer(str)) {
str = str.toString();
}
if (typeof str !== 'string') {
throw new TypeError('layouts expects a string');
throw new TypeError('layouts expects a string.');
}
if (typeof opts === 'function') {
fn = opts; opts = {};
fn = opts;
opts = {};
}
opts = opts || {};
var template = {}, prev, i = 0;
var res = {options: {}, stack: []};
var layout = {};
var depth = 0;
var prev;
while (key && (prev !== key) && (template = templates[key])) {
// `view` is the object we'll use to store the result
var view = {options: {}, history: []};
// recursively resolve layouts
while (name && (prev !== name) && (layout = layoutStack[name])) {
var delims = opts.layoutDelims;
// `context` is passed to `interpolate` to resolve templates
// to the values on the context object.
var context = {};
context[opts.tag || 'body'] = str;
// `data` is passed to `wrapLayout` to resolve layouts
// to the values on the data object.
var data = {};
data[opts.tag || 'body'] = str;
// get the context for the layout and push it onto `stack`
// get info about the current layout
var obj = {};
obj.layout = template;
obj.layout.key = key;
obj.layout = layout;
obj.layout.name = name;
obj.before = str;
obj.depth = i++;
obj.depth = depth++;
str = interpolate(template.content, context, delims);
// inject the string into the layout
str = wrapLayout(layout.content, data, delims);
obj.after = str;
// if a (sync) callback is passed, allow it modify
// the result in place
if (typeof fn === 'function') {
fn(obj, res, i);
fn(obj, view, depth);
}
res.stack.push(obj);
prev = key;
key = assertLayout(template.layout, opts.defaultLayout);
// push info about the layout onto `history`
view.history.push(obj);
prev = name;
// should we recurse again?
// (does the `layout` itself specify another layout?)
name = assertLayout(layout.layout, opts.defaultLayout);
}
res.options = opts;
res.result = str;
return res;
};
view.options = opts;
view.result = str;
return view;
}

@@ -95,22 +125,13 @@ /**

/**
* Cache compiled regexps to prevent runtime
* compilation for the same delimiter strings
* multiple times (this trick can be used for
* any compiled regex)
*/
var cache = {};
/**
* Resolve template strings to the values on the given
* `context` object.
* `data` object.
*/
function interpolate(content, context, syntax) {
function wrapLayout(content, data, syntax) {
var re = makeDelimiterRegex(syntax);
return toString(content).replace(re, function(_, $1) {
if ($1.indexOf('.') !== -1) {
return toString(get(context, $1.trim()));
return toString(content).replace(re, function(_, tagName) {
if (tagName.indexOf('.') !== -1) {
return toString(get(data, tagName.trim()));
}
return context[$1.trim()];
return data[tagName.trim()];
});

@@ -131,9 +152,9 @@ }

}
var name = syntax + '';
if (cache.hasOwnProperty(name)) {
return cache[name];
}
if (typeof syntax === 'string') {
return new RegExp(syntax, 'g');
}
var key = syntax.toString();
if (cache.hasOwnProperty(key)) {
return cache[key];
}
if (Array.isArray(syntax)) {

@@ -148,4 +169,9 @@ return (cache[syntax] = delims(syntax));

function toString(val){
function toString(val) {
return val == null ? '' : val.toString();
}
function isBuffer(val) {
return typeof val === 'object'
&& val instanceof Buffer;
}

50

package.json
{
"name": "layouts",
"description": "Wrap templates with layouts. Layouts can be nested and optionally use other layouts.",
"version": "0.9.0",
"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.",
"version": "0.10.0",
"homepage": "https://github.com/doowb/layouts",
"author": {
"name": "Brian Woodward",
"url": "https://github.com/doowb"
},
"repository": {
"type": "git",
"url": "git://github.com/doowb/layouts.git"
},
"author": "Brian Woodward (https://github.com/doowb)",
"repository": "doowb/layouts",
"bugs": {
"url": "https://github.com/doowb/layouts/issues"
},
"license": {
"type": "MIT",
"url": "https://github.com/doowb/layouts/blob/master/LICENSE"
},
"contributors": [
"Jon Schlinkert, (https://github.com/jonschlinkert)"
],
"license": "MIT",
"files": [

@@ -32,13 +26,14 @@ "index.js"

"dependencies": {
"delimiter-regex": "^1.3.0",
"delimiter-regex": "^1.3.1",
"falsey": "^0.2.1",
"get-value": "^1.0.4"
"get-value": "^1.1.5"
},
"devDependencies": {
"lodash": "^3.5.0",
"mocha": "^2.2.0",
"should": "^5.1.0"
"lodash": "^3.10.0",
"mocha": "^2.2.5",
"should": "^7.0.2"
},
"keywords": [
"atpl",
"coffee",
"consolidate",

@@ -53,6 +48,8 @@ "dot",

"express",
"haml",
"haml-coffee",
"hamljs",
"handlebars",
"hogan.js",
"hogan",
"hogan-js",
"jade",

@@ -86,3 +83,14 @@ "jazz",

"wrap"
]
],
"verb": {
"related": {
"list": [
"template",
"assemble",
"verb",
"handlebars-helpers",
"template-helpers"
]
}
}
}

@@ -1,9 +0,11 @@

# 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)
# 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)
> Wrap templates with layouts. Layouts can be nested and optionally use other layouts.
> 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.
## Install with [npm](npmjs.org)
## Install
```bash
npm i layouts --save
Install with [npm](https://www.npmjs.com/)
```sh
$ npm i layouts --save
```

@@ -14,15 +16,22 @@

```js
var layouts = require('layouts');
var renderLayouts = require('layouts');
```
## Usage
## Examples
**Basic example**
In this example, two layouts are used:
* the first layout, `one`, will wrap the string
* the second layout, `two`, will wrap the first layout
```js
var stack = {
foo: {content: 'foo above\n{% body %}\nfoo below', layout: 'bar'},
bar: {content: 'bar above\n{% body %}\nbar below', layout: 'baz'},
baz: {content: 'baz above\n{% body %}\nbaz below'},
var layouts = {
one: {content: 'one before\n{% body %}\none after', layout: 'two'},
two: {content: 'two before\n{% body %}\ntwo after'},
};
layouts('<div>This is content</div>', 'foo', stack);
// `one` is the name of the first layout to use on the provided string
renderLayouts('<div>Wrap me with a layout!!!</div>', 'one', layouts);
```

@@ -33,43 +42,118 @@

```html
baz above
bar above
foo above
<div>This is content</div>
foo below
bar below
baz below
two before
one before
<div>Wrap me with a layout!!!</div>
one after
two after
```
**HTML**
This example shows how to use nested HTML layouts to wrap content:
```js
var layouts = {};
layouts.base = {
content: [
'<!DOCTYPE html>',
'<html lang="en">',
' <head>',
' <meta charset="UTF-8">',
' <title>Home</title>',
' </head>',
' <body>',
' {% body %}',
' </body>',
'</html>',
].join('\n')
};
// this `nav` layout will be wrapped with the `base` layout
layouts.nav = {
layout: 'base',
content: '<nav>\n{% body %}\n</nav>'
};
// this string will be wrapped with the `nav` layout
var str = [
'<ul class="categories">',
' <li class="active"> <a href="#"> Development </a> </li>',
' <li> <a href="#"> Design </a> </li>',
' <li> <a href="#"> Node.js </a> </li>',
'</ul>'
].join('\n')
// `nav` is the name of the layout to use
renderLayouts(str, nav, layouts);
```
Results in something like:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<nav>
<ul class="categories">
<li class="active"> <a href="#"> Development </a> </li>
<li> <a href="#"> Design </a> </li>
<li> <a href="#"> Node.js </a> </li>
</ul>
</nav>
</body>
</html>
```
## Customization
By default, `{% body %}` is used as the placeholder (insertion point) for content, but this can easily be customized with the following options:
* `layoutDelims`: the delimiters to use. This can be a regex, like `/\{{([^}]+)\}}/`, or an array of delimiter strings, like `['{{', '}}']`
* `tag`: the name of the placeholder tag.
## API
### [layouts](./index.js#L26)
* `str` **{String}**: The content string to be wrapped with a layout.
* `key` **{String}**: The object key of the starting layout.
* `templates` **{Object}**: Object of layouts.
* `options` **{Object}**
- `layoutDelims` **{Object}**: Custom delimiters to use.
- `defaultLayout` **{Object}**: The name (key) of the default layout to use.
* `returns` **{String}**: String wrapped with a layout or layouts.
### [renderLayouts](index.js#L39)
Wrap a string one or more layouts.
Wrap one or more layouts around `string`.
**Params**
* `string` **{String}**: The string to wrap with a layout.
* `layoutName` **{String}**: The name (key) of the layout object to use.
* `layoutStack` **{Object}**: Object of layout objects.
* `options` **{Object}**: Optionally define a `defaultLayout` (string), pass custom delimiters (`layoutDelims`) to use as the placeholder for the content insertion point, or change the name of the placeholder tag with the `tag` option.
* `fn` **{Function}**: Optionally pass a function to modify the context as each layout is applied.
* `returns` **{String}**: Returns the original string wrapped with one or more layouts.
**Example**
```js
renderLayouts(string, layoutName, layoutStack, options, fn);
```
## Related
* [template](https://github.com/jonschlinkert/template): Render templates from any engine. Make custom template types, use layouts on pages, partials or any custom template type, custom delimiters, helpers, middleware, routes, loaders, and lots more. Powers Assemble v0.6.0, Verb v0.3.0 and your application.
* [assemble](http://assemble.io): Static site generator for Grunt.js, Yeoman and Node.js. Used by Zurb Foundation, Zurb Ink, H5BP/Effeckt, Less.js / lesscss.org, Topcoat, Web Experience Toolkit, and hundreds of other projects to build sites, themes, components, documentation, blogs and gh
* [verb](https://github.com/assemble/verb): Verb makes it dead simple to generate markdown documentation, using simple templates, with zero configuration required. A project without documentation is like a project that doesn't exist.
* [handlebars-helpers](https://github.com/assemble/handlebars-helpers): 120+ Handlebars helpers in ~20 categories, for Assemble, YUI, Ghost or any Handlebars project. Includes helpers like {{i18}}, {{markdown}}, {{relative}}, {{extend}}, {{moment}}, and so on.
* [template-helpers](https://github.com/jonschlinkert/template-helpers): Generic JavaScript helpers that can be used with any template engine. Handlebars, Lo-Dash, Underscore, or any engine that supports helper functions.
* [assemble](http://assemble.io): Static site generator for Grunt.js, Yeoman and Node.js. Used by Zurb Foundation, Zurb Ink, H5BP/Effeckt,… [more](http://assemble.io)
* [handlebars-helpers](https://github.com/assemble/handlebars-helpers): 120+ Handlebars helpers in ~20 categories, for Assemble, YUI, Ghost or any Handlebars project. Includes… [more](https://github.com/assemble/handlebars-helpers)
* [template](https://github.com/jonschlinkert/template): Render templates using any engine. Supports, layouts, pages, partials and custom template types. Use template… [more](https://github.com/jonschlinkert/template)
* [template-helpers](https://github.com/jonschlinkert/template-helpers): Generic JavaScript helpers that can be used with any template engine. Handlebars, Lo-Dash, Underscore, or… [more](https://github.com/jonschlinkert/template-helpers)
* [verb](https://github.com/assemble/verb): Documentation generator for GitHub projects. Extremely powerful, easy to use, can generate anything from API… [more](https://github.com/assemble/verb)
## Running tests
Install dev dependencies.
```bash
npm i -d && npm test
Install dev dependencies:
```sh
$ npm i -d && npm test
```
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/doowb/layouts/issues)
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/doowb/layouts/issues/new)

@@ -79,12 +163,13 @@ ## Author

**Brian Woodward**
+ [github/doowb](https://github.com/doowb)
+ [twitter/doowb](http://twitter.com/doowb)
+ [twitter/doowb](http://twitter.com/doowb)
## License
Copyright (c) 2014-2015 Brian Woodward
Released under the MIT license
Copyright © 2014-2015 [Brian Woodward](https://github.com/doowb)
Released under the MIT license.
***
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 09, 2015._
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on July 17, 2015._
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