src/cm/media/js/lib/yui/yui_3.10.3/docs/template/index.html
author Yves-Marie Haussonne <ymh.work+github@gmail.com>
Fri, 09 May 2014 18:35:26 +0200
changeset 656 a84519031134
parent 525 89ef5ed3c48b
permissions -rw-r--r--
add link to "privacy policy" in the header test

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Template</title>
    <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic">
    <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css">
    <link rel="stylesheet" href="../assets/css/main.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
    <script src="../../build/yui/yui-min.js"></script>
    
</head>
<body>
<!--
<a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
-->
<div id="doc">
    <div id="hd">
        <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1>
    </div>
    
        <a href="#toc" class="jump">Jump to Table of Contents</a>
    

            <h1>Template</h1>
    <div class="yui3-g">
        <div class="yui3-u-3-4">
            <div id="main">
                <div class="content"><style scoped>
.micro-code pre.code {
    height: 100%;
    margin: 0;
}

.micro-code td,
.micro-code th {
    background: #fff;
    padding: 0 0 0 12px;
}

.micro-code td:first-child,
.micro-code th:first-child {
    padding-left: 0;
}
</style>

<div class="intro">
<p>
The Template component provides <code>Y.Template</code>, a generic template engine API, and <code>Y.Template.Micro</code>, a string-based micro-templating language similar to <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/erb/rdoc/ERB.html">ERB</a> and <a href="http://underscorejs.org/#template">Underscore</a> templates.
</p>
</div>

<h2 id="getting-started">Getting Started</h2>

<p>
To include the source files for Template and its dependencies, first load
the YUI seed file if you haven't already loaded it.
</p>

<pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.10.3&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>


<p>
Next, create a new YUI instance for your application and populate it with the
modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
YUI will automatically load any dependencies required by the modules you
specify.
</p>

<pre class="code prettyprint">&lt;script&gt;
&#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
YUI().use(&#x27;template&#x27;, function (Y) {
    &#x2F;&#x2F; Template is available and ready for use. Add implementation
    &#x2F;&#x2F; code here.
});
&lt;&#x2F;script&gt;</pre>


<p>
For more information on creating YUI instances and on the
<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
documentation for the <a href="../yui/index.html">YUI Global Object</a>.
</p>


<h2 id="using-template">Using <code>Template</code></h2>

<h3 id="quick-start">Quick Start</h3>

<p>
A template engine takes a template&mdash;usually in the form of a string&mdash;and some data, and renders the data into the template to produce an HTML or text string. Using templates to keep markup and structure separate from content encourages reuse and can make code easier to read and maintain, and in many cases faster.
</p>

<p>
<code>Y.Template</code> provides a common API that can be used to compile and render templates with a variety of template engines. The two template engines included in YUI are <a href="../handlebars/index.html">Handlebars</a> and <a href="#using-templatemicro">Template.Micro</a>.
</p>

<p>
The quickest way to get started is using the <code>template</code> module which will load both the <code>template-base</code> and <code>template-micro</code> modules. The following example shows the most basic usage with the <code>Y.Template.Micro</code> engine (the default template engine):
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template&#x27;, function (Y) {
    var micro = new Y.Template(),
        html  = micro.render(&#x27;&lt;i&gt;&lt;%= this.message %&gt;&lt;&#x2F;i&gt;&#x27;, {message: &#x27;hello!&#x27;});

    Y.log(html); &#x2F;&#x2F; =&gt; &quot;&lt;i&gt;hello!&lt;&#x2F;i&gt;&quot;
});</pre>


<p>
In the above example, <code>micro</code> is an instance of a template engine backed by Template.Micro. The <code>Y.Template()</code> constructor provides an abstraction over the backing engine, giving the engine instances a uniform API.
</p>

<p>
Handlebars templates can be used instead of Micro templates by using the <code>template-base</code> and <code>handlebars</code> modules. The following example shows how to generate the same output as the above example with the Handlebars engine:
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template-base&#x27;, &#x27;handlebars&#x27;, function (Y) {
    var handlebars = new Y.Template(Y.Handlebars),
        html       = handlebars.render(&#x27;&lt;i&gt;{{message}}&lt;&#x2F;i&gt;&#x27;, {message: &#x27;hello!&#x27;});

    Y.log(html); &#x2F;&#x2F; =&gt; &quot;&lt;i&gt;hello!&lt;&#x2F;i&gt;&quot;
});</pre>


<p>
<strong>Note:</strong> Both examples are using the engine's <strong><code>render()</code></strong> method to compile and render the template dynamically on the <strong>client</strong>, doing this with Micro templates is fine, but it should be <strong>avoided with Handlebars</strong> templates. It is recommended that Handlebars templates be <a href="../handlebars/index.html#precompiling-templates">precompiled</a>, enabling the client code to use the lighter and faster <code>handlebars-base</code> module.
</p>

<h3 id="generic-template-api">Generic Template API</h3>

<p>
<code>Y.Template</code> exists specifically to provide its API as a normalization layer on top of conceptually similar, but technically different template engines and syntaxes. This layer of abstraction allows components which work with templates to not be tied to a particular engine. Another huge benefit is allowing developers to override a component's default templates using an entirely different template engine.
</p>

<p>
The two template engines provided in YUI, Handlebars and Template.Micro, are conceptually similar. They both compile string-based templates into functions, which are invoked with a data context and return the rendered output as a string. Handlebars is really well suited for organizing and managing the templates of an entire app or complex widget because of its partials and helpers features. Template.Micro is great for small templates, or when you need more powerful templates and its compilation engine is <em>extremely</em> small.
</p>

