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