Skip to content

03 Templates

Roberto Ferranti edited this page Jul 6, 2026 · 1 revision

πŸ‘£ Using a template

✍️ Define a template

using a <template> tag, a string, a DocumentFragment or a Node

<body>
    ...
    <div id="target"></div>
    <template id="my-template">
        <h1>{{title}}</h1>
    </template>
    ...
</body>

⚑ Create a template

const template = ftl.Template.fromSelector('#my-template');

🌈 Render the template

const data = {title: 'Hello World!'};
template.WithOverlay(data).renderToSelector('#target');

Attributes evaluation

All attributes starting with data-tpl- are evaluated in the followind order:

  • data-tpl-if
  • data-tpl-with
  • data-tpl-each
  • data-tpl-when
  • data-tpl-value
  • data-tpl-class-append
  • data-tpl-attr-append
  • data-tpl-text
  • data-tpl-html
  • data-tpl-remove
  • data-tpl-verbatim
  • data-tpl-*

πŸ”΅ data-tpl-if

Removes from the DOM the element if the expression evaluates as false

<h3>Tracking:</h3>
<p data-tpl-if="delivered">Your package has been delivered</p>

E.g:

data = {delivered: true}
<h3>Tracking:</h3>
<p>Your package has been delivered</p>

E.g:

data = {delivered: false}
<h3>Tracking:</h3>

🟒 data-tpl-with

Sets the context of the fragment to the specified value

data = {
    parent: {
        text: "I'm the parent obj",
        nested: {
            text: "I'm the nested obj",
            label: "fruit",
            fruits: ["apple", "banana", "tomato"]
        }
    }
}
<div data-tpl-with="parent.nested"><p>{{text}}</p></div>

renders to

<div><p>I'm the nested obj</p></div>

It is also possible to assing the evaluated valua to a variable using data-tpl-var. This is useful for referencing it from another context.

<div data-tpl-with="parent.nested" data-tpl-var="nested">
    <p>{{nested.text}}</p>
    <div>
        <h3>fruits</h3>
        <p data-tpl-each="nested.fruits">{{nested.label}}: {{self}}</p>
    </div>
</div>

that will render to

<div>
    <p>I'm the nested obj</p>
    <div>
        <h3>fruits</h3>
        <p>fruit: apple</p><p>fruit: banana</p><p>fruit: tomato</p>
    </div>
</div>

πŸ”΅ data-tpl-each

Iterates over given array rendering the tag where the attribut is declared, for each array element. Sets the context to the current element.

data = {
    a: [{v: 1}, {v: 2}, {v: 3}]
}
<div data-tpl-each="a">{{ v }}</div>

renders to

<div>1</div>
<div>2</div>
<div>3</div>

🟒 data-tpl-text

Evaluates the given expression and places it as text node inside the given element

data = {
    text: "I'm so <i>pretty!</i>"
}
<p data-tpl-text="text"></p>

renders to

<p>I'm so &lt;i&gt;pretty!&lt;/i&gt;</p>

🟒 data-tpl-html

Evaluates the given expression and places it as inner html of the given element

data = {
    text: "I'm so <i>pretty!</i>"
}
<p data-tpl-html="text"></p>

renders to

<p>I'm so <i>pretty!</i></p>

🟑 data-tpl-remove

Removes the tag, content or whole element where the attribute is specified

πŸ”Ά data-tpl-remove-tag

<div data-tpl-remove="tag"><p>paragraph</p></div>

renders to

<p>paragraph</p>

πŸ”Ά data-tpl-remove-body

<div data-tpl-remove="body"><p>paragraph</p></div>

renders to

<div></div>

πŸ”Ά data-tpl-remove-all

<div data-tpl-remove="all"><p>paragraph</p></div>

renders to

🟒 data-tpl-*

It is possible to prefix any attribute with data-tpl-. It will evaluate the expression and set the result as value of an attribute having the name of the given data-tpl- suffix

functions = {
    text: {
        concat: (separator, ...txt) => txt.join(separator)
    }
}
data = {
    color: "green"
}
<p data-tpl-style="#text:concat(' ', 'color:', color)">To be colored</p>

renders to

<p style="color: green">To be colored</p>

Special values

boolean values are always rendered as boolean attributes

<input data-tpl-readonly="true">

renders to

<input readonly>

null and undefined values cause the attribute to not be rendered

<input data-tpl-readonly="aNullValue">

renders to

<input>

Clone this wiki locally