<p>
By making Template.Micro's public API very similar to Handlebars, we've made it possible to use the two template engines interchangeably via the <code>Y.Template</code> normalization API. When you need to compile templates on the client, it is <strong>strongly recommend</strong> that you use Micro templates, because Template.Micro's compiler is <em>much</em> smaller than Handlebars' compiler &mdash; 0.5KB vs 9KB (minified and gzipped) respectively.
</p>

<h3 id="instantiating-a-template-engine">Instantiating a Template Engine</h3>

<p>
While you can use a specific template engine directly, it is recommended that you create an instance of the generic <code>Y.Template</code> engine wrapper. Doing so allows for greater flexibility and interoperability as described in the previous section.
</p>

<p>
To create a template engine instance, you must first determine which underlying engine you want to use. The two template engines included in YUI are <a href="../handlebars/index.html">Handlebars</a> and <a href="#using-templatemicro">Template.Micro</a>. If you're looking to use a different engine, refer to <a href="#creating-a-custom-template-engine">Creating a Custom Template Engine</a> section below.
</p>

<p>
Once you've determined the underlying template engine, you'll need to load the appropriate YUI module to fulfill how you plan to use templates. Refer to the following table of YUI modules to understand what each module provides:
</p>

<table>
    <thead>
        <tr>
            <th>Module</th>
            <th>Compiler</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td style="white-space: nowrap;"><code>template-base</code></td>
            <td>No</td>
            <td>
                <p>
                Provides a generic API for using template engines such as <code>Handlebars</code> and <code>Y.Template.Micro</code>.
                </p>
            </td>
        </tr>
        <tr>
            <td style="white-space: nowrap;"><code>template-micro</code></td>
            <td>Yes</td>
            <td>
                <p>
                Adds the <code>Y.Template.Micro</code> template engine, which provides fast, simple string-based micro-templating similar to ERB or Underscore templates.
                </p>
            </td>
        </tr>
        <tr>
            <td style="white-space: nowrap;"><code>template</code></td>
            <td>Yes</td>
            <td>
                <p>
                Virtual rollup of the <code>template-base</code> and <code>template-micro</code> modules.
                </p>
            </td>
        </tr>
        <tr>
            <td style="white-space: nowrap;"><code>handlebars-base</code></td>
            <td>No</td>
            <td>
                <p>
                Provides basic Handlebars template rendering functionality. Use this module when you only need to render pre-compiled templates.
                </p>
            </td>
        </tr>
        <tr>
            <td style="white-space: nowrap;"><code>handlebars-compiler</code></td>
            <td>Yes</td>
            <td>
                <p>
                Handlebars parser and compiler. Use this module when you need to compile Handlebars templates.
                </p>
            </td>
        </tr>
        <tr>
            <td style="white-space: nowrap;"><code>handlebars</code></td>
            <td>Yes</td>
            <td>
                <p>
                Virtual rollup of the <code>handlebars-base</code> and <code>handlebars-compiler</code> modules.
                </p>
            </td>
        </tr>
    </tbody>
</table>

<h4 id="using-micro-templates">Using Micro Templates</h4>

<p>
When working with Micro templates, it's easiest to use the <code>template</code> virtual rollup module. The <code>Y.Template.Micro</code> compiler is small enough that it is included with the runtime functionality.
</p>

<p>
The following example creates two template engine instances with are functionally equivalent and both backed by Template.Micro:
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template&#x27;, function (Y) {
    var microExplicit, microDefault;

    &#x2F;&#x2F; Creates a template engine instance and explicitly specifies the
    &#x2F;&#x2F; underlying engine.
    microExplicit = new Y.Template(Y.Template.Micro);

    &#x2F;&#x2F; Creates another template engine instance with the same functionality,
    &#x2F;&#x2F; but relies on &#x60;Y.Template.Micro&#x60; being defined as the underlying engine
    &#x2F;&#x2F; by default.
    microDefault = new Y.Template();
});</pre>


<h4 id="using-handlebars-templates">Using Handlebars Templates</h4>

<p>
When working with Handlebars templates, you'll need to determine if the need the Handlebars compiler functionality provided by the <code>handlebars-compiler</code> module. It is recommended that Handlebars templates be <a href="../handlebars/index.html#precompiling-templates">precompiled</a>, enabling the client code to use the lighter and faster <code>handlebars-base</code> module.
</p>

<p>
The following example loads only the Handlebars runtime and generic <code>Y.Template()</code> wrapper API. It assumes that all templates have previously been precompiled on the server or during a build step:
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template-base&#x27;, &#x27;handlebars-base&#x27;, function (Y) {
    &#x2F;&#x2F; Creates a limited template engine instance using Handlebars as the
    &#x2F;&#x2F; underlaying engine, but with only the runtime functionality.
    var handlebars = new Y.Template(Y.Handlebars);
});</pre>


<p>
<strong>Note:</strong> In the above example, the <code>handlebars</code> engine does <strong>not</strong> have the ability to <code>render()</code>, <code>compile()</code>, or <code>precompile()</code> template. It only has the ability to <code>revive()</code> and execute precompiled templates.
</p>

