/** * @class Ext.XTemplate * @extend Ext.Template * A template class that supports advanced functionality like: * * - Auto-filling arrays using templates and sub-templates * - Conditional processing with basic comparison operators * - Basic math function support * - Execute arbitrary inline code with special built-in template variables * - Custom member functions * - Many special tags and built-in operators that aren't defined as part of the API, but are supported in the templates that can be created * * XTemplate provides the templating mechanism built into {@link Ext.view.View}. * * The {@link Ext.Template} describes the acceptable parameters to pass to the constructor. The following examples * demonstrate all of the supported features. * * # Sample Data * * This is the data object used for reference in each code example: * * var data = { * name: 'Don Griffin', * title: 'Senior Technomage', * company: 'Sencha Inc.', * drinks: ['Coffee', 'Water', 'More Coffee'], * kids: [ * { name: 'Aubrey', age: 17 }, * { name: 'Joshua', age: 13 }, * { name: 'Cale', age: 10 }, * { name: 'Nikol', age: 5 }, * { name: 'Solomon', age: 0 } * ] * }; * * # Auto filling of arrays * * The **tpl** tag and the **for** operator are used to process the provided data object: * * - If the value specified in for is an array, it will auto-fill, repeating the template block inside the tpl * tag for each item in the array. * - If for="." is specified, the data object provided is examined. * - If between="..." is specified, the provided value will be inserted between the items. * This is also supported in the "foreach" looping template. * - While processing an array, the special variable {#} will provide the current array index + 1 (starts at 1, not 0). * * Examples: * * <tpl for=".">...</tpl> // loop through array at root node * <tpl for="foo">...</tpl> // loop through array at foo node * <tpl for="foo.bar">...</tpl> // loop through array at foo.bar node * <tpl for="." between=",">...</tpl> // loop through array at root node and insert ',' between each item * * Using the sample data above: * * var tpl = new Ext.XTemplate( * '<p>Kids: ', * '<tpl for=".">', // process the data.kids node * '<p>{#}. {name}</p>', // use current array index to autonumber * '</tpl></p>' * ); * tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object * * An example illustrating how the **for** property can be leveraged to access specified members of the provided data * object to populate the template: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Title: {title}</p>', * '<p>Company: {company}</p>', * '<p>Kids: ', * '<tpl for="kids">', // interrogate the kids property within the data * '<p>{name}</p>', * '</tpl></p>' * ); * tpl.overwrite(panel.body, data); // pass the root node of the data object * * Flat arrays that contain values (and not objects) can be auto-rendered using the special **`{.}`** variable inside a * loop. This variable will represent the value of the array at the current index: * * var tpl = new Ext.XTemplate( * '<p>{name}\'s favorite beverages:</p>', * '<tpl for="drinks">', * '<div> - {.}</div>', * '</tpl>' * ); * tpl.overwrite(panel.body, data); * * When processing a sub-template, for example while looping through a child array, you can access the parent object's * members via the **parent** object: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<tpl if="age > 1">', * '<p>{name}</p>', * '<p>Dad: {parent.name}</p>', * '</tpl>', * '</tpl></p>' * ); * tpl.overwrite(panel.body, data); * * The **foreach** operator is used to loop over an object's properties. The following * example demonstrates looping over the main data object's properties: * * var tpl = new Ext.XTemplate( * '<dl>', * '<tpl foreach=".">', * '<dt>{$}</dt>', // the special **`{$}`** variable contains the property name * '<dd>{.}</dd>', // within the loop, the **`{.}`** variable is set to the property value * '</tpl>', * '</dl>' * ); * tpl.overwrite(panel.body, data); * * # Conditional processing with basic comparison operators * * The **tpl** tag and the **if** operator are used to provide conditional checks for deciding whether or not to render * specific parts of the template. * * Using the sample data above: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<tpl if="age > 1">', * '<p>{name}</p>', * '</tpl>', * '</tpl></p>' * ); * tpl.overwrite(panel.body, data); * * More advanced conditionals are also supported: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<p>{name} is a ', * '<tpl if="age >= 13">', * '<p>teenager</p>', * '<tpl elseif="age >= 2">', * '<p>kid</p>', * '<tpl else>', * '<p>baby</p>', * '</tpl>', * '</tpl></p>' * ); * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<p>{name} is a ', * '<tpl switch="name">', * '<tpl case="Aubrey" case="Nikol">', * '<p>girl</p>', * '<tpl default>', * '<p>boy</p>', * '</tpl>', * '</tpl></p>' * ); * * A `break` is implied between each case and default, however, multiple cases can be listed * in a single <tpl> tag. * * # Using double quotes * * Examples: * * var tpl = new Ext.XTemplate( * "<tpl if='age > 1 && age < 10'>Child</tpl>", * "<tpl if='age >= 10 && age < 18'>Teenager</tpl>", * "<tpl if='this.isGirl(name)'>...</tpl>", * '<tpl if="id == \'download\'">...</tpl>', * "<tpl if='needsIcon'><img src='{icon}' class='{iconCls}'/></tpl>", * "<tpl if='name == \"Don\"'>Hello</tpl>" * ); * * # Basic math support * * The following basic math operators may be applied directly on numeric data values: * * + - * / * * For example: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<tpl if="age > 1">', // <-- Note that the > is encoded * '<p>{#}: {name}</p>', // <-- Auto-number each item * '<p>In 5 Years: {age+5}</p>', // <-- Basic math * '<p>Dad: {parent.name}</p>', * '</tpl>', * '</tpl></p>' * ); * tpl.overwrite(panel.body, data); * * # Execute arbitrary inline code with special built-in template variables * * Anything between `{[ ... ]}` is considered code to be executed in the scope of the template. * The expression is evaluated and the result is included in the generated result. There are * some special variables available in that code: * * - **out**: The output array into which the template is being appended (using `push` to later * `join`). * - **values**: The values in the current scope. If you are using scope changing sub-templates, * you can change what values is. * - **parent**: The scope (values) of the ancestor template. * - **xindex**: If you are in a "for" or "foreach" looping template, the index of the loop you are in (1-based). * - **xcount**: If you are in a "for" looping template, the total length of the array you are looping. * - **xkey**: If you are in a "foreach" looping template, the key of the current property * being examined. * * This example demonstrates basic row striping using an inline code block and the xindex variable: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">', * '{name}', * '</div>', * '</tpl></p>' * ); * * Any code contained in "verbatim" blocks (using "{% ... %}") will be inserted directly in * the generated code for the template. These blocks are not included in the output. This * can be used for simple things like break/continue in a loop, or control structures or * method calls (when they don't produce output). The `this` references the template instance. * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '{% if (xindex % 2 === 0) continue; %}', * '{name}', * '{% if (xindex > 100) break; %}', * '</div>', * '</tpl></p>' * ); * * # Template member functions * * One or more member functions can be specified in a configuration object passed into the XTemplate constructor for * more complex processing: * * var tpl = new Ext.XTemplate( * '<p>Name: {name}</p>', * '<p>Kids: ', * '<tpl for="kids">', * '<tpl if="this.isGirl(name)">', * '<p>Girl: {name} - {age}</p>', * '<tpl else>', * '<p>Boy: {name} - {age}</p>', * '</tpl>', * '<tpl if="this.isBaby(age)">', * '<p>{name} is a baby!</p>', * '</tpl>', * '</tpl></p>', * { * // XTemplate configuration: * disableFormats: true, * // member functions: * isGirl: function(name){ * return name == 'Aubrey' || name == 'Nikol'; * }, * isBaby: function(age){ * return age < 1; * } * } * ); * tpl.overwrite(panel.body, data); */ /** * @cfg {Boolean} compiled * Only applies to {@link Ext.Template}, XTemplates are compiled automatically on the * first call to {@link #apply} or {@link #applyOut}. * @hide */ /** * @cfg {String/Array} definitions * Optional. A statement, or array of statements which set up `var`s which may then * be accessed within the scope of the generated function. * * var data = { * name: 'Don Griffin', * isWizard: true, * title: 'Senior Technomage', * company: 'Sencha Inc.' * }; * * var tpl = new Ext.XTemplate('{[values.isWizard ? wizard : notSoWizard]}' + * ' {name}', { * definitions: 'var wizard = "Wizard", notSoWizard = "Townsperson";' * }); * * console.log(tpl.apply(data)); * // LOGS: Wizard Don Griffin */ /** * @property {Function} fn * The function that applies this template. This is created on first use of the * template (calls to `apply` or `applyOut`). * @private * @readonly */ /** * @cfg {Boolean} [strict=false] * Expressions in templates that traverse "dot paths" and fail (due to `null` at some * stage) have always been expanded as empty strings. This is convenient in most cases * but doing so can also mask errors in the template. Setting this to `true` changes * this default so that any expression errors will be thrown as exceptions. */