Marfeel Layouts: Templating Syntax

Mustache is a logic-less templating language used to dynamically render content. A template defines the structure and appearance of the output using placeholders. A JSON document provides the data that fills those placeholders.

The rendering engine processes the template and injects data from the JSON document, replacing tags like {{title}} with actual values such as Breaking News.

Example Template:

<h1>{{title}}</h1>
<p>Hi {{user.name}} {{user.lastname}}</p>
<p>{{summary}}</p>

JSON:

{
"title": "Breaking News",
"summary": "Latest updates from the newsroom.",
"user": {
   "name": "John",
   "lastname": "Smith"
   }
}

Rendered Output:

<h1>Breaking News</h1>
<p>Hi John Smith</p>
<p>Latest updates from the newsroom.</p>
Note:

Marfeel Layouts use Mustache templating syntax with the Trimou rendering engine. Trimou extends Mustache through its Helpers API, enabling conditional functions, format adapters, and string manipulation. Read more about Trimou rendering engine.

Tip: Trimou syntax works in both HTML and CSS files. Use the same helpers to inject variables, conditionals, and logic into your stylesheets.

Basic Syntax

Tag Type Syntax Purpose
Variable {{name}} Print escaped data
Unescaped HTML {{{html}}} Print raw HTML
Section {{#items}} Loop and conditional block
Inverted {{^items}} Render if false or empty

Display Content Conditionally

Use # to render content when a value exists. Use ^ to render content when a value is false or missing.

{{#articleIsClosed}}
   Subscribe to continue reading
{{/articleIsClosed}}

{{^articleIsClosed}}
   Did you like this article?
{{/articleIsClosed}}

Conditional Helpers

if tag — Render content when a condition is met:

{{#if "2 eq 2"}} This is shown {{/if}}
{{#if "2 eq 1"}} This is not shown {{/if}}

isNull and isNotNull — Check whether a variable exists:


{{#isNotNull var}} This is shown if var is not null {{/isNotNull}}
{{#isNull var}} This is shown if var is null {{/isNull}}

ifs — Inline conditional that outputs content only if the value exists:

{{#ifs variable}}{{variable}}, {{/ifs}}fallback

This is useful for comma-separated values with fallbacks. For example, a font family with fallback:

{{#ifs customFont}}{{customFont}}, {{/ifs}}system-ui

Outputs CustomFont, system-ui if customFont is set, or just system-ui if not.

choose, when, and otherwise — Handle multiple conditions:

{{#choose}}
   {{#when "2 eq 3"}} Not shown {{/when}}
   {{#when "2 eq 1"}} Not shown either {{/when}}
   {{#otherwise}} This is shown {{/otherwise}}
{{/choose}}

Combine Conditions with Variables

Use article data inside conditional expressions:

{{#choose}}
   {{#when "section eq 'OPINION'"}}
      {{section}} by {{author}}
      {{og:description}}
   {{/when}}

   {{#otherwise}}
      {{og:description}}
   {{/otherwise}}
{{/choose}}

Access Array Elements

Use dot notation with the index number. Arrays are zero-indexed.

JSON:

{
   "colors": ["black", "blue", "red"]
}

Template:

{{colors.0}} → black
{{colors.1}} → blue
{{colors.2}} → red

Iterate Over Arrays

Loop through arrays using the # operator or {{#each}} helper. Inside the loop, object properties are available at root level. Reference the entire object with {{this}}.

JSON:

{
"users": [
   {"name": "John", "surname": "Doe"},
   {"name": "Anna", "surname": "Smith"}
]
}

Template:

<ol>
   {{#users}}
   <li>{{surname}}, {{name}}</li>
   {{/users}}
</ol>

Rendered Output:

<ol>
   <li>Doe, John</li>
   <li>Smith, Anna</li>
</ol>

Iteration Properties

Access metadata about the current iteration using the iter object:

Property Description
iter.index Current position (starts at 1)
iter.position Current position (starts at 0)
iter.hasNext True if more items follow
iter.isFirst True if first item
iter.isLast True if last item

Format Dates and Times

Datetime fields must be in ISO format: yyyy-MM-dd hh:mm:ss.

timeFormat — Format dates with a specific pattern:

{{timeFormat publishTime pattern="dd-MM-yyyy"}}

Available patterns: yyyy, yy, MM, MMM, MMMM, dd, H, HH, m, mm, s, ss, a (AM/PM).

prettyTime — Display relative dates:

{{prettyTime updateDate locale='es'}}

Outputs: 2 months ago or Hace 43 minutos depending on locale.

Manipulate Strings with Expression Language

Use Java Expression Language for string manipulation and custom transformations.

Basic syntax:

{{#setEl i="<expression>"}} {{i}} {{/setEl}}

Example — Resize an image URL:

If your image URL is https://domain.com/images/image_id?width=1200, reduce the width:

{{#setEl i="img.split('?')[0]"}}{{i}}?width=240{{/setEl}}

Reference Current Item in Loops

Inside loops, use #set to reference the current item in expressions:

{{#each items}}
   {{#set item=this}}
      {{#setEl i="item.doSomething()"}} {{i}} {{/setEl}}
   {{/set}}
{{/each}}

Important: You cannot reference this directly inside Expression Language. Always assign it to a variable with #set first.

Declare Inline Variables

Define reusable variables with {{+varName}} and reference them with {{>varName}}.

Template:

{{+name}}John{{/name}}
{{+surName}}Doe{{/surName}}
{{+fullName}}
   {{>surName}}, {{>name}}
{{/fullName}}

Signed: {{>fullName}}.

Rendered Output:

Signed: Doe, John.

Inline variables add whitespace before and after when rendered. Plan your layout accordingly.

Render Raw HTML

Variables escape HTML characters by default. Use triple braces to render HTML as-is.

Syntax Input Output
{{foo}} <b>bar</b> &lt;b&gt;bar&lt;/b&gt;
{{{foo}}} <b>bar</b> bar

Calculate Averages

Use avgEl to calculate averages from arrays:

{{#avgEl "<data expression>" ["<mapper expression>"] [<decimals>]}}{{avg}}{{/avgEl}}
Parameter Required Description
Data expression Yes The array to traverse
Mapper expression No Expression to apply per item (e.g., i.price)
Decimals No Rounding precision (HALF_UP)

Examples:


{{#avgEl "data.products" "i.price" 2}}{{avg}}{{/avgEl}}
{{#avgEl "data.products" "i.name.length()" 0}}{{avg}}{{/avgEl}}
{{#avgEl "data.scores" 1}}{{avg}}{{/avgEl}}

Data Model

Each experience type—Recommender, Amplify, MarfeelPass—provides its own JSON model to the rendering engine.

The Layout Editor includes a JSON tab with example data for testing. The full data structure is available at data.experienceResponse.experience.data, with convenience aliases like recommendations for common paths.

Custom Fields are layout parameters you can configure per experience. Reference them with:

{{layoutProps.myVar}}

Read more about Custom Fields in the Layout Editor.

Going Deeper

1 Like