<p>
The following example, uses the <code>handlebars</code> virtual rollup module which includes the <code>handlebars-compiler</code>. This enables the Handlebars-backed template engine instances to use the <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html">full API</a>:
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template-base&#x27;, &#x27;handlebars&#x27;, function (Y) {
    &#x2F;&#x2F; Creates a template engine instance using Handlebars as the underlaying
    &#x2F;&#x2F; engine, with both the runtime and compiler functionality.
    var handlebars = new Y.Template(Y.Handlebars);
});</pre>


<h3 id="compiling-and-rendering-templates">Compiling and Rendering Templates</h3>

<p>
Both Handlebars and Micro templates must be compiled before they can be rendered. One benefit of this is that a template only needs to be compiled once, and it can then be rendered multiple times without being recompiled. Templates can even be <a href="#precompiling-and-reviving-templates">precompiled</a> on the server or at build time and then rendered on the client for optimal performance.
</p>

<p>
Before compiling a template string, a template engine needs to be created. Once the engine instance has been created, the template string can be passed to its <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html#method_compile"><code>compile()</code></a> method. What's returned is a reusable function.
</p>

<pre class="code prettyprint lang-javascript">var engine, template;

&#x2F;&#x2F; Create a Template.Micro engine instance.
engine = new Y.Template();

