2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('handlebars-base', function (Y, NAME) {
11 Handlebars.js - Copyright (C) 2011 Yehuda Katz
12 https://raw.github.com/wycats/handlebars.js/master/LICENSE
14 // This file contains YUI-specific wrapper code and overrides for the
15 // handlebars-base module.
18 Handlebars is a simple template language inspired by Mustache.
20 This is a YUI port of the original Handlebars project, which can be found at
21 <https://github.com/wycats/handlebars.js>.
29 Provides basic Handlebars template rendering functionality. Use this module when
30 you only need to render pre-compiled templates.
33 @submodule handlebars-base
37 Handlebars is a simple template language inspired by Mustache.
39 This is a YUI port of the original Handlebars project, which can be found at
40 <https://github.com/wycats/handlebars.js>.
45 var Handlebars = Y.namespace('Handlebars');
46 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
48 Handlebars.VERSION = "1.0.0";
49 Handlebars.COMPILER_REVISION = 4;
51 Handlebars.REVISION_CHANGES = {
52 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
58 Handlebars.helpers = {};
59 Handlebars.partials = {};
61 var toString = Object.prototype.toString,
62 functionType = '[object Function]',
63 objectType = '[object Object]';
65 Handlebars.registerHelper = function(name, fn, inverse) {
66 if (toString.call(name) === objectType) {
67 if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
68 Handlebars.Utils.extend(this.helpers, name);
70 if (inverse) { fn.not = inverse; }
71 this.helpers[name] = fn;
75 Handlebars.registerPartial = function(name, str) {
76 if (toString.call(name) === objectType) {
77 Handlebars.Utils.extend(this.partials, name);
79 this.partials[name] = str;
83 Handlebars.registerHelper('helperMissing', function(arg) {
84 if(arguments.length === 2) {
87 throw new Error("Missing helper: '" + arg + "'");
91 Handlebars.registerHelper('blockHelperMissing', function(context, options) {
92 var inverse = options.inverse || function() {}, fn = options.fn;
94 var type = toString.call(context);
96 if(type === functionType) { context = context.call(this); }
98 if(context === true) {
100 } else if(context === false || context == null) {
101 return inverse(this);
102 } else if(type === "[object Array]") {
103 if(context.length > 0) {
104 return Handlebars.helpers.each(context, options);
106 return inverse(this);
113 Handlebars.K = function() {};
115 Handlebars.createFrame = Object.create || function(object) {
116 Handlebars.K.prototype = object;
117 var obj = new Handlebars.K();
118 Handlebars.K.prototype = null;
122 Handlebars.logger = {
123 DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
125 methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
127 // can be overridden in the host environment
128 log: function(level, obj) {
129 if (Handlebars.logger.level <= level) {
130 var method = Handlebars.logger.methodMap[level];
131 if (typeof console !== 'undefined' && console[method]) {
132 console[method].call(console, obj);
138 Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
140 Handlebars.registerHelper('each', function(context, options) {
141 var fn = options.fn, inverse = options.inverse;
142 var i = 0, ret = "", data;
144 var type = toString.call(context);
145 if(type === functionType) { context = context.call(this); }
148 data = Handlebars.createFrame(options.data);
151 if(context && typeof context === 'object') {
152 if(context instanceof Array){
153 for(var j = context.length; i<j; i++) {
154 if (data) { data.index = i; }
155 ret = ret + fn(context[i], { data: data });
158 for(var key in context) {
159 if(context.hasOwnProperty(key)) {
160 if(data) { data.key = key; }
161 ret = ret + fn(context[key], {data: data});
175 Handlebars.registerHelper('if', function(conditional, options) {
176 var type = toString.call(conditional);
177 if(type === functionType) { conditional = conditional.call(this); }
179 if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
180 return options.inverse(this);
182 return options.fn(this);
186 Handlebars.registerHelper('unless', function(conditional, options) {
187 return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
190 Handlebars.registerHelper('with', function(context, options) {
191 var type = toString.call(context);
192 if(type === functionType) { context = context.call(this); }
194 if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
197 Handlebars.registerHelper('log', function(context, options) {
198 var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
199 Handlebars.log(level, context);
201 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
203 var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
205 Handlebars.Exception = function(message) {
206 var tmp = Error.prototype.constructor.apply(this, arguments);
208 // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
209 for (var idx = 0; idx < errorProps.length; idx++) {
210 this[errorProps[idx]] = tmp[errorProps[idx]];
213 Handlebars.Exception.prototype = new Error();
215 // Build out our basic SafeString type
216 Handlebars.SafeString = function(string) {
217 this.string = string;
219 Handlebars.SafeString.prototype.toString = function() {
220 return this.string.toString();
232 var badChars = /[&<>"'`]/g;
233 var possible = /[&<>"'`]/;
235 var escapeChar = function(chr) {
236 return escape[chr] || "&";
240 extend: function(obj, value) {
241 for(var key in value) {
242 if(value.hasOwnProperty(key)) {
243 obj[key] = value[key];
248 escapeExpression: function(string) {
249 // don't escape SafeStrings, since they're already safe
250 if (string instanceof Handlebars.SafeString) {
251 return string.toString();
252 } else if (string == null || string === false) {
256 // Force a string conversion as this will be done by the append regardless and
257 // the regex test will do this transparently behind the scenes, causing issues if
258 // an object's to string has escaped characters in it.
259 string = string.toString();
261 if(!possible.test(string)) { return string; }
262 return string.replace(badChars, escapeChar);
265 isEmpty: function(value) {
266 if (!value && value !== 0) {
268 } else if(toString.call(value) === "[object Array]" && value.length === 0) {
275 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
278 template: function(templateSpec) {
281 escapeExpression: Handlebars.Utils.escapeExpression,
282 invokePartial: Handlebars.VM.invokePartial,
284 program: function(i, fn, data) {
285 var programWrapper = this.programs[i];
287 programWrapper = Handlebars.VM.program(i, fn, data);
288 } else if (!programWrapper) {
289 programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
291 return programWrapper;
293 merge: function(param, common) {
294 var ret = param || common;
296 if (param && common) {
298 Handlebars.Utils.extend(ret, common);
299 Handlebars.Utils.extend(ret, param);
303 programWithDepth: Handlebars.VM.programWithDepth,
304 noop: Handlebars.VM.noop,
308 return function(context, options) {
309 options = options || {};
310 var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
312 var compilerInfo = container.compilerInfo || [],
313 compilerRevision = compilerInfo[0] || 1,
314 currentRevision = Handlebars.COMPILER_REVISION;
316 if (compilerRevision !== currentRevision) {
317 if (compilerRevision < currentRevision) {
318 var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
319 compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
320 throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
321 "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
323 // Use the embedded version info since the runtime doesn't know about this revision yet
324 throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
325 "Please update your runtime to a newer version ("+compilerInfo[1]+").";
333 programWithDepth: function(i, fn, data /*, $depth */) {
334 var args = Array.prototype.slice.call(arguments, 3);
336 var program = function(context, options) {
337 options = options || {};
339 return fn.apply(this, [context, options.data || data].concat(args));
342 program.depth = args.length;
345 program: function(i, fn, data) {
346 var program = function(context, options) {
347 options = options || {};
349 return fn(context, options.data || data);
355 noop: function() { return ""; },
356 invokePartial: function(partial, name, context, helpers, partials, data) {
357 var options = { helpers: helpers, partials: partials, data: data };
359 if(partial === undefined) {
360 throw new Handlebars.Exception("The partial " + name + " could not be found");
361 } else if(partial instanceof Function) {
362 return partial(context, options);
363 } else if (!Handlebars.compile) {
364 throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
366 partials[name] = Handlebars.compile(partial, {data: data !== undefined});
367 return partials[name](context, options);
372 Handlebars.template = Handlebars.VM.template;
373 // This file contains YUI-specific wrapper code and overrides for the
374 // handlebars-base module.
376 Handlebars.VERSION += '-yui';
379 Registers a helper function that will be made available to all templates.
381 Helper functions receive the current template context as the `this` object, and
382 can also receive arguments passed by the template.
386 Y.Handlebars.registerHelper('linkify', function () {
387 return '<a href="' + Y.Escape.html(this.url) + '">' +
388 Y.Escape.html(this.text) + '</a>';
391 var source = '<ul>{{#links}}<li>{{{linkify}}}</li>{{/links}}</ul>';
393 Y.Handlebars.render(source, {
395 {url: '/foo', text: 'Foo'},
396 {url: '/bar', text: 'Bar'},
397 {url: '/baz', text: 'Baz'}
401 @method registerHelper
402 @param {String} name Name of this helper.
403 @param {Function} fn Helper function.
404 @param {Boolean} [inverse=false] If `true`, this helper will be considered an
405 "inverse" helper, like "unless". This means it will only be called if the
406 expression given in the template evaluates to a false or empty value.
410 Registers a partial that will be made available to all templates.
412 A partial is another template that can be used to render part of a larger
413 template. For example, a website with a common header and footer across all its
414 pages might use a template for each page, which would call shared partials to
415 render the headers and footers.
417 Partials may be specified as uncompiled template strings or as compiled template
422 Y.Handlebars.registerPartial('header', '<h1>{{title}}</h1>');
423 Y.Handlebars.registerPartial('footer', 'Copyright (c) 2011 by Me.');
425 var source = '{{> header}} <p>Mustaches are awesome!</p> {{> footer}}';
427 Y.Handlebars.render(source, {title: 'My Page About Mustaches'});
429 @method registerPartial
430 @param {String} name Name of this partial.
431 @param {Function|String} partial Template string or compiled template function.
435 Converts a precompiled template into a renderable template function.
439 <script src="precompiled-template.js"></script>
441 YUI().use('handlebars-base', function (Y) {
442 // Convert the precompiled template function into a renderable template
444 var template = Y.Handlebars.template(precompiledTemplate);
447 template({pie: 'Pumpkin'});
452 @param {Function} template Precompiled Handlebars template function.
453 @return {Function} Compiled template function.
456 // Alias for Y.Handlebars.template(), used by Y.Template.
457 Handlebars.revive = Handlebars.template;
459 // Make Y.Template.Handlebars an alias for Y.Handlebars.
460 Y.namespace('Template').Handlebars = Handlebars;
463 }, '3.13.0', {"requires": []});