Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

handlebars-layouts

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

handlebars-layouts - npm Package Compare versions

Comparing version 0.3.3 to 1.0.0

CHANGELOG.md

4

bower.json
{
"name": "handlebars-layouts",
"version": "0.3.3",
"description": "Handlebars helpers which implement Jade-like layout blocks.",
"version": "1.0.0",
"description": "Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig.",
"main": "dist/handlebars-layouts.js",
"ignore": ["/*", "/*/", "!/dist/handlebars-layouts.js"]
}

@@ -1,88 +0,176 @@

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.handlebarsLayouts=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var getBlocks = function (context, name) {
var blocks = context._blocks;
return blocks[name] || (blocks[name] = []);
};
function noop() {
return '';
}
module.exports = function (handlebars) {
handlebars.registerHelper({
extend: function (partial, options) {
var context = Object.create(this);
var template = handlebars.partials[partial];
function getStack(context) {
return context._layoutStack || (context._layoutStack = []);
}
// Partial template required
if (template == null) {
throw new Error('Missing layout partial: \'' + partial + '\'');
}
function initActions(context) {
var stack = getStack(context),
actions = {};
// New block context
context._blocks = {};
context._layoutActions = actions;
// Parse blocks and discard output
options.fn(context);
while (stack.length) {
stack.pop()(context);
}
// Render final layout partial with revised blocks
if (typeof template !== 'function') {
template = handlebars.compile(template);
}
return actions;
}
// Compile, then render
return template(context);
},
function getActions(context) {
return context._layoutActions || initActions(context);
}
append: function (name, options) {
getBlocks(this, name).push({
should: 'append',
fn: options.fn
});
},
function getActionsByName(context, name) {
var actions = getActions(context);
prepend: function (name, options) {
getBlocks(this, name).push({
should: 'prepend',
fn: options.fn
});
},
return actions[name] || (actions[name] = []);
}
replace: function (name, options) {
getBlocks(this, name).push({
should: 'replace',
fn: options.fn
});
},
function applyAction(val, action) {
/* jshint validthis:true */
block: function (name, options) {
var block = null;
var retval = options.fn(this);
var blocks = getBlocks(this, name);
var length = blocks.length;
var i = 0;
switch (action.mode) {
case 'append': {
return val + action.fn(this);
}
for (; i < length; i++) {
block = blocks[i];
case 'prepend': {
return action.fn(this) + val;
}
switch (block && block.fn && block.should) {
case 'append':
retval = retval + block.fn(this);
break;
case 'replace': {
return action.fn(this);
}
case 'prepend':
retval = block.fn(this) + retval;
break;
default: {
return val;
}
}
}
case 'replace':
retval = block.fn(this);
break;
}
}
/**
* Registers layout helpers on an instance of Handlebars.
*
* @type {Function}
* @param {Object} handlebars Handlebars instance.
* @return {Object} Handlebars instance.
*/
function layouts(handlebars) {
var helpers = {
/**
* @method extend
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @return {String} Rendered partial.
*/
extend: function (name, options) {
options = options || {};
return retval;
}
});
var fn = options.fn || noop,
context = Object.create(this || {}),
template = handlebars.partials[name];
return handlebars;
};
// Partial template required
if (template == null) {
throw new Error('Missing partial: \'' + name + '\'');
}
},{}]},{},[1])
// Compile partial, if needed
if (typeof template !== 'function') {
template = handlebars.compile(template);
}
// Add overrides to stack
getStack(context).push(fn);
// Render partial
return template(context);
},
/**
* @method embed
* @return {String} Rendered partial.
*/
embed: function () {
var context = Object.create(this || {});
// Reset context
context._layoutStack = null;
context._layoutActions = null;
// Extend
return helpers.extend.apply(context, arguments);
},
/**
* @method block
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @return {String} Block content.
*/
block: function (name, options) {
options = options || {};
var fn = options.fn || noop,
context = this || {};
return getActionsByName(context, name).reduce(
applyAction.bind(context),
fn(context)
);
},
/**
* @method content
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @param {Object} options.hash
* @param {String} options.hash.mode
* @return {String} Always empty.
*/
content: function (name, options) {
options = options || {};
var fn = options.fn || noop,
hash = options.hash || {},
mode = hash.mode || 'replace',
context = this || {};
getActionsByName(context, name).push({
mode: mode.toLowerCase(),
fn: fn
});
return '';
}
};
handlebars.registerHelper(helpers);
return handlebars;
}
/**
* Assemble-compatible register method.
*
* @method register
* @param {Object} handlebars Handlebars instance.
* @return {Object} Handlebars instance.
* @static
*/
layouts.register = layouts;
// Legacy
module.exports = layouts;
},{}]},{},[1])(1)
});
'use strict';
var gulp = require('gulp');
var pkg = require('./package.json');
var gulp = require('gulp'),
pkg = require('./package.json'),
paths = {
dest: './dist',
gulp: './gulpfile.js',
src: './index.js',
test: './test/*.{e2e,spec}.js'
};
var paths = {
dest: './dist',
gulp: './gulpfile.js',
src: './index.js',
test: './test/**/*Spec.js'
};
gulp.task('default', ['build']);
gulp.task('lint', function () {
var jscs = require('gulp-jscs');
var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs'),
jshint = require('gulp-jshint');
return gulp
.src([paths.gulp, paths.src, paths.test])
.pipe(jscs())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
return gulp
.src([paths.gulp, paths.src, paths.test])
.pipe(jscs())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
});
gulp.task('cover', function () {
var istanbul = require('gulp-istanbul');
var istanbul = require('gulp-istanbul');
return gulp
.src(paths.src)
.pipe(istanbul());
return gulp
.src(paths.src)
.pipe(istanbul());
});
gulp.task('test', ['cover'], function () {
var istanbul = require('gulp-istanbul');
var jasmine = require('gulp-jasmine');
gulp.task('test', ['lint', 'cover'], function () {
var istanbul = require('gulp-istanbul'),
mocha = require('gulp-mocha');
return gulp
.src(paths.test)
.pipe(jasmine({ verbose: true }))
.pipe(istanbul.writeReports());
return gulp
.src(paths.test)
.pipe(mocha({ reporter: 'spec' }))
.pipe(istanbul.writeReports());
});
gulp.task('build', ['lint', 'test'], function () {
var browserify = require('browserify');
var source = require('vinyl-source-stream');
gulp.task('build', ['test'], function () {
var browserify = require('browserify'),
source = require('vinyl-source-stream'),
options = { standalone: 'handlebars-layouts' };
return browserify(paths.src)
.bundle()
.pipe(source(pkg.name + '.js'))
.pipe(gulp.dest(paths.dest));
return browserify(paths.src, options)
.bundle()
.pipe(source(pkg.name + '.js'))
.pipe(gulp.dest(paths.dest));
});
'use strict';
var getBlocks = function (context, name) {
var blocks = context._blocks;
return blocks[name] || (blocks[name] = []);
};
function noop() {
return '';
}
var layouts = function (handlebars) {
handlebars.registerHelper({
extend: function (partial, options) {
var context = Object.create(this);
var template = handlebars.partials[partial];
function getStack(context) {
return context._layoutStack || (context._layoutStack = []);
}
// Partial template required
if (template == null) {
throw new Error('Missing layout partial: \'' + partial + '\'');
}
function initActions(context) {
var stack = getStack(context),
actions = {};
// New block context
context._blocks = {};
context._layoutActions = actions;
// Parse blocks and discard output
options.fn(context);
while (stack.length) {
stack.pop()(context);
}
// Render final layout partial with revised blocks
if (typeof template !== 'function') {
template = handlebars.compile(template);
}
return actions;
}
// Compile, then render
return template(context);
},
function getActions(context) {
return context._layoutActions || initActions(context);
}
append: function (name, options) {
getBlocks(this, name).push({
should: 'append',
fn: options.fn
});
},
function getActionsByName(context, name) {
var actions = getActions(context);
prepend: function (name, options) {
getBlocks(this, name).push({
should: 'prepend',
fn: options.fn
});
},
return actions[name] || (actions[name] = []);
}
replace: function (name, options) {
getBlocks(this, name).push({
should: 'replace',
fn: options.fn
});
},
function applyAction(val, action) {
/* jshint validthis:true */
block: function (name, options) {
var block = null;
var retval = options.fn(this);
var blocks = getBlocks(this, name);
var length = blocks.length;
var i = 0;
switch (action.mode) {
case 'append': {
return val + action.fn(this);
}
for (; i < length; i++) {
block = blocks[i];
case 'prepend': {
return action.fn(this) + val;
}
switch (block && block.fn && block.should) {
case 'append':
retval = retval + block.fn(this);
break;
case 'replace': {
return action.fn(this);
}
case 'prepend':
retval = block.fn(this) + retval;
break;
default: {
return val;
}
}
}
case 'replace':
retval = block.fn(this);
break;
}
}
/**
* Registers layout helpers on an instance of Handlebars.
*
* @type {Function}
* @param {Object} handlebars Handlebars instance.
* @return {Object} Handlebars instance.
*/
function layouts(handlebars) {
var helpers = {
/**
* @method extend
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @return {String} Rendered partial.
*/
extend: function (name, options) {
options = options || {};
return retval;
}
});
var fn = options.fn || noop,
context = Object.create(this || {}),
template = handlebars.partials[name];
return handlebars;
};
// Partial template required
if (template == null) {
throw new Error('Missing partial: \'' + name + '\'');
}
// Assemble
// Compile partial, if needed
if (typeof template !== 'function') {
template = handlebars.compile(template);
}
// Add overrides to stack
getStack(context).push(fn);
// Render partial
return template(context);
},
/**
* @method embed
* @return {String} Rendered partial.
*/
embed: function () {
var context = Object.create(this || {});
// Reset context
context._layoutStack = null;
context._layoutActions = null;
// Extend
return helpers.extend.apply(context, arguments);
},
/**
* @method block
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @return {String} Block content.
*/
block: function (name, options) {
options = options || {};
var fn = options.fn || noop,
context = this || {};
return getActionsByName(context, name).reduce(
applyAction.bind(context),
fn(context)
);
},
/**
* @method content
* @param {String} name
* @param {Object} options
* @param {Function(Object)} options.fn
* @param {Object} options.hash
* @param {String} options.hash.mode
* @return {String} Always empty.
*/
content: function (name, options) {
options = options || {};
var fn = options.fn || noop,
hash = options.hash || {},
mode = hash.mode || 'replace',
context = this || {};
getActionsByName(context, name).push({
mode: mode.toLowerCase(),
fn: fn
});
return '';
}
};
handlebars.registerHelper(helpers);
return handlebars;
}
/**
* Assemble-compatible register method.
*
* @method register
* @param {Object} handlebars Handlebars instance.
* @return {Object} Handlebars instance.
* @static
*/
layouts.register = layouts;

@@ -89,0 +170,0 @@

{
"name": "handlebars-layouts",
"version": "0.3.3",
"description": "Handlebars helpers which implement Jade-like layout blocks.",
"version": "1.0.0",
"description": "Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig.",
"keywords": [

@@ -10,6 +10,9 @@ "blocks",

"handlebars",
"hbs",
"jade",
"layout",
"mote",
"mustache"
"mustache",
"swig",
"twig"
],

@@ -30,13 +33,19 @@ "homepage": "https://github.com/shannonmoeller/handlebars-layouts",

"devDependencies": {
"coveralls": "^2.6.1",
"gulp": "^3.6.0",
"gulp-istanbul": "^0.1.1",
"gulp-jasmine": "^0.2.0",
"gulp-jscs": "^0.4.1",
"gulp-jshint": "^1.5.1",
"gulp-watch": "^0.5.3",
"browserify": "^6.1.0",
"coveralls": "^2.11.2",
"expect.js": "^0.3.1",
"express": "^4.9.8",
"gulp": "^3.8.9",
"gulp-istanbul": "^0.3.1",
"gulp-jscs": "^1.2.1",
"gulp-jshint": "^1.8.5",
"gulp-mocha": "^1.1.1",
"gulp-prettify": "^0.3.0",
"handlebars": "~2.0",
"jshint-stylish": "^0.1.5",
"vinyl-source-stream": "^0.1.1",
"browserify": "^3.44.1"
"hbs": "^2.7.0",
"hbs-utils": "0.0.3",
"jshint-stylish": "^1.0.0",
"map-stream": "^0.1.0",
"vinyl-fs": "^0.3.10",
"vinyl-source-stream": "^1.0.0"
},

@@ -43,0 +52,0 @@ "engines": {

@@ -1,9 +0,6 @@

# Handlebars Layouts
# `handlebars-layouts`
> Handlebars helpers which implement Jade-like layout blocks.
> Handlebars helpers which implement layout blocks similar to Jade, Jinja, Swig, and Twig.
[![NPM version](https://badge.fury.io/js/handlebars-layouts.png)](http://badge.fury.io/js/handlebars-layouts)
[![Build Status](https://travis-ci.org/shannonmoeller/handlebars-layouts.png?branch=master)](https://travis-ci.org/shannonmoeller/handlebars-layouts)
[![Coverage Status](https://coveralls.io/repos/shannonmoeller/handlebars-layouts/badge.png?branch=master)](https://coveralls.io/r/shannonmoeller/handlebars-layouts?branch=master)
[![Dependency Status](https://david-dm.org/shannonmoeller/handlebars-layouts.png?theme=shields.io)](https://david-dm.org/shannonmoeller/handlebars-layouts)
[![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url]

@@ -18,8 +15,168 @@ ## Install

$ bower install handlebars-layouts
$ bower install shannonmoeller/handlebars-layouts
With [Component](http://component.io):
## Helpers
$ component install shannonmoeller/handlebars-layouts
### `{{#extend [partial]}}`
- `partial` `String` - Name of partial to render.
Loads a layout partial of a given name and defines block content.
```html
{{#extend "layout"}}
{{#content "title" mode="prepend"}}Example - {{/content}}
{{/extend}}
```
### `{{#embed [partial]}}`
- `partial` `String` - Name of partial to render.
Allows you to load a partial which itself extends from a layout. Blocks defined in embedded partials will not conflict with those in the primary layout.
```html
{{#extend "layout"}}
{{#content "body"}}
{{#embed "gallery"}}
{{#content "body"}}
<img src="1.png" alt="" />
<img src="2.png" alt="" />
{{/content}}
{{/embed}}
{{#embed "modal"}}
{{#content "title" mode="prepend"}}Image 1 - {{/content}}
{{#content "body"}}<img src="1.png" alt="" />{{/content}}
{{/embed}}
{{/content}}
{{/extend}}
```
### `{{#block [name]}}`
- `name` `String` - Block identifier.
Defines a named block, with optional default content. Blocks may have content appended, prepended, or replaced entirely when extending or embedding. You may append and prepend to the same block multiple times.
```html
{{#block "header"}}
<h1>Hello World</h1>
{{/block}}
{{#block "main"}}
<p>Lorem ipsum...</p>
{{/block}}
{{#block "footer"}}
<p>&copy; 1970</p>
{{/block}}
```
### `{{#content [name] mode="(append|prepend|replace)"}}`
- `name` `String` - Identifier of the block to modify.
- `mode` `String` _(Optional)_ - Means of providing block content. Default: `replace`.
Sets block content, optionally appending or prepending using the `mode` attribute.
Layout:
```html
<html>
...
<body>
{{#block "header"}}
<h1>Hello World</h1>
{{/block}}
{{#block "main"}}
<p>Lorem ipsum.</p>
{{/block}}
{{#block "footer"}}
<p>&copy; 1999</p>
{{/block}}
</body>
</html>
```
Page:
```html
{{#extend "layout"}}
{{#content "header"}}
<h1>Goodnight Moon</h1>
{{/content}}
{{#content "main" mode="append"}}
<p>Dolor sit amet.</p>
{{/content}}
{{#content "footer" mode="prepend"}}
<p>MIT License</p>
{{/content}}
{{/extend}}
```
Output:
```html
<html>
...
<body>
<h1>Goodnight Moon</h1>
<p>Lorem ipsum.</p>
<p>Dolor sit amet.</p>
<p>MIT License</p>
<p>&copy; 1999</p>
</body>
</html>
```
## Api
Helpers are registered by passing in your instance of Handlebars. This allows
you to selectively register the helpers on various instances of Handlebars.
### `layouts(handlebars)`
- `handlebars` `Handlebars` - An instance of Handlebars.
```js
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts(handlebars);
```
### `layouts.register(handlebars)`
- `handlebars` `Handlebars` - An instance of Handlebars.
Helpers are also exposed via a `register` method for use with [Assemble](http://assemble.io/).
```js
var handlebars = require('handlebars'),
layouts = require('handlebars-layouts');
layouts.register(handlebars);
// or
grunt.initConfig({
assemble: {
options: {
helpers: ['path/to/handlebars-layouts.js']
}
}
});
```
## Example

@@ -71,7 +228,7 @@

{{#extend "layout"}}
{{#append "head"}}
{{#content "head" mode="append"}}
<link rel="stylesheet" href="assets/css/home.css" />
{{/append}}
{{/content}}
{{#replace "body"}}
{{#content "body"}}
<h2>Welcome Home</h2>

@@ -84,7 +241,7 @@

</ul>
{{/replace}}
{{/content}}
{{#prepend "foot"}}
{{#content "foot" mode="prepend"}}
<script src="assets/js/analytics.js"></script>
{{/prepend}}
{{/content}}
{{/extend}}

@@ -106,3 +263,3 @@ ```

// Compile template
var template = Handlebars.compile(fs.readFileSync('template.html', 'uft8'));
var template = Handlebars.compile(fs.readFileSync('template.html', 'utf8'));

@@ -161,6 +318,28 @@ // Render template

$ npm test
```sh
$ npm test
```
## Contribute
[![Tasks][waffle-img]][waffle-url] [![Chat][gitter-img]][gitter-url] [![Tip][gittip-img]][gittip-url]
Standards for this project, including tests, code coverage, and semantics are enforced with a build tool. Pull requests must include passing tests with 100% code coverage and no linting errors.
## License
MIT
[coveralls-img]: http://img.shields.io/coveralls/shannonmoeller/handlebars-layouts/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/shannonmoeller/handlebars-layouts
[downloads-img]: http://img.shields.io/npm/dm/handlebars-layouts.svg?style=flat-square
[gitter-img]: http://img.shields.io/badge/chat-shannonmoeller/handlebars--layouts-blue.svg?style=flat-square
[gitter-url]: https://gitter.im/shannonmoeller/handlebars-layouts
[gittip-img]: http://img.shields.io/gittip/shannonmoeller.svg?style=flat-square
[gittip-url]: https://www.gittip.com/shannonmoeller
[npm-img]: http://img.shields.io/npm/v/handlebars-layouts.svg?style=flat-square
[npm-url]: https://npmjs.org/package/handlebars-layouts
[travis-img]: http://img.shields.io/travis/shannonmoeller/handlebars-layouts.svg?style=flat-square
[travis-url]: https://travis-ci.org/shannonmoeller/handlebars-layouts
[waffle-img]: http://img.shields.io/github/issues/shannonmoeller/handlebars-layouts.svg?style=flat-square
[waffle-url]: http://waffle.io/shannonmoeller/handlebars-layouts
{
"title": "Layout Test",
"items": [
"apple",
"orange",
"banana"
],
"alt1": "description 1",
"alt2": "description 2",
"alt3": "description 3"
"title": "Layout Test",
"items": [
"apple",
"orange",
"banana"
],
"alt1": "description 1",
"alt2": "description 2",
"alt3": "description 3"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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