&#x2F;&#x2F; Compile a template into a reusable function.
template = engine.compile(&#x27;My favorite animal is a &lt;%= this.animal %&gt;.&#x27;);</pre>


<p>
When you're ready to render the template, execute the function and pass in some data. You'll get back a rendered string.
</p>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Render a previously compiled template.
var output = template({animal: &#x27;Rhino&#x27;});
Y.log(output); &#x2F;&#x2F; =&gt; &quot;My favorite animal is a Rhino.&quot;</pre>


<p>
You can re-render the template at any time just by calling the function again. You can even pass in completely different data.
</p>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Re-render a previously compiled template.
output = template({animal: &#x27;Spotted Cuscus&#x27;});
Y.log(output); &#x2F;&#x2F; =&gt; &quot;My favorite animal is a Spotted Cuscus.&quot;</pre>


<p>
If you don't plan to use a template more than once, you can compile and render it in a single step with the template engine's <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html#method_render"><code>render()</code></a> method.
</p>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Compile and render a template in a single step.
output = engine.render(&#x27;My favorite animal is a &lt;%= this.animal %&gt;.&#x27;, {animal: &#x27;Rhino&#x27;});
Y.log(output); &#x2F;&#x2F; =&gt; &quot;My favorite animal is a Rhino.&quot;</pre>


<p>
<strong> Note:</strong> The above examples are using Micro templates. If these examples used Handlebars templates, the <code>engine</code> instance would have been created using <code>Y.Handlebars</code>, and template syntax would have used <code>{{animal}}</code> instead of <code>&lt;%= this.animal %&gt;</code>.
</p>

<h3 id="precompiling-and-reviving-templates">Precompiling and Reviving Templates</h3>

<p>
Since Micro and Handlebars templates can be compiled and rendered in separate steps, it's possible to precompile a template for use later. You can precompile a template into raw JavaScript on the server (or even on the command line in the case of Handlebars), serve this precompiled JavaScript template to the client, and then render it on the client using any data the client has at its disposal.
</p>

<p>
The main benefit of precompilation is performance. Not only does the client not need to go through the compile step, but if your using a template engine like Handlebars, you don't even have to load the compiler on the client! All the client needs in order to render a precompiled template is the engine's runtime. In the case of Handlebars this is a 9KB (minified and gzipped) savings.
</p>

<p>
<code>Y.Template</code> engine instances have a <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html#method_precompile"><code>precompile()</code> method</a> which uses the underlaying <code>engine</code> to convert the specified <code>text</code> into a string of JavaScript source code. This string of code which represents the template, can later be revived using the engine instance's <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html#method_revive"><code>revive()</code> method</a> which turns it into a JavaScript function.
</p>

<p>
The <code>precompile()</code> method differs from the <code>compile()</code> method in a couple of important ways:
</p>

<ul>
<li>
    <p>
    The <code>precompile()</code> method returns a string of JavaScript code that's meant to be parsed and executed later, whereas <code>compile()</code> returns a live JavaScript function.
    </p>
</li>
<li>
    <p>
    The code returned by the <code>precompile()</code> method contains no references to any outside objects. Once it's evaluated, the resulting precompiled function must be passed to <code>Y.Template</code> engine instance's <code>revive()</code> method, which will "rehydrate" it into an executable template function using the current template engine.
    </p>
</li>
</ul>

<p>
For more details, refer to the Precompiling and Reviving Templates sections of the <a href="#precompiling-and-reviving-micro-templates">Template.Micro</a> and <a href="../handlebars/index.html#precompiling-templates">Handlebars</a> user guides.
</p>

<h3 id="creating-a-custom-template-engine">Creating a Custom Template Engine</h3>

<p>
The generic <code>Y.Template</code> interface is <a href="#generic-template-api">designed</a> to work with a variety of string -> function template engines. To implement a custom underlaying template engine for <code>Y.Template</code>, refer to the following list of methods and their descriptions which need to be implemented:
</p>

<dl>
    <dt><code>compile( text , [options] )</code></dt>
    <dd>
        <p>
        Compiles a string template into a reusable function and returns that function to the caller.
        </p>

        <p>
        The core concept of a string -> function template engine is its compilation method. A custom template engine <em>must</em> implement this method.
        </p>
    </dd>

    <dt><code>render( text , data , [options] )</code></dt>
    <dd>
        <p>
        Compiles and renders a template in a single step, and returns the rendered result.
        </p>

        <p>
        A custom template engine does <em>not</em> have to implement this method. It is merely provided as a convenience to the user. If the underlying engine does not implement this method, the <code>compile()</code> method will be called and the resulting function will be invoked.
        </p>
    </dd>

    <dt><code>precompile( text , [options] )</code></dt>
    <dd>
        <p>
        Precompiles a string template into a new string containing JavaScript source code for the precompiled template and returns it to the caller. The <code>revive()</code> method is this method's companion, it converts the precompiled template back into a renderable function.
        </p>

        <p>
        A custom template engine does <em>not</em> have to implement this method. If precompilation is a feature of the underlying template engine, then the <code>revive()</code> method <em>must</em> also be implemented.
        </p>
    </dd>

    <dt><code>revive( precompiled , [options] )</code></dt>
    <dd>
        <p>
        Revives a precompiled template function into an executable template function and returns that function to the caller. The precompiled code must already have been evaluated; this method won't evaluate it for you.
        </p>

        <p>
        This is a companion method to the <code>precompile()</code> method and it <em>must</em> be implemented if the underlying template engine supports precompilation.
        </p>
    </dd>
</dl>

<h2 id="using-templatemicro">Using <code>Template.Micro</code></h2>

<p>
<code>Y.Template.Micro</code> is a string-based micro-templating language similar to <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/erb/rdoc/ERB.html">ERB</a> and <a href="http://underscorejs.org/#template">Underscore</a> templates. Template.Micro is great for small, powerful templates, and its compilation engine is <em>extremely</em> fast with a small footprint.
</p>

<p>
Compared with the features of Handlebars, Template.Micro is much simpler. Using the <a href="#generic-template-api">generic engine API</a> provided by <code>Y.Template</code>, Micro and Handlebars templates can be used interchangeably. This gives you a powerful way to customize a component's Handlebars templates by overriding them with Micro templates, and not incur the cost of loading the <code>handlebars-compiler</code> module.
</p>

<h3 id="template-syntax">Template Syntax</h3>

<h4 id="basic-expressions">Basic Expressions</h4>

<p>
Within a Micro template, use <code>&lt;%= ... %&gt;</code> to output the value of an expression (where <code>...</code> is the JavaScript expression or data variable to evaluate). The output will be <strong>HTML-escaped by default.</strong>
</p>

<p>
A simple Template.Micro expression looks like this:
</p>

<pre class="code prettyprint">&lt;h1&gt;&lt;%= this.title %&gt;&lt;&#x2F;h1&gt;</pre>


<p>
This tells Template.Micro:
</p>

<ol>
    <li>
        <p>
        if there exists a <code>title</code> property in the current context in which the template function was executed, and that property is not falsy or an empty array, insert its value here.
        </p>
    </li>
    <li>
        <p>
        Otherwise, insert an empty string.
        </p>
    </li>
</ol>

<p>
The following example shows how the data context is defined when executing a Micro template function:
</p>

<pre class="code prettyprint lang-javascript">var micro   = new Y.Template(),
    heading = micro.compile(&#x27;&lt;h1&gt;&lt;%= this.title %&gt;&lt;&#x2F;h1&gt;&#x27;),
    output;

&#x2F;&#x2F; The object passed to the template function becomes the context in which the
&#x2F;&#x2F; template is executed. This object is also available through the &#x60;data&#x60;
&#x2F;&#x2F; variable within the template&#x27;s expressions.
output = heading({title: &#x27;The Adventures of the Spotted Cuscus&#x27;});
Y.log(output); &#x2F;&#x2F; =&gt; &quot;&lt;h1&gt;The Adventures of the Spotted Cuscus&lt;&#x2F;h1&gt;&quot;</pre>


<p>
<strong>Note:</strong> The template functions are <code>call()</code>-ed with the context of the object which is passed to the template function. This object is also available through the <code>data</code> variable. Therefore, <code>data === this</code>, within the template expressions. The previous template could have been written as:
</p>

<pre class="code prettyprint">&lt;h1&gt;&lt;%= data.title %&gt;&lt;&#x2F;h1&gt;</pre>


<h4 id="html-escaping">HTML Escaping</h4>

<p>
By default, content rendered using a percent-equals expression like <code>&lt;%= foo %&gt;</code> will automatically be HTML-escaped for safety. To render unescaped HTML output, use a percent-double-equals expression like <code>&lt;%== foo %&gt;</code>. <strong>Only use a percent-double-equals expression for content you trust!</strong> Never use it to render unfiltered user input.
</p>

<h4 id="inline-code-code-blocks">Inline Code &amp; Code Blocks</h4>

<p>
To execute arbitrary JavaScript code within the template without rendering its output, use <code>&lt;% ... %&gt;</code> (where <code>...</code> is the code to be executed). This allows the use of if/else blocks, loops, function calls, etc., although it's recommended that you avoid embedding anything beyond basic flow control logic in your templates.
</p>

<table class="micro-code">
    <tbody>
        <tr>
            <th colspan="2">Template Source</th>
        </tr>

        <tr>
            <td colspan="2" width="100%">
<pre class="code prettyprint lang-html">&lt;h1&gt;Animals&lt;&#x2F;h1&gt;

&lt;ul class=&quot;&lt;%= this.classNames.list %&gt;&quot;&gt;
  &lt;% Y.Array.each(this.animals, function (animal, i) { %&gt;
    &lt;li class=&quot;&lt;%= i % 2 ? &#x27;odd&#x27; : &#x27;even&#x27; %&gt;&quot;&gt;
        &lt;%= animal %&gt;
    &lt;&#x2F;li&gt;
  &lt;% }); %&gt;
&lt;&#x2F;ul&gt;</pre>

            </td>
        </tr>

        <tr>
            <th style="padding-top: 0.5em;">Data</th>
            <th style="padding-top: 0.5em;">Output</th>
        </tr>

        <tr>
            <td width="50%">
<pre class="code prettyprint lang-javascript">{
    classNames: {list: &#x27;animals&#x27;},

    animals: [
        &#x27;Rhino&#x27;,
        &#x27;Plain Tiger butterfly&#x27;,
        &#x27;Spotted Cuscus&#x27;
    ]
}</pre>

            </td>

            <td width="50%">
<pre class="code prettyprint lang-html">&lt;h1&gt;Animals&lt;&#x2F;h1&gt;

&lt;ul class=&quot;animals&quot;&gt;
    &lt;li class=&quot;even&quot;&gt;Rhino&lt;&#x2F;li&gt;
    &lt;li class=&quot;odd&quot;&gt;Plain Tiger butterfly&lt;&#x2F;li&gt;
    &lt;li class=&quot;even&quot;&gt;Spotted Cuscus&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;</pre>

            </td>
        </tr>
    </tbody>
</table>

<h3 id="precompiling-and-reviving-micro-templates">Precompiling and Reviving Micro Templates</h3>

<p>
Precompiling Micro templates <a href="#precompiling-and-reviving-templates">has advantages</a>, especially when an app uses many templates. The rest of this section will demonstrate how to precompile templates on the server.
</p>

<p>
To precompile Micro templates on the server using <a href="http://nodejs.org/">Node.js</a>, first install the YUI <a href="http://npmjs.org/">npm</a> module by running the following in a terminal from the directory that contains your server application (this assumes you already have Node and npm installed):
</p>

<pre class="code terminal"><span class="noselect">$ </span>npm install yui</pre>


<p>
This will install the <code>yui</code> npm module in the current directory and make it available to your application.
</p>

<p>
Next, in your application code, call the <a href="http://yuilibrary.com/yui/docs/api/classes/Template.Micro.html#method_precompile"><code>precompile()</code></a> method to precompile a Micro template. It will return a string containing JavaScript code.
</p>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Load the YUI Template.Micro module.
var Micro = require(&#x27;yui&#x2F;template-micro&#x27;).Template.Micro;

&#x2F;&#x2F; Precompile a template string (pass any string you like here).
var precompiled = Micro.precompile(&#x27;My favorite animal is a &lt;%= this.animal %&gt;.&#x27;);</pre>


<p>
The <code>precompiled</code> variable will contain a string of JavaScript code that looks something like this:
</p>

<pre class="code prettyprint lang-javascript">function (Y, $e, data) {
var $b=&#x27;&#x27;, $v=function (v){return v || v === 0 ? v : $b;}, $t=&#x27;My favorite animal is a &#x27;+
$e($v( this.animal ))+
&#x27;.&#x27;;
return $t;
}</pre>


<p>
You can now serve this precompiled JS to the client in whatever way makes the most sense for your application. On the client, load the <code>template</code> YUI module, create a <code>Y.Template</code> engine instance, and pass the precompiled template to its <a href="http://yuilibrary.com/yui/docs/api/classes/Template.html#method_revive"><code>revive()</code></a> method to convert it into a renderable template function.
</p>

<p>
Here's a simple <a href="http://expressjs.com/">Express</a> app that precompiles a template on the server and renders it on the client:
</p>

<pre class="code prettyprint lang-javascript">#!&#x2F;usr&#x2F;bin&#x2F;env node
var Micro   = require(&#x27;yui&#x2F;template-micro&#x27;).Template.Micro,
    express = require(&#x27;express&#x27;),
    app     = express(),

    precompiled = Micro.precompile(&#x27;My favorite animal is a &lt;%= this.animal %&gt;.&#x27;);

app.get(&#x27;&#x2F;&#x27;, function (req, res) {
    res.send(
        &#x27;&lt;html&gt;&lt;body&gt;&#x27; +
            &#x27;&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.10.3&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;&#x27; +
            &#x27;&lt;script&gt;&#x27; +
                &#x27;YUI().use(&quot;template&quot;, function (Y) {&#x27; +
                    &#x27;var micro    = new Y.Template(),&#x27; +
                    &#x27;    template = micro.revive(&#x27; + precompiled + &#x27;);&#x27; +
                    &#x27;Y.one(&quot;body&quot;).append(template({animal: &quot;Plain Tiger butterfly&quot;}));&#x27; +
                &#x27;});&#x27; +
            &#x27;&lt;&#x2F;script&gt;&#x27; +
        &#x27;&lt;&#x2F;body&gt;&lt;&#x2F;html&gt;&#x27;
    );
});

app.listen(7000);</pre>


<p>
To see this simple server in action, save it to a file, install Express and YUI by running <code>npm i express yui</code>, then execute the file with Node.js and browse to <a href="http://localhost:7000/" target="_blank">http://localhost:7000/</a>.
</p>

<h3 id="customizing-template-syntax">Customizing Template Syntax</h3>

<p>
Micro templates have a simple syntax, there are only three forms:
</p>

<dl>
    <dt><code>&lt;%= ... %&gt;</code></dt>
    <dd>
        <p>
        Safely outputs the value of a JavaScript expression. The output will be HTML-escaped by default.
        </p>
    </dd>

    <dt><code>&lt;%== ... %&gt;</code></dt>
    <dd>
        <p>
        Outputs the raw value of a JavaScript expression. This does <em>not</em> HTML-escape the output. Never use it to render unfiltered user input.
        </p>
    </dd>

    <dt><code>&lt;% ... %&gt;</code></dt>
    <dd>
        <p>
        Executes arbitrary JavaScript code within the template without rendering its output.
        </p>
    </dd>
</dl>

<p>
These syntax identifiers are defined as RegExp on <a href="http://yuilibrary.com/yui/docs/api/classes/Template.Micro.html#property_options"><code>Y.Template.Micro.options</code></a>. If you wish to define a custom syntax for your Micro templates, you can do so by defining new RegExps for your custom identifiers.
</p>

<h4 id="defining-a-handlebars-like-syntax">Defining a Handlebars-like Syntax</h4>

<p>
The following example will define a Handlebars-like Micro template syntax:
</p>

<dl>
    <dt><code>{{ ... }}</code></dt>
    <dd>
        <p>
        Safely outputs the value of a JavaScript expression. The output will be HTML-escaped by default.
        </p>
    </dd>

    <dt><code>{{{ ... }}}</code></dt>
    <dd>
        <p>
        Outputs the raw value of a JavaScript expression. This does <em>not</em> HTML-escape the output. Never use it to render unfiltered user input.
        </p>
    </dd>

    <dt><code>{{% ... %}}</code></dt>
    <dd>
        <p>
        Executes arbitrary JavaScript code within the template without rendering its output.
        </p>
    </dd>
</dl>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Create RegExps which define our new Micro template syntax.
Y.mix(Y.Template.Micro.options, {
    code         : &#x2F;\{\{%([\s\S]+?)%\}\}&#x2F;g,
    escapedOutput: &#x2F;\{\{(?!%)([\s\S]+?)\}\}&#x2F;g,
    rawOutput    : &#x2F;\{\{\{([\s\S]+?)\}\}\}&#x2F;g
}, true);</pre>


<table class="micro-code">
    <tbody>
        <tr>
            <th colspan="2">Template Source</th>
        </tr>

        <tr>
            <td colspan="2" width="100%">
<pre class="code prettyprint lang-html">&lt;h1&gt;Animals&lt;&#x2F;h1&gt;

&lt;ul class=&quot;{{ this.classNames.list }}&quot;&gt;
  {{% Y.Array.each(this.animals, function (animal, i) { %}}
    &lt;li class=&quot;{{ i % 2 ? &#x27;odd&#x27; : &#x27;even&#x27; }}&quot;&gt;
        {{ animal }}
    &lt;&#x2F;li&gt;
  {{% }); %}}
&lt;&#x2F;ul&gt;</pre>

            </td>
        </tr>

        <tr>
            <th style="padding-top: 0.5em;">Data</th>
            <th style="padding-top: 0.5em;">Output</th>
        </tr>

        <tr>
            <td width="50%">
<pre class="code prettyprint lang-javascript">{
    classNames: {list: &#x27;animals&#x27;},

    animals: [
        &#x27;Rhino&#x27;,
        &#x27;Plain Tiger butterfly&#x27;,
        &#x27;Spotted Cuscus&#x27;
    ]
}</pre>

            </td>

            <td width="50%">
<pre class="code prettyprint lang-html">&lt;h1&gt;Animals&lt;&#x2F;h1&gt;

&lt;ul class=&quot;animals&quot;&gt;
    &lt;li class=&quot;even&quot;&gt;Rhino&lt;&#x2F;li&gt;
    &lt;li class=&quot;odd&quot;&gt;Plain Tiger butterfly&lt;&#x2F;li&gt;
    &lt;li class=&quot;even&quot;&gt;Spotted Cuscus&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;</pre>

            </td>
        </tr>
    </tbody>
</table>

<p>
<strong>Note:</strong> The syntax identifiers can be specified on a per-template basis by passing <code>options</code> as the second argument to the <code>compile()</code>, <code>precompile()</code>, or <code>render()</code> methods. Alternatively you can specify <code>defaults</code> when using the <a href="#generic-template-api">generic Template API</a>, doing so will only affect how the templates are process for that engine instance.
</p>

<h2 id="using-templates-in-custom-components">Using Templates in Custom Components</h2>

<p>
When creating custom components for your app, it's natural to bundle the templates with the component that will use them. The following examples show how to create a custom view component which uses templates.
</p>

<h3 id="custom-view-with-embeded-template">Custom View with Embeded Template</h3>

<p>
This example shows how to create a very basic view with an embedded template:
</p>

<pre class="code prettyprint lang-javascript">YUI().use(&#x27;template-micro&#x27;, &#x27;view&#x27;, function (Y) {
    Y.AnimalListView = Y.Base.create(&#x27;animalListView&#x27;, Y.View, [], {
        &#x2F;&#x2F; The compiled Micro template sits on the view&#x27;s prototype.
        template: Y.Template.Micro.compile(
            &#x27;&lt;ul class=&quot;animals&quot;&gt;&#x27; +
              &#x27;&lt;% Y.Array.each(this.animals, function (animal, i) { %&gt;&#x27; +
                &#x27;&lt;li class=&quot;&lt;% i % 2 ? &quot;odd&quot; : &quot;even&quot; %&gt;&quot;&gt;&#x27; +
                    &#x27;&lt;%= animal %&gt;&#x27; +
                &#x27;&lt;&#x2F;li&gt;&#x27; +
              &#x27;&lt;% }); %&gt;&#x27; +
            &#x27;&lt;&#x2F;ul&gt;&#x27;
        ),

        render: function () {
            var html = this.template({
                animals: this.get(&#x27;animals&#x27;)
            });

            this.get(&#x27;container&#x27;).setHTML(html);
            return this;
        }
    });

    &#x2F;&#x2F; Create an instance of the view and render it to the &#x60;&lt;body&gt;&#x60;.

    var animalListView = new Y.AnimalListView({
        animals: [
            &#x27;Rhino&#x27;,
            &#x27;Plain Tiger butterfly&#x27;,
            &#x27;Spotted Cuscus&#x27;
        ]
    });

    animalListView.get(&#x27;container&#x27;).appendTo(&#x27;body&#x27;);
});</pre>


<h3 id="custom-view-with-external-template">Custom View with External Template</h3>

<p>
Usually embedding the template in your component's JavaScript code is bad practice. The following examples show two ways to externalize a component's templates.
</p>

<h4 id="defining-templates-in-html">Defining Templates in HTML</h4>

<p>
One option is to embed your template inside a special <code>&lt;script&gt;</code> element, one whose <code>type</code> attribute is set to something which the browser will not process as JavaScript:
</p>

<pre class="code prettyprint lang-html">&lt;script id=&quot;t-animals&quot; type=&quot;text&#x2F;x-template&quot;&gt;
    &lt;ul class=&quot;animals&quot;&gt;
      &lt;% Y.Array.each(this.animals, function (animal, i) { %&gt;
        &lt;li class=&quot;&lt;% i % 2 ? &#x27;odd&#x27; : &#x27;even&#x27; %&gt;&quot;&gt;
            &lt;%= animal %&gt;
        &lt;&#x2F;li&gt;
      &lt;% }); %&gt;
    &lt;&#x2F;ul&gt;
&lt;&#x2F;script&gt;</pre>


<pre class="code prettyprint lang-javascript">YUI().use(&#x27;node-base&#x27;, &#x27;template-micro&#x27;, &#x27;view&#x27;, function (Y) {
    Y.AnimalListView = Y.Base.create(&#x27;animalListView&#x27;, Y.View, [], {
        &#x2F;&#x2F; The template source is pulled from the HTML, then compiled into a
        &#x2F;&#x2F; template function which sits on the view&#x27;s prototype.
        template: Y.Template.Micro.compile(Y.one(&#x27;#t-animals&#x27;).getHTML()),

        render: function () {
            var html = this.template({
                animals: this.get(&#x27;animals&#x27;)
            });

            this.get(&#x27;container&#x27;).setHTML(html);
            return this;
        }
    });

    &#x2F;&#x2F; Create an instance of the view and render it to the &#x60;&lt;body&gt;&#x60;.

    var animalListView = new Y.AnimalListView({
        animals: [
            &#x27;Rhino&#x27;,
            &#x27;Plain Tiger butterfly&#x27;,
            &#x27;Spotted Cuscus&#x27;
        ]
    });

    animalListView.get(&#x27;container&#x27;).appendTo(&#x27;body&#x27;);
});</pre>


<h4 id="defining-templates-in-a-module">Defining Templates in a Module</h4>

<p>
When your custom component is used within multiple apps, you might not have control over the HTML of the page. A great option is to create a separate module which holds your template source which your view module can <code>require</code>:
</p>

<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Defines a YUI module which will hold the template source for our view.
YUI.add(&#x27;animalListTemplate&#x27;, function (Y) {
    Y.namespace(&#x27;AnimalListView&#x27;).template = Y.Template.Micro.compile(
        &#x27;&lt;ul class=&quot;animals&quot;&gt;&#x27; +
          &#x27;&lt;% Y.Array.each(this.animals, function (animal, i) { %&gt;&#x27; +
            &#x27;&lt;li class=&quot;&lt;% i % 2 ? &quot;odd&quot; : &quot;even&quot; %&gt;&quot;&gt;&#x27; +
                &#x27;&lt;%= animal %&gt;&#x27; +
            &#x27;&lt;&#x2F;li&gt;&#x27; +
          &#x27;&lt;% }); %&gt;&#x27; +
        &#x27;&lt;&#x2F;ul&gt;&#x27;
    );
}, &#x27;0.0.1&#x27;, {
    requires: [&#x27;template-micro&#x27;]
});</pre>


<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Defines a YUI module which defines our view and requires our template module.
YUI.add(&#x27;animalListView&#x27;, function (Y) {
    var AnimalListView = Y.Base.create(&#x27;animalListView&#x27;, Y.View, [], {
        render: function () {
            var html = AnimalListView.template({
                animals: this.get(&#x27;animals&#x27;)
            });

            this.get(&#x27;container&#x27;).setHTML(html);
            return this;
        }
    });

    &#x2F;&#x2F; Properly exposes the view constructor while retaining the namespace.
    Y.AnimalListView = Y.mix(AnimalListView, Y.AnimalListView);
}, &#x27;0.0.1&#x27;, {
    requires: [&#x27;animalListTemplate&#x27;, &#x27;view&#x27;]
});</pre>


<pre class="code prettyprint lang-javascript">&#x2F;&#x2F; Create an instance of the view and render it to the &#x60;&lt;body&gt;&#x60;.
YUI({
    modules: {
        animalListTemplate: &#x27;&#x2F;animal-list-template.js&#x27;,
        animalListView    : &#x27;&#x2F;animal-list-view.js&#x27;
    }
}).use(&#x27;animalListView&#x27;, function (Y) {
    var animalListView = new Y.AnimalListView({
        animals: [
            &#x27;Rhino&#x27;,
            &#x27;Plain Tiger butterfly&#x27;,
            &#x27;Spotted Cuscus&#x27;
        ]
    });

    animalListView.get(&#x27;container&#x27;).appendTo(&#x27;body&#x27;);
});</pre>


<p>
Refer to the <a href="../yui/create.html">Creating YUI Modules</a> user guide for more details.
</p>

<h2 id="best-practices">Best Practices</h2>

<p>
The following is a list of best practices to consider when using templates in your app and/or custom components:
</p>

<h3 id="less-logic-is-better">Less Logic is Better</h3>

<p>
Make sure not to embed too much logic in your templates, things can get out of control if you do. You should <em>avoid</em> template logic which has side effects! Micro templates allow you to embed any arbitrary JavaScript in your templates, while Handlebars templates are logic-less by design.
</p>

<h3 id="externalize-templates">Externalize Templates</h3>

<p>
Avoid embedding huge template strings in your JavaScript code. Strive to separate your templates from the code that uses them, having your templates specified in separate files is best. The <a href="#defining-templates-in-a-module">template module example</a> above would ideally use a build-time process to wrap the template source with the YUI module registration wrapper.
</p>

<h3 id="compile-once-render-often">Compile Once, Render Often</h3>

<p>
Template <a href="#instantiating-a-template-engine">compilation is expensive</a>. You should avoid compiling a template more than once. Ideally, you are <a href="#precompiling-and-reviving-templates">precompiling templates</a> on the server or during a build-time process to avoid the compilation step on the client.
</p>
</div>
            </div>
        </div>

        <div class="yui3-u-1-4">
            <div class="sidebar">
                
                    <div id="toc" class="sidebox">
                        <div class="hd">
                            <h2 class="no-toc">Table of Contents</h2>
                        </div>

                        <div class="bd">
                            <ul class="toc">
<li>
<a href="#getting-started">Getting Started</a>
</li>
<li>
<a href="#using-template">Using <code>Template</code></a>
<ul class="toc">
<li>
<a href="#quick-start">Quick Start</a>
</li>
<li>
<a href="#generic-template-api">Generic Template API</a>
</li>
<li>
<a href="#instantiating-a-template-engine">Instantiating a Template Engine</a>
<ul class="toc">
<li>
<a href="#using-micro-templates">Using Micro Templates</a>
</li>
<li>
<a href="#using-handlebars-templates">Using Handlebars Templates</a>
</li>
</ul>
</li>
<li>
<a href="#compiling-and-rendering-templates">Compiling and Rendering Templates</a>
</li>
<li>
<a href="#precompiling-and-reviving-templates">Precompiling and Reviving Templates</a>
</li>
<li>
<a href="#creating-a-custom-template-engine">Creating a Custom Template Engine</a>
</li>
</ul>
</li>
<li>
<a href="#using-templatemicro">Using <code>Template.Micro</code></a>
<ul class="toc">
<li>
<a href="#template-syntax">Template Syntax</a>
<ul class="toc">
<li>
<a href="#basic-expressions">Basic Expressions</a>
</li>
<li>
<a href="#html-escaping">HTML Escaping</a>
</li>
<li>
<a href="#inline-code-code-blocks">Inline Code &amp; Code Blocks</a>
</li>
</ul>
</li>
<li>
<a href="#precompiling-and-reviving-micro-templates">Precompiling and Reviving Micro Templates</a>
</li>
<li>
<a href="#customizing-template-syntax">Customizing Template Syntax</a>
<ul class="toc">
<li>
<a href="#defining-a-handlebars-like-syntax">Defining a Handlebars-like Syntax</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#using-templates-in-custom-components">Using Templates in Custom Components</a>
<ul class="toc">
<li>
<a href="#custom-view-with-embeded-template">Custom View with Embeded Template</a>
</li>
<li>
<a href="#custom-view-with-external-template">Custom View with External Template</a>
<ul class="toc">
<li>
<a href="#defining-templates-in-html">Defining Templates in HTML</a>
</li>
<li>
<a href="#defining-templates-in-a-module">Defining Templates in a Module</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#best-practices">Best Practices</a>
<ul class="toc">
<li>
<a href="#less-logic-is-better">Less Logic is Better</a>
</li>
<li>
<a href="#externalize-templates">Externalize Templates</a>
</li>
<li>
<a href="#compile-once-render-often">Compile Once, Render Often</a>
</li>
</ul>
</li>
</ul>
                        </div>
                    </div>
                

                

                
            </div>
        </div>
    </div>
</div>

<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>

<script>
YUI.Env.Tests = {
    examples: [],
    project: '../assets',
    assets: '../assets/template',
    name: 'template',
    title: 'Template',
    newWindow: '',
    auto:  false 
};

</script>
<script src="../assets/yui/test-runner.js"></script>



</body>
</html>