Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / XTemplate.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-XTemplate'>/**
19 </span> * @class Ext.XTemplate
20  * @extends Ext.Template
21  * &lt;p&gt;A template class that supports advanced functionality like:&lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
22  * &lt;li&gt;Autofilling arrays using templates and sub-templates&lt;/li&gt;
23  * &lt;li&gt;Conditional processing with basic comparison operators&lt;/li&gt;
24  * &lt;li&gt;Basic math function support&lt;/li&gt;
25  * &lt;li&gt;Execute arbitrary inline code with special built-in template variables&lt;/li&gt;
26  * &lt;li&gt;Custom member functions&lt;/li&gt;
27  * &lt;li&gt;Many special tags and built-in operators that aren't defined as part of
28  * the API, but are supported in the templates that can be created&lt;/li&gt;
29  * &lt;/ul&gt;&lt;/div&gt;&lt;/p&gt;
30  * &lt;p&gt;XTemplate provides the templating mechanism built into:&lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
31  * &lt;li&gt;{@link Ext.view.View}&lt;/li&gt;
32  * &lt;/ul&gt;&lt;/div&gt;&lt;/p&gt;
33  *
34  * The {@link Ext.Template} describes
35  * the acceptable parameters to pass to the constructor. The following
36  * examples demonstrate all of the supported features.&lt;/p&gt;
37  *
38  * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
39  *
40  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Sample Data&lt;/u&gt;&lt;/b&gt;
41  * &lt;div class=&quot;sub-desc&quot;&gt;
42  * &lt;p&gt;This is the data object used for reference in each code example:&lt;/p&gt;
43  * &lt;pre&gt;&lt;code&gt;
44 var data = {
45 name: 'Tommy Maintz',
46 title: 'Lead Developer',
47 company: 'Sencha Inc.',
48 email: 'tommy@sencha.com',
49 address: '5 Cups Drive',
50 city: 'Palo Alto',
51 state: 'CA',
52 zip: '44102',
53 drinks: ['Coffee', 'Soda', 'Water'],
54 kids: [{
55         name: 'Joshua',
56         age:3
57     },{
58         name: 'Matthew',
59         age:2
60     },{
61         name: 'Solomon',
62         age:0
63 }]
64 };
65  &lt;/code&gt;&lt;/pre&gt;
66  * &lt;/div&gt;
67  * &lt;/li&gt;
68  *
69  *
70  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Auto filling of arrays&lt;/u&gt;&lt;/b&gt;
71  * &lt;div class=&quot;sub-desc&quot;&gt;
72  * &lt;p&gt;The &lt;b&gt;&lt;tt&gt;tpl&lt;/tt&gt;&lt;/b&gt; tag and the &lt;b&gt;&lt;tt&gt;for&lt;/tt&gt;&lt;/b&gt; operator are used
73  * to process the provided data object:
74  * &lt;ul&gt;
75  * &lt;li&gt;If the value specified in &lt;tt&gt;for&lt;/tt&gt; is an array, it will auto-fill,
76  * repeating the template block inside the &lt;tt&gt;tpl&lt;/tt&gt; tag for each item in the
77  * array.&lt;/li&gt;
78  * &lt;li&gt;If &lt;tt&gt;for=&quot;.&quot;&lt;/tt&gt; is specified, the data object provided is examined.&lt;/li&gt;
79  * &lt;li&gt;While processing an array, the special variable &lt;tt&gt;{#}&lt;/tt&gt;
80  * will provide the current array index + 1 (starts at 1, not 0).&lt;/li&gt;
81  * &lt;/ul&gt;
82  * &lt;/p&gt;
83  * &lt;pre&gt;&lt;code&gt;
84 &amp;lt;tpl &lt;b&gt;for&lt;/b&gt;=&quot;.&quot;&gt;...&amp;lt;/tpl&gt;       // loop through array at root node
85 &amp;lt;tpl &lt;b&gt;for&lt;/b&gt;=&quot;foo&quot;&gt;...&amp;lt;/tpl&gt;     // loop through array at foo node
86 &amp;lt;tpl &lt;b&gt;for&lt;/b&gt;=&quot;foo.bar&quot;&gt;...&amp;lt;/tpl&gt; // loop through array at foo.bar node
87  &lt;/code&gt;&lt;/pre&gt;
88  * Using the sample data above:
89  * &lt;pre&gt;&lt;code&gt;
90 var tpl = new Ext.XTemplate(
91     '&amp;lt;p&gt;Kids: ',
92     '&amp;lt;tpl &lt;b&gt;for&lt;/b&gt;=&quot;.&quot;&gt;',       // process the data.kids node
93         '&amp;lt;p&gt;{#}. {name}&amp;lt;/p&gt;',  // use current array index to autonumber
94     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
95 );
96 tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
97  &lt;/code&gt;&lt;/pre&gt;
98  * &lt;p&gt;An example illustrating how the &lt;b&gt;&lt;tt&gt;for&lt;/tt&gt;&lt;/b&gt; property can be leveraged
99  * to access specified members of the provided data object to populate the template:&lt;/p&gt;
100  * &lt;pre&gt;&lt;code&gt;
101 var tpl = new Ext.XTemplate(
102     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
103     '&amp;lt;p&gt;Title: {title}&amp;lt;/p&gt;',
104     '&amp;lt;p&gt;Company: {company}&amp;lt;/p&gt;',
105     '&amp;lt;p&gt;Kids: ',
106     '&amp;lt;tpl &lt;b&gt;for=&quot;kids&quot;&lt;/b&gt;&gt;',     // interrogate the kids property within the data
107         '&amp;lt;p&gt;{name}&amp;lt;/p&gt;',
108     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
109 );
110 tpl.overwrite(panel.body, data);  // pass the root node of the data object
111  &lt;/code&gt;&lt;/pre&gt;
112  * &lt;p&gt;Flat arrays that contain values (and not objects) can be auto-rendered
113  * using the special &lt;b&gt;&lt;tt&gt;{.}&lt;/tt&gt;&lt;/b&gt; variable inside a loop.  This variable
114  * will represent the value of the array at the current index:&lt;/p&gt;
115  * &lt;pre&gt;&lt;code&gt;
116 var tpl = new Ext.XTemplate(
117     '&amp;lt;p&gt;{name}\&amp;#39;s favorite beverages:&amp;lt;/p&gt;',
118     '&amp;lt;tpl for=&quot;drinks&quot;&gt;',
119         '&amp;lt;div&gt; - {.}&amp;lt;/div&gt;',
120     '&amp;lt;/tpl&gt;'
121 );
122 tpl.overwrite(panel.body, data);
123  &lt;/code&gt;&lt;/pre&gt;
124  * &lt;p&gt;When processing a sub-template, for example while looping through a child array,
125  * you can access the parent object's members via the &lt;b&gt;&lt;tt&gt;parent&lt;/tt&gt;&lt;/b&gt; object:&lt;/p&gt;
126  * &lt;pre&gt;&lt;code&gt;
127 var tpl = new Ext.XTemplate(
128     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
129     '&amp;lt;p&gt;Kids: ',
130     '&amp;lt;tpl for=&quot;kids&quot;&gt;',
131         '&amp;lt;tpl if=&quot;age &amp;amp;gt; 1&quot;&gt;',
132             '&amp;lt;p&gt;{name}&amp;lt;/p&gt;',
133             '&amp;lt;p&gt;Dad: {&lt;b&gt;parent&lt;/b&gt;.name}&amp;lt;/p&gt;',
134         '&amp;lt;/tpl&gt;',
135     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
136 );
137 tpl.overwrite(panel.body, data);
138  &lt;/code&gt;&lt;/pre&gt;
139  * &lt;/div&gt;
140  * &lt;/li&gt;
141  *
142  *
143  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Conditional processing with basic comparison operators&lt;/u&gt;&lt;/b&gt;
144  * &lt;div class=&quot;sub-desc&quot;&gt;
145  * &lt;p&gt;The &lt;b&gt;&lt;tt&gt;tpl&lt;/tt&gt;&lt;/b&gt; tag and the &lt;b&gt;&lt;tt&gt;if&lt;/tt&gt;&lt;/b&gt; operator are used
146  * to provide conditional checks for deciding whether or not to render specific
147  * parts of the template. Notes:&lt;div class=&quot;sub-desc&quot;&gt;&lt;ul&gt;
148  * &lt;li&gt;Double quotes must be encoded if used within the conditional&lt;/li&gt;
149  * &lt;li&gt;There is no &lt;tt&gt;else&lt;/tt&gt; operator &amp;mdash; if needed, two opposite
150  * &lt;tt&gt;if&lt;/tt&gt; statements should be used.&lt;/li&gt;
151  * &lt;/ul&gt;&lt;/div&gt;
152  * &lt;pre&gt;&lt;code&gt;
153 &amp;lt;tpl if=&quot;age &amp;gt; 1 &amp;amp;&amp;amp; age &amp;lt; 10&quot;&gt;Child&amp;lt;/tpl&gt;
154 &amp;lt;tpl if=&quot;age &gt;= 10 &amp;&amp; age &lt; 18&quot;&gt;Teenager&amp;lt;/tpl&gt;
155 &amp;lt;tpl &lt;b&gt;if&lt;/b&gt;=&quot;this.isGirl(name)&quot;&gt;...&amp;lt;/tpl&gt;
156 &amp;lt;tpl &lt;b&gt;if&lt;/b&gt;=&quot;id==\'download\'&quot;&gt;...&amp;lt;/tpl&gt;
157 &amp;lt;tpl &lt;b&gt;if&lt;/b&gt;=&quot;needsIcon&quot;&gt;&amp;lt;img src=&quot;{icon}&quot; class=&quot;{iconCls}&quot;/&gt;&amp;lt;/tpl&gt;
158 // no good:
159 &amp;lt;tpl if=&quot;name == &quot;Tommy&quot;&quot;&gt;Hello&amp;lt;/tpl&gt;
160 // encode &amp;#34; if it is part of the condition, e.g.
161 &amp;lt;tpl if=&quot;name == &amp;#38;quot;Tommy&amp;#38;quot;&quot;&gt;Hello&amp;lt;/tpl&gt;
162  * &lt;/code&gt;&lt;/pre&gt;
163  * Using the sample data above:
164  * &lt;pre&gt;&lt;code&gt;
165 var tpl = new Ext.XTemplate(
166     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
167     '&amp;lt;p&gt;Kids: ',
168     '&amp;lt;tpl for=&quot;kids&quot;&gt;',
169         '&amp;lt;tpl if=&quot;age &amp;amp;gt; 1&quot;&gt;',
170             '&amp;lt;p&gt;{name}&amp;lt;/p&gt;',
171         '&amp;lt;/tpl&gt;',
172     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
173 );
174 tpl.overwrite(panel.body, data);
175  &lt;/code&gt;&lt;/pre&gt;
176  * &lt;/div&gt;
177  * &lt;/li&gt;
178  *
179  *
180  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Basic math support&lt;/u&gt;&lt;/b&gt;
181  * &lt;div class=&quot;sub-desc&quot;&gt;
182  * &lt;p&gt;The following basic math operators may be applied directly on numeric
183  * data values:&lt;/p&gt;&lt;pre&gt;
184  * + - * /
185  * &lt;/pre&gt;
186  * For example:
187  * &lt;pre&gt;&lt;code&gt;
188 var tpl = new Ext.XTemplate(
189     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
190     '&amp;lt;p&gt;Kids: ',
191     '&amp;lt;tpl for=&quot;kids&quot;&gt;',
192         '&amp;lt;tpl if=&quot;age &amp;amp;gt; 1&quot;&gt;',  // &lt;-- Note that the &amp;gt; is encoded
193             '&amp;lt;p&gt;{#}: {name}&amp;lt;/p&gt;',  // &lt;-- Auto-number each item
194             '&amp;lt;p&gt;In 5 Years: {age+5}&amp;lt;/p&gt;',  // &lt;-- Basic math
195             '&amp;lt;p&gt;Dad: {parent.name}&amp;lt;/p&gt;',
196         '&amp;lt;/tpl&gt;',
197     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
198 );
199 tpl.overwrite(panel.body, data);
200  &lt;/code&gt;&lt;/pre&gt;
201  * &lt;/div&gt;
202  * &lt;/li&gt;
203  *
204  *
205  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Execute arbitrary inline code with special built-in template variables&lt;/u&gt;&lt;/b&gt;
206  * &lt;div class=&quot;sub-desc&quot;&gt;
207  * &lt;p&gt;Anything between &lt;code&gt;{[ ... ]}&lt;/code&gt; is considered code to be executed
208  * in the scope of the template. There are some special variables available in that code:
209  * &lt;ul&gt;
210  * &lt;li&gt;&lt;b&gt;&lt;tt&gt;values&lt;/tt&gt;&lt;/b&gt;: The values in the current scope. If you are using
211  * scope changing sub-templates, you can change what &lt;tt&gt;values&lt;/tt&gt; is.&lt;/li&gt;
212  * &lt;li&gt;&lt;b&gt;&lt;tt&gt;parent&lt;/tt&gt;&lt;/b&gt;: The scope (values) of the ancestor template.&lt;/li&gt;
213  * &lt;li&gt;&lt;b&gt;&lt;tt&gt;xindex&lt;/tt&gt;&lt;/b&gt;: If you are in a looping template, the index of the
214  * loop you are in (1-based).&lt;/li&gt;
215  * &lt;li&gt;&lt;b&gt;&lt;tt&gt;xcount&lt;/tt&gt;&lt;/b&gt;: If you are in a looping template, the total length
216  * of the array you are looping.&lt;/li&gt;
217  * &lt;/ul&gt;
218  * This example demonstrates basic row striping using an inline code block and the
219  * &lt;tt&gt;xindex&lt;/tt&gt; variable:&lt;/p&gt;
220  * &lt;pre&gt;&lt;code&gt;
221 var tpl = new Ext.XTemplate(
222     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
223     '&amp;lt;p&gt;Company: {[values.company.toUpperCase() + &quot;, &quot; + values.title]}&amp;lt;/p&gt;',
224     '&amp;lt;p&gt;Kids: ',
225     '&amp;lt;tpl for=&quot;kids&quot;&gt;',
226         '&amp;lt;div class=&quot;{[xindex % 2 === 0 ? &quot;even&quot; : &quot;odd&quot;]}&quot;&gt;',
227         '{name}',
228         '&amp;lt;/div&gt;',
229     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;'
230  );
231 tpl.overwrite(panel.body, data);
232  &lt;/code&gt;&lt;/pre&gt;
233  * &lt;/div&gt;
234  * &lt;/li&gt;
235  *
236  * &lt;li&gt;&lt;b&gt;&lt;u&gt;Template member functions&lt;/u&gt;&lt;/b&gt;
237  * &lt;div class=&quot;sub-desc&quot;&gt;
238  * &lt;p&gt;One or more member functions can be specified in a configuration
239  * object passed into the XTemplate constructor for more complex processing:&lt;/p&gt;
240  * &lt;pre&gt;&lt;code&gt;
241 var tpl = new Ext.XTemplate(
242     '&amp;lt;p&gt;Name: {name}&amp;lt;/p&gt;',
243     '&amp;lt;p&gt;Kids: ',
244     '&amp;lt;tpl for=&quot;kids&quot;&gt;',
245         '&amp;lt;tpl if=&quot;this.isGirl(name)&quot;&gt;',
246             '&amp;lt;p&gt;Girl: {name} - {age}&amp;lt;/p&gt;',
247         '&amp;lt;/tpl&gt;',
248          // use opposite if statement to simulate 'else' processing:
249         '&amp;lt;tpl if=&quot;this.isGirl(name) == false&quot;&gt;',
250             '&amp;lt;p&gt;Boy: {name} - {age}&amp;lt;/p&gt;',
251         '&amp;lt;/tpl&gt;',
252         '&amp;lt;tpl if=&quot;this.isBaby(age)&quot;&gt;',
253             '&amp;lt;p&gt;{name} is a baby!&amp;lt;/p&gt;',
254         '&amp;lt;/tpl&gt;',
255     '&amp;lt;/tpl&gt;&amp;lt;/p&gt;',
256     {
257         // XTemplate configuration:
258         compiled: true,
259         // member functions:
260         isGirl: function(name){
261            return name == 'Sara Grace';
262         },
263         isBaby: function(age){
264            return age &lt; 1;
265         }
266     }
267 );
268 tpl.overwrite(panel.body, data);
269  &lt;/code&gt;&lt;/pre&gt;
270  * &lt;/div&gt;
271  * &lt;/li&gt;
272  *
273  * &lt;/ul&gt;&lt;/div&gt;
274  *
275  * @param {Mixed} config
276  */
277
278 Ext.define('Ext.XTemplate', {
279
280     /* Begin Definitions */
281
282     extend: 'Ext.Template',
283
284     statics: {
285 <span id='Ext-XTemplate-method-from'>        /**
286 </span>         * Creates a template from the passed element's value (&lt;i&gt;display:none&lt;/i&gt; textarea, preferred) or innerHTML.
287          * @param {String/HTMLElement} el A DOM element or its id
288          * @return {Ext.Template} The created template
289          * @static
290          */
291         from: function(el, config) {
292             el = Ext.getDom(el);
293             return new this(el.value || el.innerHTML, config || {});
294         }
295     },
296
297     /* End Definitions */
298
299     argsRe: /&lt;tpl\b[^&gt;]*&gt;((?:(?=([^&lt;]+))\2|&lt;(?!tpl\b[^&gt;]*&gt;))*?)&lt;\/tpl&gt;/,
300     nameRe: /^&lt;tpl\b[^&gt;]*?for=&quot;(.*?)&quot;/,
301     ifRe: /^&lt;tpl\b[^&gt;]*?if=&quot;(.*?)&quot;/,
302     execRe: /^&lt;tpl\b[^&gt;]*?exec=&quot;(.*?)&quot;/,
303     constructor: function() {
304         this.callParent(arguments);
305
306         var me = this,
307             html = me.html,
308             argsRe = me.argsRe,
309             nameRe = me.nameRe,
310             ifRe = me.ifRe,
311             execRe = me.execRe,
312             id = 0,
313             tpls = [],
314             VALUES = 'values',
315             PARENT = 'parent',
316             XINDEX = 'xindex',
317             XCOUNT = 'xcount',
318             RETURN = 'return ',
319             WITHVALUES = 'with(values){ ',
320             m, matchName, matchIf, matchExec, exp, fn, exec, name, i;
321
322         html = ['&lt;tpl&gt;', html, '&lt;/tpl&gt;'].join('');
323
324         while ((m = html.match(argsRe))) {
325             exp = null;
326             fn = null;
327             exec = null;
328             matchName = m[0].match(nameRe);
329             matchIf = m[0].match(ifRe);
330             matchExec = m[0].match(execRe);
331
332             exp = matchIf ? matchIf[1] : null;
333             if (exp) {
334                 fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}');
335             }
336
337             exp = matchExec ? matchExec[1] : null;
338             if (exp) {
339                 exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}');
340             }
341
342             name = matchName ? matchName[1] : null;
343             if (name) {
344                 if (name === '.') {
345                     name = VALUES;
346                 } else if (name === '..') {
347                     name = PARENT;
348                 }
349                 name = Ext.functionFactory(VALUES, PARENT, 'try{' + WITHVALUES + RETURN + name + ';}}catch(e){return;}');
350             }
351
352             tpls.push({
353                 id: id,
354                 target: name,
355                 exec: exec,
356                 test: fn,
357                 body: m[1] || ''
358             });
359
360             html = html.replace(m[0], '{xtpl' + id + '}');
361             id = id + 1;
362         }
363
364         for (i = tpls.length - 1; i &gt;= 0; --i) {
365             me.compileTpl(tpls[i]);
366         }
367         me.master = tpls[tpls.length - 1];
368         me.tpls = tpls;
369     },
370
371     // @private
372     applySubTemplate: function(id, values, parent, xindex, xcount) {
373         var me = this, t = me.tpls[id];
374         return t.compiled.call(me, values, parent, xindex, xcount);
375     },
376 <span id='Ext-XTemplate-cfg-codeRe'>    /**
377 </span>     * @cfg {RegExp} codeRe The regular expression used to match code variables (default: matches &lt;tt&gt;{[expression]}&lt;/tt&gt;).
378      */
379     codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g,
380
381     re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g,
382
383     // @private
384     compileTpl: function(tpl) {
385         var fm = Ext.util.Format,
386             me = this,
387             useFormat = me.disableFormats !== true,
388             body, bodyReturn, evaluatedFn;
389
390         function fn(m, name, format, args, math) {
391             var v;
392             // name is what is inside the {}
393             // Name begins with xtpl, use a Sub Template
394             if (name.substr(0, 4) == 'xtpl') {
395                 return &quot;',this.applySubTemplate(&quot; + name.substr(4) + &quot;, values, parent, xindex, xcount),'&quot;;
396             }
397             // name = &quot;.&quot; - Just use the values object.
398             if (name == '.') {
399                 // filter to not include arrays/objects/nulls
400                 v = 'Ext.Array.indexOf([&quot;string&quot;, &quot;number&quot;, &quot;boolean&quot;], typeof values) &gt; -1 || Ext.isDate(values) ? values : &quot;&quot;';
401             }
402
403             // name = &quot;#&quot; - Use the xindex
404             else if (name == '#') {
405                 v = 'xindex';
406             }
407             else if (name.substr(0, 7) == &quot;parent.&quot;) {
408                 v = name;
409             }
410             // name has a . in it - Use object literal notation, starting from values
411             else if (name.indexOf('.') != -1) {
412                 v = &quot;values.&quot; + name;
413             }
414
415             // name is a property of values
416             else {
417                 v = &quot;values['&quot; + name + &quot;']&quot;;
418             }
419             if (math) {
420                 v = '(' + v + math + ')';
421             }
422             if (format &amp;&amp; useFormat) {
423                 args = args ? ',' + args : &quot;&quot;;
424                 if (format.substr(0, 5) != &quot;this.&quot;) {
425                     format = &quot;fm.&quot; + format + '(';
426                 }
427                 else {
428                     format = 'this.' + format.substr(5) + '(';
429                 }
430             }
431             else {
432                 args = '';
433                 format = &quot;(&quot; + v + &quot; === undefined ? '' : &quot;;
434             }
435             return &quot;',&quot; + format + v + args + &quot;),'&quot;;
436         }
437
438         function codeFn(m, code) {
439             // Single quotes get escaped when the template is compiled, however we want to undo this when running code.
440             return &quot;',(&quot; + code.replace(me.compileARe, &quot;'&quot;) + &quot;),'&quot;;
441         }
442
443         bodyReturn = tpl.body.replace(me.compileBRe, '\\n').replace(me.compileCRe, &quot;\\'&quot;).replace(me.re, fn).replace(me.codeRe, codeFn);
444         body = &quot;evaluatedFn = function(values, parent, xindex, xcount){return ['&quot; + bodyReturn + &quot;'].join('');};&quot;;
445         eval(body);
446
447         tpl.compiled = function(values, parent, xindex, xcount) {
448             var vs,
449                 length,
450                 buffer,
451                 i;
452
453             if (tpl.test &amp;&amp; !tpl.test.call(me, values, parent, xindex, xcount)) {
454                 return '';
455             }
456
457             vs = tpl.target ? tpl.target.call(me, values, parent) : values;
458             if (!vs) {
459                return '';
460             }
461
462             parent = tpl.target ? values : parent;
463             if (tpl.target &amp;&amp; Ext.isArray(vs)) {
464                 buffer = [];
465                 length = vs.length;
466                 if (tpl.exec) {
467                     for (i = 0; i &lt; length; i++) {
468                         buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
469                         tpl.exec.call(me, vs[i], parent, i + 1, length);
470                     }
471                 } else {
472                     for (i = 0; i &lt; length; i++) {
473                         buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
474                     }
475                 }
476                 return buffer.join('');
477             }
478
479             if (tpl.exec) {
480                 tpl.exec.call(me, vs, parent, xindex, xcount);
481             }
482             return evaluatedFn.call(me, vs, parent, xindex, xcount);
483         };
484
485         return this;
486     },
487
488 <span id='Ext-XTemplate-method-applyTemplate'>    /**
489 </span>     * Returns an HTML fragment of this template with the specified values applied.
490      * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
491      * @return {String} The HTML fragment
492      */
493     applyTemplate: function(values) {
494         return this.master.compiled.call(this, values, {}, 1, 1);
495     },
496
497 <span id='Ext-XTemplate-method-compile'>    /**
498 </span>     * Compile the template to a function for optimized performance.  Recommended if the template will be used frequently.
499      * @return {Function} The compiled function
500      */
501     compile: function() {
502         return this;
503     }
504 }, function() {
505 <span id='Ext-XTemplate-method-apply'>    /**
506 </span>     * Alias for {@link #applyTemplate}
507      * Returns an HTML fragment of this template with the specified values applied.
508      * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
509      * @return {String} The HTML fragment
510      * @member Ext.XTemplate
511      * @method apply
512      */
513     this.createAlias('apply', 'applyTemplate');
514 });
515 </pre>
516 </body>
517 </html>