grunt-bake
Advanced tools
Comparing version 0.3.18 to 1.0.0
@@ -123,2 +123,12 @@ /* | ||
inline_recursive_bake: { | ||
options: { | ||
content: "test/fixtures/content.json" | ||
}, | ||
files: { | ||
"tmp/inline_recursive_bake.html": "test/fixtures/inline_recursive_bake.html" | ||
} | ||
}, | ||
inline_bake: { | ||
@@ -190,2 +200,15 @@ options: { | ||
foreach_meta: { | ||
options: { | ||
transforms: { | ||
visibleBool: function(state) { | ||
return state ? 'is true' : 'is false'; | ||
} | ||
} | ||
}, | ||
files: { | ||
"tmp/foreach_meta.html": "test/fixtures/foreach_meta.html" | ||
} | ||
}, | ||
no_process_bake: { | ||
@@ -335,2 +358,8 @@ options: { | ||
}, | ||
multiline_bake: { | ||
files: { | ||
"tmp/multiline_bake.html": "test/fixtures/multiline_bake.html" | ||
} | ||
} | ||
} | ||
@@ -337,0 +366,0 @@ |
{ | ||
"name": "grunt-bake", | ||
"description": "Bake external includes into files to create static pages with no server-side compilation time", | ||
"version": "0.3.18", | ||
"version": "1.0.0", | ||
"homepage": "https://github.com/MathiasPaumgarten/grunt-bake", | ||
@@ -14,3 +14,3 @@ "author": { | ||
"name": "David Zacharias", | ||
"url": "https://github.com/david-zacharias" | ||
"email": "zacharias@werk85.de" | ||
}, | ||
@@ -17,0 +17,0 @@ { |
375
README.md
@@ -41,18 +41,18 @@ # grunt-bake | ||
grunt.initConfig( { | ||
bake: { | ||
your_target: { | ||
options: { | ||
// Task-specific options go here. | ||
}, | ||
bake: { | ||
your_target: { | ||
options: { | ||
// Task-specific options go here. | ||
}, | ||
files: { | ||
// files go here, like so: | ||
files: { | ||
// files go here, like so: | ||
"dist/index.html": "app/index.html", | ||
"dist/mobile.html": "app/mobile.html" | ||
"dist/index.html": "app/index.html", | ||
"dist/mobile.html": "app/mobile.html" | ||
// etc ... | ||
} | ||
}, | ||
}, | ||
// etc ... | ||
} | ||
}, | ||
}, | ||
} ) | ||
@@ -65,7 +65,7 @@ ``` | ||
<html> | ||
<head></head> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
<!--(bake includes/footer.html)--> | ||
</body> | ||
<head></head> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
<!--(bake includes/footer.html)--> | ||
</body> | ||
</html> | ||
@@ -94,19 +94,19 @@ ``` | ||
{ | ||
"en": { | ||
"title": "Book", | ||
"en": { | ||
"title": "Book", | ||
"info": { | ||
"author": "Joe Do", | ||
"job": "Writer" | ||
} | ||
}, | ||
"info": { | ||
"author": "Joe Do", | ||
"job": "Writer" | ||
} | ||
}, | ||
"de": { | ||
"title": "Buch", | ||
"de": { | ||
"title": "Buch", | ||
"info": { | ||
"author": "Joe Do", | ||
"job": "Schreiber" | ||
} | ||
} | ||
"info": { | ||
"author": "Joe Do", | ||
"job": "Schreiber" | ||
} | ||
} | ||
} | ||
@@ -122,4 +122,4 @@ ``` | ||
<div> | ||
<span>{{info.author}}</span> | ||
<span>{{info.job}}</span> | ||
<span>{{info.author}}</span> | ||
<span>{{info.job}}</span> | ||
</div> | ||
@@ -164,8 +164,8 @@ ``` | ||
transforms: { | ||
upper: function(str) { | ||
return String(str).toUpperCase(); | ||
}, | ||
nl2br: function(str) { | ||
// ... | ||
} | ||
upper: function(str) { | ||
return String(str).toUpperCase(); | ||
}, | ||
nl2br: function(str) { | ||
// ... | ||
} | ||
} | ||
@@ -194,9 +194,9 @@ ``` | ||
grunt.initConfig( { | ||
bake: { | ||
build: { | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
bake: { | ||
build: { | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
} ) | ||
@@ -207,5 +207,5 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
</body> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
</body> | ||
</html> | ||
@@ -222,5 +222,5 @@ ``` | ||
<html> | ||
<body> | ||
<div id="container"></div> | ||
</body> | ||
<body> | ||
<div id="container"></div> | ||
</body> | ||
</html> | ||
@@ -235,14 +235,14 @@ ``` | ||
grunt.initConfig( { | ||
bake: { | ||
build: { | ||
options: { | ||
content: "app/content.json", | ||
section: "en" | ||
} | ||
bake: { | ||
build: { | ||
options: { | ||
content: "app/content.json", | ||
section: "en" | ||
} | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
} ) | ||
@@ -255,9 +255,9 @@ ``` | ||
{ | ||
"en": { | ||
"title": "Hello World" | ||
}, | ||
"en": { | ||
"title": "Hello World" | ||
}, | ||
"de": { | ||
"title": "Hallo Welt" | ||
} | ||
"de": { | ||
"title": "Hallo Welt" | ||
} | ||
} | ||
@@ -269,5 +269,5 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
</body> | ||
<body> | ||
<!--(bake includes/container.html)--> | ||
</body> | ||
</html> | ||
@@ -284,5 +284,5 @@ ``` | ||
<html> | ||
<body> | ||
<div id="container">Hello World</div> | ||
</body> | ||
<body> | ||
<div id="container">Hello World</div> | ||
</body> | ||
</html> | ||
@@ -301,5 +301,5 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake includes/container.html title="Salut Monde" name="Mathias")--> | ||
</body> | ||
<body> | ||
<!--(bake includes/container.html title="Salut Monde" name="Mathias")--> | ||
</body> | ||
</html> | ||
@@ -317,6 +317,6 @@ ``` | ||
<html> | ||
<body> | ||
<div id="container">Salut monde</div> | ||
<span>Mathias</span> | ||
</body> | ||
<body> | ||
<div id="container">Salut monde</div> | ||
<span>Mathias</span> | ||
</body> | ||
</html> | ||
@@ -336,7 +336,7 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake includes/container.html _if="name")--> | ||
<body> | ||
<!--(bake includes/container.html _if="name")--> | ||
<!--(bake includes/other.html _if="foo == 'bar'")--> | ||
</body> | ||
<!--(bake includes/other.html _if="foo == 'bar'")--> | ||
</body> | ||
</html> | ||
@@ -354,3 +354,3 @@ ``` | ||
{ | ||
"foo": "bar" | ||
"foo": "bar" | ||
} | ||
@@ -362,6 +362,6 @@ ``` | ||
<html> | ||
<body> | ||
<body> | ||
<span>bar</span> | ||
</body> | ||
<span>bar</span> | ||
</body> | ||
</html> | ||
@@ -374,7 +374,7 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake-start _if="name")--> | ||
<h1>{{name}}</h1> | ||
<!--(bake-end)--> | ||
</body> | ||
<body> | ||
<!--(bake-start _if="name")--> | ||
<h1>{{name}}</h1> | ||
<!--(bake-end)--> | ||
</body> | ||
</html> | ||
@@ -392,11 +392,11 @@ ``` | ||
<html> | ||
<body> | ||
<ul class="first"> | ||
<!--(bake includes/li.html _foreach="name:[mike, drew, steve]")--> | ||
</ul> | ||
<body> | ||
<ul class="first"> | ||
<!--(bake includes/li.html _foreach="name:[mike, drew, steve]")--> | ||
</ul> | ||
<ul class="second"> | ||
<!--(bake includes/li.html _foreach="name:authors.names")--> | ||
</ul> | ||
</body> | ||
<ul class="second"> | ||
<!--(bake includes/li.html _foreach="name:authors.names")--> | ||
</ul> | ||
</body> | ||
</html> | ||
@@ -413,5 +413,5 @@ ``` | ||
{ | ||
"authors": { | ||
"names": [ "jenna", "carla", "susy" ] | ||
} | ||
"authors": { | ||
"names": [ "jenna", "carla", "susy" ] | ||
} | ||
} | ||
@@ -423,15 +423,15 @@ ``` | ||
<html> | ||
<body> | ||
<ul class="first"> | ||
<li>mike</li> | ||
<li>drew</li> | ||
<li>steve</li> | ||
</ul> | ||
<body> | ||
<ul class="first"> | ||
<li>mike</li> | ||
<li>drew</li> | ||
<li>steve</li> | ||
</ul> | ||
<ul class="second"> | ||
<li>jenna</li> | ||
<li>carla</li> | ||
<li>susy</li> | ||
</ul> | ||
</body> | ||
<ul class="second"> | ||
<li>jenna</li> | ||
<li>carla</li> | ||
<li>susy</li> | ||
</ul> | ||
</body> | ||
</html> | ||
@@ -444,13 +444,40 @@ ``` | ||
<html> | ||
<body> | ||
<ul> | ||
<!--(bake-start _foreach="name:[robert, susan, carl]")--> | ||
<li>{{name}}</li> | ||
<!--(bake-end)--> | ||
</ul> | ||
</body> | ||
<body> | ||
<ul> | ||
<!--(bake-start _foreach="name:[robert, susan, carl]")--> | ||
<li>{{name}}</li> | ||
<!--(bake-end)--> | ||
</ul> | ||
</body> | ||
</html> | ||
``` | ||
Bake automatically supplies meta information for each loop, like current index. Values can be accessed by the defined key followed by `@index`, `@iteration`, `@first`, `@last`, or `@total`. | ||
```html | ||
<html> | ||
<body> | ||
<ul> | ||
<!--(bake-start _foreach="name:[Robert, Susan, Carl]")--> | ||
<li><a href="#anchor-{{name@iteration}}">{{name}}</a></li> | ||
<!--(bake-end)--> | ||
</ul> | ||
</body> | ||
</html> | ||
``` | ||
This will render the following: | ||
```html | ||
<html> | ||
<body> | ||
<ul> | ||
<li><a href="#anchor-1">Robert</a></li> | ||
<li><a href="#anchor-2">Susan</a></li> | ||
<li><a href="#anchor-3">Carl</a></li> | ||
</ul> | ||
</body> | ||
</html> | ||
``` | ||
#### Inline Section statement | ||
@@ -463,6 +490,6 @@ | ||
<html> | ||
<body> | ||
<!--(bake includes/file.html _section="home")--> | ||
<!--(bake includes/file.html _section="about")--> | ||
</body> | ||
<body> | ||
<!--(bake includes/file.html _section="home")--> | ||
<!--(bake includes/file.html _section="about")--> | ||
</body> | ||
</html> | ||
@@ -480,10 +507,10 @@ ``` | ||
{ | ||
"home": { | ||
"title": "Home", | ||
"content": "This is home" | ||
}, | ||
"about": { | ||
"title": "About", | ||
"content": "This is about" | ||
} | ||
"home": { | ||
"title": "Home", | ||
"content": "This is home" | ||
}, | ||
"about": { | ||
"title": "About", | ||
"content": "This is about" | ||
} | ||
} | ||
@@ -495,8 +522,8 @@ ``` | ||
<html> | ||
<body> | ||
<h1>Home</h1> | ||
<p>This is home</p> | ||
<h1>About</h1> | ||
<p>This is about</p> | ||
</body> | ||
<body> | ||
<h1>Home</h1> | ||
<p>This is home</p> | ||
<h1>About</h1> | ||
<p>This is about</p> | ||
</body> | ||
</html> | ||
@@ -517,5 +544,5 @@ ``` | ||
<html> | ||
<body> | ||
<!--(bake includes/file.html _render="baseline")--> | ||
</body> | ||
<body> | ||
<!--(bake includes/file.html _render="baseline")--> | ||
</body> | ||
</html> | ||
@@ -527,11 +554,11 @@ ``` | ||
bake: { | ||
your_target: { | ||
options: { | ||
baseline: false | ||
}, | ||
your_target: { | ||
options: { | ||
baseline: false | ||
}, | ||
files: { | ||
"dist/index.html": "app/base.html" | ||
} | ||
}, | ||
files: { | ||
"dist/index.html": "app/base.html" | ||
} | ||
}, | ||
} | ||
@@ -545,4 +572,4 @@ ``` | ||
<html> | ||
<body> | ||
</body> | ||
<body> | ||
</body> | ||
</html> | ||
@@ -559,19 +586,19 @@ ``` | ||
var processFunction( source, content ) { | ||
return source + "<br>"; | ||
return source + "<br>"; | ||
} | ||
grunt.initConfig( { | ||
bake: { | ||
build: { | ||
options: { | ||
content: "app/content.json", | ||
section: "en", | ||
process: processFunction | ||
} | ||
bake: { | ||
build: { | ||
options: { | ||
content: "app/content.json", | ||
section: "en", | ||
process: processFunction | ||
} | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
files: { | ||
"app/index.html": "app/base.html" | ||
} | ||
} | ||
} | ||
} ) | ||
@@ -586,7 +613,7 @@ ``` | ||
watch: { | ||
bake: { | ||
files: [ "app/includes/**" ], | ||
tasks: "bake:build" | ||
} | ||
bake: { | ||
files: [ "app/includes/**" ], | ||
tasks: "bake:build" | ||
} | ||
} | ||
``` |
@@ -33,2 +33,5 @@ /* | ||
// normalize basePath | ||
if ( options.basePath.substr( -1 , 1 ) !== "/" && options.basePath.length > 0 ) { | ||
@@ -39,2 +42,13 @@ options.basePath = options.basePath + "/"; | ||
// normalize content | ||
if ( mout.lang.isString( options.content ) ) { | ||
options.content = grunt.file.readJSON( options.content ); | ||
} else if ( mout.lang.isFunction( options.content ) ) { | ||
options.content = options.content(); | ||
} else { | ||
options.content = options.content ? options.content : {}; | ||
} | ||
// ======================= | ||
@@ -88,6 +102,5 @@ // -- DEFAULT PROCESSOR -- | ||
// Regex to parse bake tags. The regex returns file path as match. | ||
// Regex to parse bake tags. Retuns linebreak, indent, type, and signature | ||
var regex = /(\n?)([ |\t]*)<!--\(\s?bake\s+([\w\/.\-]+)\s?([^]*?)\)-->/g; | ||
var regexInline = /(?:[ |\t]*<!--\(\s?bake-start\s+([^>]*)\)-->)\n?([\s\S]+?)(?:[ |\t]*<!--\(\s?bake-end\s?\)-->)/g; | ||
var regex = /(\n?)([ |\t]*)<!--\(\s?bake(-start|-end)?([^]*?)\)-->/; | ||
@@ -103,3 +116,6 @@ // Regex to parse attributes. | ||
// Regex to detect includePath / attributes in signature | ||
var signatureRegex = /^((?!_\S+=)[^\s]+)\s?([\S\s]*)$/; | ||
// Method to check wether file exists and warn if not. | ||
@@ -141,2 +157,29 @@ | ||
// Parses a bake call signature (extract filepath and arguments) | ||
function parseSignature( signature ) { | ||
var match; | ||
var result; | ||
// trim whitespace from signature otherwise reqular expression test may fail | ||
signature = signature.trim(); | ||
if( match = signatureRegex.exec( signature ) ) { | ||
result = { | ||
includePath: match[1], | ||
attributes: match[2], | ||
signature: signature | ||
}; | ||
} else { | ||
result = { | ||
includePath: "", | ||
attributes: signature, | ||
signature: signature | ||
}; | ||
} | ||
return result; | ||
} | ||
// Helper method to check if a value represents false | ||
@@ -200,8 +243,8 @@ | ||
var lines = content.split( "\n" ); | ||
var prepedLines = lines.map( function( line ) { | ||
return indent + line; | ||
} ); | ||
return prepedLines.join( "\n" ); | ||
return content | ||
.split( "\n" ) | ||
.map( function( line ) { | ||
return indent + line; | ||
} ) | ||
.join( "\n" ); | ||
} | ||
@@ -246,6 +289,7 @@ | ||
var contentValue = resolveName( left, values ); | ||
if( mout.object.has( values, left ) ) left = resolveName( left, values ); | ||
if( mout.object.has( values, right ) ) right = resolveName( right, values ); | ||
if ( operator === "==" && contentValue === right ) return false; | ||
else if ( operator === "!=" && contentValue !== right ) return false; | ||
if ( operator === "==" && left === right ) return false; | ||
else if ( operator === "!=" && left !== right ) return false; | ||
@@ -342,6 +386,11 @@ return true; | ||
function replace( linebreak, indent, includePath, attributes, filePath, values ) { | ||
function replaceFile( linebreak, indent, includePath, attributes, filePath, values ) { | ||
includePath = preparePath( includePath, filePath ); | ||
var includeContent = grunt.file.read( includePath ); | ||
return replaceString( includeContent, linebreak, indent, includePath, attributes, values ); | ||
} | ||
function replaceString( includeContent, linebreak, indent, includePath, attributes, values ) { | ||
var inlineValues = parseInlineValues( attributes ); | ||
@@ -359,7 +408,6 @@ var section = validateSection( inlineValues, values ); | ||
var forEachName = validateForEach( inlineValues, values, forEachValues ); | ||
var includeContent = grunt.file.read( includePath ); | ||
values = mout.object.merge( values, inlineValues ); | ||
includeContent = applyIndent( indent, includeContent ); | ||
includeContent = applyIndent( indent, includeContent); | ||
@@ -369,10 +417,16 @@ if ( forEachValues.length > 0 ) { | ||
var fragment = ""; | ||
var newline = ""; | ||
var oldValue = values[ forEachName ]; | ||
var total = forEachValues.length; | ||
forEachValues.forEach( function( value, index ) { | ||
values[ forEachName ] = value; | ||
newline = index > 0 ? "\n" : ""; | ||
fragment += newline + parse( includeContent, includePath, values ); | ||
// assign meta vars with information about current iteration | ||
values[ forEachName + "@index" ] = String( index ); | ||
values[ forEachName + "@iteration" ] = String( index + 1 ); | ||
values[ forEachName + "@first" ] = ( index === 0 ); | ||
values[ forEachName + "@last" ] = ( ( total - 1 ) === index ); | ||
values[ forEachName + "@total" ] = String( total ); | ||
fragment += linebreak + parse( includeContent, includePath, values ); | ||
} ); | ||
@@ -383,3 +437,3 @@ | ||
return linebreak + fragment; | ||
return fragment; | ||
@@ -391,72 +445,79 @@ } else { | ||
} | ||
} | ||
function inlineReplace( attributes, content, filePath, values ) { | ||
var inlineValues = parseInlineValues( attributes ); | ||
// ===================== | ||
// -- RECURSIVE PARSE -- | ||
// ===================== | ||
if ( validateRender( inlineValues ) ) return ""; | ||
if ( validateIf( inlineValues, values ) ) return ""; | ||
// extract bake sections. | ||
// For inline-bake it searches for matching closing tags and returns inline content and other information | ||
var forEachValues = []; | ||
var forEachName = validateForEach( inlineValues, values, forEachValues ); | ||
var includeContent = content.trimRight(); | ||
var section = validateSection( inlineValues, values ); | ||
function extractSection( content ) { | ||
var depth = 0; // tracks how difference between found opening and closing tags | ||
var start = 0; // character position in `content` where inner-content starts | ||
var position = 0; // current character position within _original_ content | ||
var length = 0; // length section (= spacing plus bake-tag) we currently evaluate | ||
var remain = content; // content left for further extraction | ||
var section = {}; | ||
if ( section !== null ) { | ||
values = values[ section ]; | ||
} | ||
do { | ||
values = mout.object.merge( values, inlineValues ); | ||
var result = remain.match( regex ); | ||
if ( forEachValues.length > 0 ) { | ||
if( ! result ) break; | ||
var fragment = ""; | ||
var newline = ""; | ||
var oldValue = values[ forEachName ]; | ||
length = result[ 0 ].length; | ||
position += result.index; | ||
forEachValues.forEach( function( value, index ) { | ||
values[ forEachName ] = value; | ||
if( depth === 0 ) { | ||
newline = mout.lang.isFunction( options.process ) ? options.process( includeContent, values ) : includeContent; | ||
start = position + length; | ||
fragment += ( index > 0 ? "\n" : "" ) + newline; | ||
} ); | ||
section = mout.object.merge( section, parseSignature( result[ 4 ] ), { | ||
before: content.slice( 0, position ), | ||
linebreak: result[ 1 ], | ||
indent: result[ 2 ] | ||
} ); | ||
} | ||
if ( oldValue === undefined ) values[ forEachName ] = oldValue; | ||
else delete values[ forEachName ]; | ||
remain = remain.slice( result.index + length ); | ||
return fragment; | ||
depth += (result[ 3 ] === "-start"); | ||
depth -= (result[ 3 ] === "-end"); | ||
} else { | ||
if( depth === 0 ) { | ||
return mout.object.merge( section, { | ||
inner: content.slice( start, position ), | ||
after: content.slice( position + length ) | ||
} ); | ||
} | ||
return parse( includeContent, filePath, values ); | ||
position += length; | ||
} | ||
} while( true ); | ||
return null; | ||
} | ||
// ===================== | ||
// -- RECURSIVE PARSE -- | ||
// ===================== | ||
// Recursivly search for bake-tags and create one file. | ||
// Recursivly search for includes and create one file. | ||
function parse( fileContent, filePath, values ) { | ||
fileContent = fileContent.replace( regexInline, function( match, attributes, content ) { | ||
return inlineReplace( attributes, content, filePath, values ); | ||
} ); | ||
var section = extractSection( fileContent ); | ||
if ( mout.lang.isFunction( options.process ) ) { | ||
fileContent = options.process( fileContent, values ); | ||
} | ||
if( section ) { | ||
fileContent = section.before; | ||
fileContent = fileContent.replace( regex, function( match, linebreak, indent, includePath, attributes ) { | ||
return replace( linebreak, indent, includePath, attributes, filePath, values ); | ||
} ); | ||
if(section.inner) { | ||
fileContent += replaceString( section.inner, "", "", filePath, section.attributes, values ); | ||
} else { | ||
fileContent += replaceFile( section.linebreak, section.indent, section.includePath, section.attributes, filePath, values ); | ||
} | ||
fileContent += parse( section.after, filePath, values ); | ||
} | ||
return fileContent; | ||
return mout.lang.isFunction( options.process ) ? options.process( fileContent, values ) : fileContent; | ||
} | ||
@@ -478,22 +539,13 @@ | ||
var values; | ||
if ( mout.lang.isString( options.content ) ) { | ||
values = grunt.file.readJSON( options.content ); | ||
} else if ( mout.lang.isFunction( options.content ) ) { | ||
values = options.content(); | ||
} else { | ||
values = options.content ? options.content : {}; | ||
} | ||
if ( options.section ) { | ||
if ( ! values[ options.section ] ) { | ||
if ( ! options.content[ options.section ] ) { | ||
grunt.log.error( "content doesn't have section " + options.section ); | ||
} | ||
values = values[ options.section ]; | ||
options.content = options.content[ options.section ]; | ||
} | ||
var srcContent = grunt.file.read( src ); | ||
var destContent = parse( srcContent, src, values ); | ||
var destContent = parse( srcContent, src, options.content ); | ||
@@ -500,0 +552,0 @@ grunt.file.write( dest, destContent ); |
@@ -15,2 +15,3 @@ "use strict"; | ||
"tmp/recursive_bake.html": "test/expected/recursive_bake.html", | ||
"tmp/inline_recursive_bake.html": "test/expected/inline_recursive_bake.html", | ||
"tmp/inline_bake.html": "test/expected/inline_bake.html", | ||
@@ -32,3 +33,5 @@ "tmp/absolute_path_bake.html": "test/expected/default_bake.html", | ||
"tmp/transform_multiple.html": "test/expected/transform_multiple.html", | ||
"tmp/transform_deep.html": "test/expected/transform_deep.html" | ||
"tmp/transform_deep.html": "test/expected/transform_deep.html", | ||
"tmp/foreach_meta.html": "test/expected/foreach_meta.html", | ||
"tmp/multiline_bake.html": "test/expected/multiline_bake.html" | ||
}; | ||
@@ -35,0 +38,0 @@ |
@@ -23,14 +23,33 @@ { | ||
"rooms": [ | ||
{ | ||
"width": "9", | ||
"depth": "5", | ||
"height": "2" | ||
}, | ||
{ | ||
"width": "4", | ||
"depth": "2", | ||
"height": "2.4" | ||
} | ||
] | ||
"rooms": [ | ||
{ | ||
"width": "9", | ||
"depth": "5", | ||
"height": "2" | ||
}, | ||
{ | ||
"width": "4", | ||
"depth": "2", | ||
"height": "2.4" | ||
} | ||
], | ||
"groups": [ | ||
{ | ||
"name": "A-Team", | ||
"members": [ | ||
"Joane", | ||
"Marc", | ||
"Frank" | ||
] | ||
}, | ||
{ | ||
"name": "B-Team", | ||
"members": [ | ||
"Mike", | ||
"Lisa" | ||
] | ||
} | ||
] | ||
} |
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
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
47024
63
768
0
590