Permalink
Browse files

Added an option to pass additional context to parent / child template…

… with `extend` / `include` tags.
  • Loading branch information...
Pierre Matri
Pierre Matri committed Aug 21, 2012
1 parent afe4308 commit c93307a68291b59ff10d50d6a9c2e5fac3c2726a
View
@@ -5,6 +5,8 @@
### New features
* Added `filter` tag.
+* Added an option to pass additional context to parent / child template with `extend` / `include` tags.
+* Added cloning of data object when rendering a template.
## 0.2.1
View
@@ -390,6 +390,22 @@ new Template(tpl2).render({ nested: nested }, callback);
<div>Hello!</div>
```
+#### Passing additional context to parent template
+
+```
+// foo.kiwi
+Hello, ${name}!
+
+// Template
+<div>${name} says: {{include "foo" childContext}}</div>
+
+// Code
+new Template(tpl).render({ name: 'Tom', childContext: { name: 'Bob' }}, callback);
+
+// Result
+<div>Tom says: Hello, Bob!</div>
+```
+
### {{block}}
#### Basic usage
@@ -428,7 +444,7 @@ Hello, {{block place}}world{{/block}}, dear {{block name}}user{{/block}}!
new Template(tpl).render({}, callback);
// Result
-<div>Hello, big world, dear user 42!</div>
+Hello, big world, dear user 42!
```
#### Parent
@@ -447,7 +463,7 @@ When using block tag with `{{extend}}`, you may want to inclue parent block mark
new Template(tpl).render({}, callback);
// Result
-<div>I just wanted to say « Welcome! »</div>
+I just wanted to say « Welcome! »
```
@@ -487,7 +503,7 @@ Hello, {{block place}}world{{/block}}!
new Template(tpl2).render({}, callback);
// Result
-<div>Hello, kiwi!</div>
+Hello, kiwi!
```
#### Using directly another `Template` instance
@@ -505,7 +521,24 @@ var parent = new Template(tpl1);
new Template(tpl2).render({ parent: parent }, callback);
// Result
-<div>Hello, kiwi!</div>
+Hello, kiwi!
+```
+
+#### Passing additional context to parent template
+
+```
+// foo.kiwi
+${name} says: {{block message}}Nothing...{{/block}}!
+
+// Template
+{{extend parent parentContext}}
+{{block place}}Hello, ${name}{{/block}}
+
+// Code
+new Template(tpl).render({ name: 'Tom', parentContext: { message: 'Bob' }}, callback);
+
+// Result
+Bob says: Hello, Tom!
```
### {{raw}}
View
33 kiwi.js
@@ -1479,6 +1479,7 @@ var utils = require('../utils');
*/
var EXTEND_PARSE_RE = /^extend\s+(.+)$/;
+var EXTEND_ARGS_SPLIT_RE = /\s+(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g;
/**
@@ -1515,20 +1516,25 @@ extendTag.compile = function(token, compiledContents, compiler, callback) {
}
var parsed = token.tag.match(EXTEND_PARSE_RE);
+ var parsedArgs = parsed ? parsed[1].split(EXTEND_ARGS_SPLIT_RE) : null;
- if(!parsed) {
+ if(!parsed || !parsedArgs) {
return callback(new Error('Compilation error: Unable to parse tag `' +
token.tag +
'`.'
));
}
- var name = parsed[1];
+ var name = parsedArgs[0];
+ var compiledInclude = parsedArgs[1] ?
+ ('_.extend($data, ' + parsedArgs[1] + ')') :
+ '$data';
var compiled = 'var __originalCallback = $callback;' +
'$callback = function(err, compiled) {' +
'$helpers.extend(' + name + ', __compiled, $template,' +
- '$data, __originalCallback);' +
+ compiledInclude +
+ ', __originalCallback);' +
'};';
callback(null, compiled);
@@ -1868,7 +1874,8 @@ var utils = require('../utils');
* Constants
*/
-var INCLUDE_PARSE_RE = /^include\s+(.+)$/;
+var INCLUDE_PARSE_RE = /^include\s+(.+)?$/;
+var INCLUDE_ARGS_SPLIT_RE = /\s+(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g;
/**
@@ -1899,19 +1906,25 @@ includeTag.isBlock = false;
includeTag.compile = function(token, compiledContents, compiler, callback) {
var parsed = token.tag.match(INCLUDE_PARSE_RE);
+ var parsedArgs = parsed ? parsed[1].split(INCLUDE_ARGS_SPLIT_RE) : null;
- if(!parsed) {
+ if(!parsed || !parsedArgs) {
return callback(new Error('Compilation error: Unable to parse tag `' +
token.tag +
'`.'
));
}
- var name = parsed[1];
+ var name = parsedArgs[0];
+
+ var compiledInclude = parsedArgs[1] ?
+ ('_.extend($data, ' + parsedArgs[1] + ')') :
+ '$data';
compiler.__compilationEnd.unshift('});');
var compiled = '$helpers.include(' + name + ', $template,' +
- '$data, function(err, rendered) {' +
+ compiledInclude + ', ' +
+ 'function(err, rendered) {' +
'__acc.push(rendered);';
callback(null, compiled);
@@ -2365,11 +2378,11 @@ Template.prototype.render = function(data, callback) {
// Support callback as 1st arg
if(_.isFunction(data) && !callback){
callback = data;
- data = {};
+ data = null;
}
- // Data defaults
- if(!data) data = {};
+ // Data defaults and / or cloning
+ data = data ? _.clone(data) : data;
// Check whether we have the compiled template ready in the object or in cache
var cacheKey = 'template::' + this._cacheKey();
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -17,6 +17,7 @@ var utils = require('../utils');
*/
var EXTEND_PARSE_RE = /^extend\s+(.+)$/;
+var EXTEND_ARGS_SPLIT_RE = /\s+(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g;
/**
@@ -53,20 +54,25 @@ extendTag.compile = function(token, compiledContents, compiler, callback) {
}
var parsed = token.tag.match(EXTEND_PARSE_RE);
+ var parsedArgs = parsed ? parsed[1].split(EXTEND_ARGS_SPLIT_RE) : null;
- if(!parsed) {
+ if(!parsed || !parsedArgs) {
return callback(new Error('Compilation error: Unable to parse tag `' +
token.tag +
'`.'
));
}
- var name = parsed[1];
+ var name = parsedArgs[0];
+ var compiledInclude = parsedArgs[1] ?
+ ('_.extend($data, ' + parsedArgs[1] + ')') :
+ '$data';
var compiled = 'var __originalCallback = $callback;' +
'$callback = function(err, compiled) {' +
'$helpers.extend(' + name + ', __compiled, $template,' +
- '$data, __originalCallback);' +
+ compiledInclude +
+ ', __originalCallback);' +
'};';
callback(null, compiled);
View
@@ -16,7 +16,8 @@ var utils = require('../utils');
* Constants
*/
-var INCLUDE_PARSE_RE = /^include\s+(.+)$/;
+var INCLUDE_PARSE_RE = /^include\s+(.+)?$/;
+var INCLUDE_ARGS_SPLIT_RE = /\s+(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g;
/**
@@ -47,19 +48,25 @@ includeTag.isBlock = false;
includeTag.compile = function(token, compiledContents, compiler, callback) {
var parsed = token.tag.match(INCLUDE_PARSE_RE);
+ var parsedArgs = parsed ? parsed[1].split(INCLUDE_ARGS_SPLIT_RE) : null;
- if(!parsed) {
+ if(!parsed || !parsedArgs) {
return callback(new Error('Compilation error: Unable to parse tag `' +
token.tag +
'`.'
));
}
- var name = parsed[1];
+ var name = parsedArgs[0];
+
+ var compiledInclude = parsedArgs[1] ?
+ ('_.extend($data, ' + parsedArgs[1] + ')') :
+ '$data';
compiler.__compilationEnd.unshift('});');
var compiled = '$helpers.include(' + name + ', $template,' +
- '$data, function(err, rendered) {' +
+ compiledInclude + ', ' +
+ 'function(err, rendered) {' +
'__acc.push(rendered);';
callback(null, compiled);
View
@@ -19,12 +19,12 @@ describe('Extend tag', function() {
it('should extend template', function(done) {
function onLoaded(err, data) {
- should.not.exist(err);
+ if(err) return done(err);
template.render({}, onRendered)
}
function onRendered(err, rendered) {
- should.not.exist(err);
+ if(err) return done(err);
rendered.trim().should.equal('foo doo woo roo');
done(err);
}
@@ -35,12 +35,12 @@ describe('Extend tag', function() {
it('should extend template with dynamic parent', function(done) {
function onLoaded(err, data) {
- should.not.exist(err);
+ if(err) return done(err);
template.render({parent: 'intermediate'}, onRendered)
}
function onRendered(err, rendered) {
- should.not.exist(err);
+ if(err) return done(err);
rendered.trim().should.equal('foo doo woo moo');
done(err);
}
@@ -50,26 +50,43 @@ describe('Extend tag', function() {
it('should extend template with Template instance as parent', function(done) {
- var parentTemplate = new Template({ cache: true });
+ var parentTemplate = new Template({ cache: true });
- function onParentTemplateLoaded(err, data) {
- should.not.exist(err);
- template.loadFile(__dirname + '/../fixtures/dynamic.kiwi', onLoaded);
- }
+ function onParentTemplateLoaded(err, data) {
+ if(err) return done(err);
+ template.loadFile(__dirname + '/../fixtures/dynamic.kiwi', onLoaded);
+ }
- function onLoaded(err, data) {
- should.not.exist(err);
- template.render({parent: parentTemplate}, onRendered)
- }
+ function onLoaded(err, data) {
+ if(err) return done(err);
+ template.render({parent: parentTemplate}, onRendered)
+ }
- function onRendered(err, rendered) {
- should.not.exist(err);
- rendered.trim().should.equal('foo doo woo moo');
- done(err);
- }
+ function onRendered(err, rendered) {
+ if(err) return done(err);
+ rendered.trim().should.equal('foo doo woo moo');
+ done(err);
+ }
- parentTemplate.loadFile(__dirname + '/../fixtures/intermediate.kiwi', onParentTemplateLoaded);
- });
+ parentTemplate.loadFile(__dirname + '/../fixtures/intermediate.kiwi', onParentTemplateLoaded);
+ });
+
+ it('should extend template with additional context', function(done) {
+
+ function onLoaded(err, data) {
+ if(err) return done(err);
+ template.render({someContext: {somevar: 'HWYHO'}}, onRendered)
+ }
+
+ function onRendered(err, rendered) {
+ if(err) return done(err);
+ rendered.trim().should.equal('before inside HWYHO stillinside after');
+ done();
+ }
+
+ template.loadFile(__dirname + '/../fixtures/extend_context.kiwi', onLoaded);
+ });
+
it('should properly cache paths', function(done) {
var calls = 0;
@@ -80,14 +97,14 @@ describe('Extend tag', function() {
}
function onFirstRender(err, rendered) {
- should.not.exist(err);
+ if(err) return done(err);
rendered.trim().should.equal('foo doo woo loo');
calls.should.equal(1);
template.render({}, onSecondRender)
}
function onSecondRender(err, rendered) {
- should.not.exist(err);
+ if(err) return done(err);
rendered.trim().should.equal('foo doo woo loo');
calls.should.equal(1);
done(err);
@@ -1,2 +1,3 @@
foo bar woo loo
-foo doo woo roo
+foo doo woo roo
+bar
@@ -8,7 +8,7 @@
var should = require('should');
var Template = require('../../lib/template');
-describe('Extend tag', function() {
+describe('Include tag', function() {
it('should include template with Template instance as child', function(done) {
@@ -1,2 +1,3 @@
{{include "../fixtures/root.kiwi"}}
-{{include "../fixtures/leaf"}}
+{{include "../fixtures/leaf"}}
+{{include "../fixtures/var" objt}}
@@ -0,0 +1 @@
+{{extend "root_var" someContext}}
View
@@ -0,0 +1 @@
+${foo}

0 comments on commit c93307a

Please sign in to comment.