Build layouts for Recommender experiences that display article recommendations across your site. Your layouts define how recommended content appears—as inline modules, sliders, flowcards, or custom formats.
Layout Anatomy
Recommender layouts follow the same structure as other Marfeel layouts:
| Component | Purpose |
|---|---|
| HTML Template | Structure and content placement. Uses Trimou templating to iterate over recommendations and display article data. |
| CSS Template | Visual styling. Also uses Trimou templating to inject colors, fonts, and configurable properties. |
| Layout Properties | Configurable variables (Custom Fields) that make layouts reusable across different experiences. |
Layout Configuration
Create your layout in the Layout Editor header:
| Setting | Options | Description |
|---|---|---|
| Type | Recommender | Must be “Recommender” for recommendation experiences |
How Values Get Filled
Layouts declare Custom Fields, but values come from the experience that uses the layout:
Experience Settings → Layout Custom Fields (defaults)
Experience-level settings take precedence over layout defaults. This lets you configure the same layout differently across experiences.
Template Data
Recommendations Array
Recommendations are injected as JSON during rendering. Each recommendation contains article data:
{
"recommendations": [{
"title": "Article title",
"url": "https://domain.com/path/to/article.html",
"img": "https://domain.com/path/to/image.jpg",
"authors": ["Author 1", "Author 2"],
"sections": ["Section"],
"tags": ["Tag1", "tagGroup:Tag2", "Tag3"],
"publishTime": "2024-12-26 17:01:03",
"visibility": "open"
}]
}
| Property | Description |
|---|---|
{{title}} |
Article headline |
{{url}} |
Article URL |
{{img}} |
Featured image URL |
{{authors}} |
Array of author names |
{{sections}} |
Array of section/category names |
{{tags}} |
Array of tags |
{{publishTime}} |
Publication date (ISO format) |
{{visibility}} |
Access level: open or hard-paywall |
Layout Properties (Custom Fields)
Reference Custom Fields with {{layoutProps.<key>}}. See Layout Editor for how to create and configure Custom Fields.
HTML Templating
Base Structure
Iterate over recommendations using the {{#recommendations}} block:
<section class="recommender-module">
<ul>
{{#recommendations}}
<li>
<a href="{{url}}">
<img src="{{img}}" alt="{{title}}" />
<h2>{{title}}</h2>
</a>
<span class="section">{{sections.0}}</span>
</li>
{{/recommendations}}
</ul>
</section>
{{#recommendations}} at some point. Access Array Elements
Use dot notation with index numbers (zero-indexed):
{{sections.0}} <!-- First section -->
{{authors.0}} <!-- First author -->
Iteration Properties
Access metadata about the current position in the loop:
| Property | Description |
|---|---|
iter.index |
Current position (starts at 1) |
iter.position |
Current position (starts at 0) |
iter.isFirst |
True if first item |
iter.isLast |
True if last item |
iter.hasNext |
True if more items follow |
{{#recommendations}}
<article class="{{#if iter.isFirst}}featured{{/if}}">
<h2>{{title}}</h2>
</article>
{{/recommendations}}
Common Patterns
Display Premium Content Indicator
Show an icon when visibility is hard-paywall:
{{+premiumIcon}}
{{#if "visibility eq 'hard-paywall'"}}
<img src="https://domain.com/premium-icon.svg" alt="Premium" />
{{/if}}
{{/premiumIcon}}
{{#recommendations}}
<article>
<a href="{{url}}">
<h2>{{{>premiumIcon}}}{{title}}</h2>
</a>
</article>
{{/recommendations}}
Format Publish Dates
Use datetime helpers for different formats:
{{timeFormat publishTime pattern="MMM dd"}} <!-- Jul 09 -->
{{timeFormat publishTime pattern="hh:mm a"}} <!-- 08:35 AM -->
{{prettyTime publishTime}} <!-- 15 minutes ago -->
{{prettyTime publishTime locale='es'}} <!-- Hace 15 minutos -->
See Templating Syntax for full datetime formatting reference.
Build Author/Section URLs
Use expression language to construct URLs from author or section names:
{{+authorUrl}}
{{#set author=this}}
{{#setEl i="author.toLowerCase().replace(' ', '-')"}}
https://domain.com/authors/{{i}}.html
{{/setEl}}
{{/set}}
{{/authorUrl}}
{{#recommendations}}
<article>
<h2><a href="{{url}}">{{title}}</a></h2>
{{#authors}}
<a href="{{>authorUrl}}">{{this}}</a>
{{/authors}}
</article>
{{/recommendations}}
Optimize Image Sizes
Full-size images can hurt performance. Use expression language to modify image URLs for your CDN:
{{#setEl i="img.split('?')[0]"}}{{i}}?width=240{{/setEl}}
This transforms https://domain.com/image.jpg?width=1200 into https://domain.com/image.jpg?width=240.
Layout Generation with Copilot
Marfeel Copilot can generate a Recommender layout based on an existing module from your site:
- In the Layout Editor preview, use the HTML element picker (top left)
- Select the element you want to copy—use breadcrumbs to target parent elements if needed
- Click Generate > Layout in the bottom right dialog
The suggested layout appears in a popup with a dedicated preview. Refine it before applying as a Custom Layout.
Default Layouts
Marfeel provides pre-built layouts so you don’t need to start from scratch.
Flowcard Layouts
Recommender Flowcard List — Full-featured layout with configurable:
- Section and author colors
- Pill frequency (e.g., show pill every 4th article)
- Ad unit integration (slot, position, density, dimensions)
- Multi-size ad formats
- Google Analytics tracking
Inline Module Layouts
- List of Thumbs — Thumbnail grid
- List of Text Links — Text-only list
- Block of Thumbs — Compact thumbnail block
- Ticker — Scrolling headline ticker
Desktop Layouts
Optimized for larger screens (also work on mobile):
- Desktop Single Article
- Desktop Photo Slider
- Desktop Pill Slider
- Desktop Thumb Slider
WhatsApp Layouts
For WhatsApp channel feed experiences:
- WhatsApp Layout Card
- WhatsApp Layout Inline
Troubleshooting
Preview shows placeholder content, not my site’s articles
The Layout Editor preview renders using the JSON tab’s example data. To test with real content:
- Open a Recommender experience in edit mode
- Click JSON endpoint in the preview options (top right)
- Copy the response
- Paste into the Layout Editor’s JSON tab
Copied layouts have unwanted attributes
When copying HTML from a live page, JavaScript may have already added dynamic IDs, lazy-load markers, or other attributes. Copy HTML with JavaScript disabled to avoid this.

