handlebars-layouts
Advanced tools
Comparing version 0.3.3 to 1.0.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.", | ||
"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)); | ||
}); |
217
index.js
'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": { |
213
README.md
@@ -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>© 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>© 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>© 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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
35141
32
490
0
341
17
1