API Docs for: 3.13.0
Show:

File: template/js/template-base.js

  1. /**
  2. Virtual rollup of the `template-base` and `template-micro` modules.
  3.  
  4. @module template
  5. @main template
  6. @since 3.8.0
  7. **/
  8.  
  9. /**
  10. Provides a generic API for using template engines such as Handlebars and
  11. `Y.Template.Micro`.
  12.  
  13. @module template
  14. @submodule template-base
  15. @since 3.8.0
  16. **/
  17.  
  18. /**
  19. Provides a generic API for using template engines such as Handlebars and
  20. `Y.Template.Micro`.
  21.  
  22. ### Examples
  23.  
  24. Using with `Y.Template.Micro` (the default template engine):
  25.  
  26. YUI().use('template', function (Y) {
  27. var micro = new Y.Template(),
  28. html = micro.render('<%= data.message %>', {message: 'hello!'});
  29.  
  30. // ...
  31. });
  32.  
  33. Using with Handlebars:
  34.  
  35. YUI().use('template-base', 'handlebars', function (Y) {
  36. var handlebars = new Y.Template(Y.Handlebars),
  37. html = handlebars.render('{{message}}', {message: 'hello!'});
  38.  
  39. // ...
  40. });
  41.  
  42. @class Template
  43. @param {Mixed} [engine=Y.Template.Micro] Template engine to use, such as
  44. `Y.Template.Micro` or `Y.Handlebars`. Defaults to `Y.Template.Micro` if not
  45. specified.
  46. @param {Object} [defaults] Default options to use when instance methods are
  47. invoked.
  48. @constructor
  49. @since 3.8.0
  50. **/
  51.  
  52. function Template(engine, defaults) {
  53. /**
  54. Default options.
  55.  
  56. @property {Object} defaults
  57. @since 3.8.1
  58. **/
  59. this.defaults = defaults;
  60.  
  61. /**
  62. Template engine class.
  63.  
  64. @property {Mixed} engine
  65. @since 3.8.0
  66. **/
  67. this.engine = engine || Y.Template.Micro;
  68.  
  69. if (!this.engine) {
  70. Y.error('No template engine loaded.');
  71. }
  72. }
  73.  
  74. /**
  75. Registry that maps template names to revived template functions.
  76.  
  77. @property _registry
  78. @type Object
  79. @static
  80. @protected
  81. @since 3.12.0
  82. **/
  83. Template._registry = {};
  84.  
  85. /**
  86. Registers a pre-compiled template into the central template registry with a
  87. given template string, allowing that template to be called and rendered by
  88. that name using the `Y.Template.render()` static method.
  89.  
  90. For example, given the following simple Handlebars template, in `foo.hbs`:
  91. @example
  92. <p>{{tagline}}</p>
  93.  
  94. It can be precompiled using the Handlebars CLI, and added into a YUI module
  95. in the following way. Alternatively, `locator` can be used to automate this
  96. process for you:
  97. @example
  98. YUI.add('templates-foo', function (Y) {
  99.  
  100. var engine = new Y.Template(Y.Handlebars),
  101. precompiled;
  102.  
  103. precompiled = // Long precompiled template function here //
  104.  
  105. Y.Template.register('foo', engine.revive(precompiled));
  106.  
  107. }, '0.0.1', {requires: ['template-base', 'handlebars-base']});
  108.  
  109. See the `Y.Template#render` method to see how a registered template is used.
  110.  
  111. @method register
  112. @param {String} templateName The template name.
  113. @param {Function} template The function that returns the rendered string. The
  114. function should take the following parameters. If a pre-compiled template
  115. does not accept these parameters, it is up to the developer to normalize it.
  116. @param {Object} [template.data] Data object to provide when rendering the
  117. template.
  118. @param {Object} [template.options] Options to pass along to the template
  119. engine. See template engine docs for options supported by each engine.
  120. @return {Function} revivedTemplate This is the same function as in `template`,
  121. and is done to maintain compatibility with the `Y.Template#revive()` method.
  122. @static
  123. @since 3.12.0
  124. **/
  125. Template.register = function (templateName, template) {
  126. Template._registry[templateName] = template;
  127. return template;
  128. };
  129.  
  130. /**
  131. Returns the registered template function, given the template name. If an
  132. unregistered template is accessed, this will return `undefined`.
  133.  
  134. @method get
  135. @param {String} templateName The template name.
  136. @return {Function} revivedTemplate The revived template function, or `undefined`
  137. if it has not been registered.
  138. @static
  139. @since 3.12.0
  140. **/
  141.  
  142. Template.get = function (templateName) {
  143. return Template._registry[templateName];
  144. }
  145.  
  146. /**
  147. Renders a template into a string, given the registered template name and data
  148. to be interpolated. The template name must have been registered previously with
  149. `register()`.
  150.  
  151. Once the template has been registered and built into a YUI module, it can be
  152. listed as a dependency for any other YUI module. Continuing from the above
  153. example, the registered template can be used in the following way:
  154.  
  155. @example
  156. YUI.add('bar', function (Y) {
  157.  
  158. var html = Y.Template.render('foo', {
  159. tagline: '"bar" is now template language agnostic'
  160. });
  161.  
  162. }, '0.0.1', {requires: ['template-base', 'templates-foo']});
  163.  
  164. The template can now be used without having to know which specific rendering
  165. engine generated it.
  166.  
  167. @method render
  168. @param {String} templateName The abstracted name to reference the template.
  169. @param {Object} [data] The data to be interpolated into the template.
  170. @param {Object} [options] Any additional options to be passed into the template.
  171. @return {String} output The rendered result.
  172. @static
  173. @since 3.12.0
  174. **/
  175. Template.render = function (templateName, data, options) {
  176. var template = Template._registry[templateName],
  177. result = '';
  178.  
  179. if (template) {
  180. result = template(data, options);
  181. } else {
  182. Y.error('Unregistered template: "' + templateName + '"');
  183. }
  184.  
  185. return result;
  186. };
  187.  
  188. Template.prototype = {
  189. /**
  190. Compiles a template with the current template engine and returns a compiled
  191. template function.
  192.  
  193. @method compile
  194. @param {String} text Template text to compile.
  195. @param {Object} [options] Options to pass along to the template engine. See
  196. template engine docs for options supported by each engine.
  197. @return {Function} Compiled template function.
  198. @since 3.8.0
  199. **/
  200. compile: function (text, options) {
  201. options = options ? Y.merge(this.defaults, options) : this.defaults;
  202. return this.engine.compile(text, options);
  203. },
  204.  
  205. /**
  206. Precompiles a template with the current template engine and returns a string
  207. containing JavaScript source code for the precompiled template.
  208.  
  209. @method precompile
  210. @param {String} text Template text to compile.
  211. @param {Object} [options] Options to pass along to the template engine. See
  212. template engine docs for options supported by each engine.
  213. @return {String} Source code for the precompiled template.
  214. @since 3.8.0
  215. **/
  216. precompile: function (text, options) {
  217. options = options ? Y.merge(this.defaults, options) : this.defaults;
  218. return this.engine.precompile(text, options);
  219. },
  220.  
  221. /**
  222. Compiles and renders a template with the current template engine in a single
  223. step, and returns the rendered result.
  224.  
  225. @method render
  226. @param {String} text Template text to render.
  227. @param {Object} data Data object to provide when rendering the template.
  228. @param {Object} [options] Options to pass along to the template engine. See
  229. template engine docs for options supported by each engine.
  230. @return {String} Rendered result.
  231. @since 3.8.0
  232. **/
  233. render: function (text, data, options) {
  234. options = options ? Y.merge(this.defaults, options) : this.defaults;
  235.  
  236. if (this.engine.render) {
  237. return this.engine.render(text, data, options);
  238. }
  239.  
  240. return this.engine.compile(text, options)(data, options);
  241. },
  242.  
  243. /**
  244. Revives a precompiled template function into an executable template function
  245. using the current template engine. The precompiled code must already have
  246. been evaluated; this method won't evaluate it for you.
  247.  
  248. @method revive
  249. @param {Function} precompiled Precompiled template function.
  250. @param {Object} [options] Options to pass along to the template engine. See
  251. template engine docs for options supported by each engine.
  252. @return {Function} Compiled template function.
  253. @since 3.8.0
  254. **/
  255. revive: function (precompiled, options) {
  256. options = options ? Y.merge(this.defaults, options) : this.defaults;
  257.  
  258. return this.engine.revive ? this.engine.revive(precompiled, options) :
  259. precompiled;
  260. }
  261. };
  262.  
  263. // Copy existing namespaced properties from Y.Template to the Template function
  264. // if Y.Template already exists, then make the function the new Y.Template.
  265. // This ensures that other modules can safely add stuff to the Y.Template
  266. // namespace even if they're loaded before this one.
  267. Y.Template = Y.Template ? Y.mix(Template, Y.Template) : Template;
  268.