Skip to content

Commit

Permalink
Add the concept of default options to Y.Template.
Browse files Browse the repository at this point in the history
  • Loading branch information
ericf committed Dec 17, 2012
1 parent 978126c commit 3a72361
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/template/docs/index.mustache
Expand Up @@ -648,7 +648,7 @@ The following example will define a Handlebars-like Micro template syntax:
Y.mix(Y.Template.Micro.options, {
code : /\{\{%([\s\S]+?)%\}\}/g,
escapedOutput: /\{\{(?!%)([\s\S]+?)\}\}/g,
rawOutput : /\{\{\{([\s\S]+?)\}\}/g
rawOutput : /\{\{\{([\s\S]+?)\}\}\}/g
}, true);
```

Expand Down Expand Up @@ -710,7 +710,7 @@ Y.mix(Y.Template.Micro.options, {
</table>

<p>
<strong>Note:</strong> The syntax identifiers can be specified on a per-template basis by passing `options` as the second argument to the `compile()`, `precompile()`, or `render()` methods.
<strong>Note:</strong> The syntax identifiers can be specified on a per-template basis by passing `options` as the second argument to the `compile()`, `precompile()`, or `render()` methods. Alternatively you can specify `defaults` when using the [[#Generic Template API|generic Template API]], doing so will only affect how the templates are process for that engine instance.
</p>

<h2>Using Templates in Custom Components</h2>
Expand Down
36 changes: 35 additions & 1 deletion src/template/js/template-base.js
Expand Up @@ -43,11 +43,21 @@ Using with Handlebars:
@param {Mixed} [engine=Y.Template.Micro] Template engine to use, such as
`Y.Template.Micro` or `Y.Handlebars`. Defaults to `Y.Template.Micro` if not
specified.
@param {Object} [defaults] Default options to use when instance methods are
invoked.
@constructor
@since 3.8.0
**/

function Template(engine) {
function Template(engine, defaults) {
/**
Default options.
@property {Object} defaults
@since 3.8.1
**/
this.defaults = defaults;

/**
Template engine class.
Expand All @@ -74,6 +84,12 @@ Template.prototype = {
@since 3.8.0
**/
compile: function (text, options) {
var defaults = this.defaults;

if (defaults) {
options = options ? Y.merge(defaults, options) : defaults;
}

return this.engine.compile(text, options);
},

Expand All @@ -89,6 +105,12 @@ Template.prototype = {
@since 3.8.0
**/
precompile: function (text, options) {
var defaults = this.defaults;

if (defaults) {
options = options ? Y.merge(defaults, options) : defaults;
}

return this.engine.precompile(text, options);
},

Expand All @@ -105,6 +127,12 @@ Template.prototype = {
@since 3.8.0
**/
render: function (text, data, options) {
var defaults = this.defaults;

if (defaults) {
options = options ? Y.merge(defaults, options) : defaults;
}

if (this.engine.render) {
return this.engine.render(text, data, options);
}
Expand All @@ -125,6 +153,12 @@ Template.prototype = {
@since 3.8.0
**/
revive: function (precompiled, options) {
var defaults = this.defaults;

if (defaults) {
options = options ? Y.merge(defaults, options) : defaults;
}

return this.engine.revive ? this.engine.revive(precompiled, options) :
precompiled;
}
Expand Down
85 changes: 85 additions & 0 deletions src/template/tests/unit/assets/template-test.js
Expand Up @@ -234,6 +234,91 @@ templateSuite.add(new Y.Test.Case({
}
}));

templateSuite.add(new Y.Test.Case({
name: 'Options',

setUp: function () {
// Creates a Template.Micro engine with specificed defaults.
this.microEngine = new Y.Template(Y.Template.Micro, {
code : /\{\{%([\s\S]+?)%\}\}/g,
escapedOutput: /\{\{(?!%)([\s\S]+?)\}\}/g,
rawOutput : /\{\{\{([\s\S]+?)\}\}\}/g
});

// Creates a Handlebars engine with specificed defaults.
this.hbEngine = new Y.Template(Y.Handlebars, {
partials: {
foo: '!{{a}}!'
}
});
},

tearDown: function () {
delete this.microEngine;
delete this.hbEngine;
},

'compile() should compile a template using the specified `defaults`': function () {
Assert.areSame('foo', this.microEngine.compile('{{this.a}}')({a: 'foo'}), 'should compile Micro templates with custom syntax');
Assert.areSame('!foo!', this.hbEngine.compile('{{> foo}}')({a: 'foo'}, this.hbEngine.defaults), 'should compile Handlebars template with default partials');
},

'compile() should merge `defaults` with specificed `options`': function () {
Assert.areSame(
'foo',
this.microEngine.compile('<%= data.a %>', {
escapedOutput: /<%=([\s\S]+?)%>/g
})({a: 'foo'})
);
},

'precompile() should precompile a template using the specified `defaults`': function () {
Assert.areSame(
"function (Y, $e, data) {\nvar $b='',$t=''+\n$e((data.test)||$b)+\n'';\nreturn $t;\n}",
this.microEngine.precompile('{{data.test}}')
);
},

'precompile() should merge `defaults` with the specified `options`': function () {
Assert.areSame(
"function (Y, $e, data) {\nvar $b='',$t=''+\n$e((data.test)||$b)+\n'';\nreturn $t;\n}",

this.microEngine.precompile('<%=data.test%>', {
escapedOutput: /<%=([\s\S]+?)%>/g
})
);
},

'render() should compile and render a template using the the specified `defaults`': function () {
Assert.areSame(
'foo',
this.microEngine.render('{{data.a}}', {a: 'foo'})
);
},

'render() should merge `defaults` with the specified `options`': function () {
Assert.areSame(
'foo bar',
this.microEngine.render('<%= data.a %> {{{ data.b }}}', {
a: 'foo',
b: 'bar'
}, {
escapedOutput: /<%=([\s\S]+?)%>/g
})
);
},

'revive() should revive a precompiled template using the specified `defaults`': function () {
eval('var precompiled = ' + this.microEngine.precompile('{{data.a}}') + ';');
Assert.areSame('foo', this.microEngine.revive(precompiled)({a: 'foo'}));
},

'revive() should merge `defaults` with the specified `options`': function () {
eval('var precompiled = ' + this.microEngine.precompile('{{data.a}}') + ';');
Assert.areSame('foo', this.microEngine.revive(precompiled, {})({a: 'foo'}));
}
}));

}, '@VERSION@', {
requires: ['handlebars', 'template', 'test']
});

0 comments on commit 3a72361

Please sign in to comment.