var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /// <reference path="ITemplateOptions.ts" /> /// <reference path="../net/Uri.ts" /> /// <reference path="../base/BaseClass.ts" /> /// <reference path="../util/DomHelper.ts" /> /// <reference path="../lib-definitions/ejs.d.ts" /> /// <reference path="../ajax/Ajax.ts" /> var econda; (function (econda) { var templating; (function (templating) { var Uri = econda.net.Uri; var DomHelper = econda.util.DomHelper; /** * Wrapper for common template engines. Defaults to EJS template engine. Templates allow you * to render data to html using an html template. For details about the template syntax of ejs visit their website: <a href="http://embeddedjs.com/">http://embeddedjs.com/</a> * * * <h3>Example</h3> * * // content of /path/to/template.html * <div>Hello <%= firstName %> <%= lastName %></div> * * // content of /page/where_we_use_the_template.html * * var data = { * firstName: "Edgar", * lastName: "Gray" * }; * * var myTemplate = new econda.templating.Template({ * uri: "/path/to/template.html" * }); * var renderedHtml = myTemplate.render(data); * * // set as content of a div element or - just as an example: show a message box * alert(renderedHtml); * * * <h4>Example Template</h4> * * <% columns = 5; i = 0; attributes = {'brand': '', 'arcticleno': 'Art.No.:'} %> * <div class="ec-widget"> * <div class="ec-widget-products"> * <div class="ec-widget-title">Recommendations</div> * <% for (act in products) { if (i == 0) { %> * <ul class="ec-widget-grid"> * <% } %> * <li class="ec-widget-list"> * <div class="ec-widget-image"><a href="<%= products[act].deeplink %>" title="<%= products[act].name %>"><img src="<%= products[act].iconurl %>" alt="<%= products[act].name %>" /> </a></div> * <div class="ec-widget-name"><a href="<%= products[act].deeplink %>" title="<%= products[act].name %>"><%= products[act].name %></a></div> * <div class="ec-widget-price"><%= products[act].price %></div> * <% for (attr in attributes) { if (products[act][attr]) { %> * <div class="ec-widget-attribute"><%= attributes[attr] %> <%= products[act][attr] %></div> * <% }} %> * </li> * <% i++; if (i == columns) {i= 0 %> * </ul> * <% }} %> * </div> * * * @class econda.templating.Template * @extends econda.base.BaseClass * @author Edgar Gaiser */ var Template = (function (_super) { __extends(Template, _super); function Template(cfg) { _super.call(this); /** * Instance reference of (ejs) template engine * @private */ // _engineInstance: any = null; /** * @cfg {econda.net.Uri} uri * @accessor * Uri from where we have to load the html template. Should be an absolute path (e.g. "/path/to/my_template.html"). */ this.uri = null; /** * Template source code if not loaded from server. * @cfg {String} template * @accessor */ this.template = null; /** * @cfg {String} [engine="ejs"] * @accessor * Renderer engine to use. The only supported one is ejs. Please send us a feature request * if you prefer another engine. */ this.engine = "ejs"; /** * @cfg {String} element * @accessor * HTML element or Id (or CSS path if jQuery is installed) to read the template source from. If the element contains an HTML comment tag, content of the first * comment tag inside the referenced or given HTML element is used as template source. * * <div id="mytemplate"> * <!-- * <div>This is my template</div> * --> * </div> */ this._element = null; if (cfg instanceof Template) { return cfg; } this.initConfig(cfg, "uri"); } Template.prototype.getUri = function () { return this.uri; }; Template.prototype.setUri = function (uri) { this.uri = new Uri(uri); return this; }; Template.prototype.getTemplate = function () { return this.template; }; Template.prototype.setTemplate = function (source) { this.template = source; return this; }; Template.prototype.getEngine = function () { return this.engine; }; Template.prototype.setEngine = function (name) { name = name.toLowerCase(); if (name != "ejs") { throw "It's not possible to change the template engine in this version."; } return this; }; Template.prototype.getElement = function () { return this._element; }; Template.prototype.setElement = function (element) { this._element = element; return this; }; /** * Render this template with given values * @param {Object} data * @param {Function} success * @param {Function} error */ Template.prototype.render = function (data, success, error) { if (data === void 0) { data = null; } if (success === void 0) { success = null; } if (error === void 0) { error = null; } var templateUri = this.getUri(), template = this.getTemplate(), sourceElement = this.getElement(); if (!templateUri && !template && !sourceElement) { error("Cannot render template: No template or uri found."); return; } // read from dom if needed if (!template && sourceElement) { var templateSource = this._readTemplateSourceFromDom(sourceElement); if (templateSource) { template = templateSource; } } if (!template && templateUri) { // check cache var templateFn = ejs.cache.get(templateUri.toString()); if (templateFn && success) { success(templateFn(data)); } else { // load async econda.ajax.Ajax.request({ uri: templateUri.toString(), method: 'GET', success: function (template) { var templateFn = function (data) { var result; try { result = ejs.render(template, data, { escape: function (str) { return str; } }); if (success) { success(result); } } catch (e) { if (error) { error(e); } else { console.warn(e); } } return result; }; ejs.cache.set(templateUri.toString(), templateFn); templateFn(data); }, error: error ? function () { error('error loading template'); } : null }); } // abort because we found cached data or we load it async return; } // compile given html template if (template) { var result; try { result = ejs.render(template, data, { escape: function (str) { return str; } }); if (success) { success(result); } } catch (e) { if (error) { error(e); } else { console.warn(e); } } return result; } error('error loading template'); return; }; Template.prototype._readTemplateSourceFromDom = function (element) { var e = DomHelper.element(element); var encodedTemplate = null; if (!e) { return null; } encodedTemplate = e.innerHTML; for (var i = 0; i < e.childNodes.length; i++) { if (e.childNodes[i].nodeType == 8) { encodedTemplate = e.childNodes[i].textContent; break; } } // decode template tags return encodedTemplate.trim().replace('<%', '<%').replace('%>', '%>'); }; return Template; }(econda.base.BaseClass)); templating.Template = Template; // end of class })(templating = econda.templating || (econda.templating = {})); })(econda || (econda = {})); // end of module