List Nodes
List nodes repeat their children for each item in a data source. They are the primary way to display collections of content -- blog listings, team grids, product catalogs, and any other repeatable layout.
Meno has a single unified List node type with two source modes:
Collection lists pull items from a CMS collection.
Prop-based lists iterate over an array passed as a component prop.
Adding a List Node
Select the element where you want the list to appear.
Open the Command Palette (Cmd+E on macOS, Ctrl+E on Windows/Linux).
Choose Add CMS List (for collection source) or Add List (for prop source).
The new list node appears as a child of the selected element.
Configuring a Collection List
Select the list node in the structure tree.
In the Properties panel on the right, set Source Type to
collection.Set Source to the collection name (e.g.
posts,team,products).Optionally set Limit to cap the number of items shown.
Optionally configure Sort (field and order) and Filter conditions.
Build the item template by adding child elements inside the list node. Use
{{item.fieldName}}template expressions to insert each item's data.
By default, the item variable is the singularized form of the collection name.
For a collection named posts, the variable is post, so you can write
{{post.title}} instead of {{item.title}}. To customize this, set the
Item Variable field.
Configuring a Prop-Based List
Select the list node.
Set Source Type to
prop.Set Source to the prop name that holds the array (e.g.
items,features).Add child elements and use
{{item.fieldName}}to reference each array element's properties.
This is useful when a reusable component receives its data as a prop rather than querying the CMS directly.
Template Variables
Inside a list's children, these template expressions are available:
Variable | Description |
|---|---|
| Value of a field on the current item |
| Zero-based index of the current item |
|
|
|
|
When using a named context (the itemAs property or auto-singularized name):
Variable | Description |
|---|---|
| Named access (collection "posts", auto-singularized) |
| Index using the named prefix |
| First-item flag using the named prefix |
| Last-item flag using the named prefix |
The legacy item/itemIndex/itemFirst/itemLast variables are always
available alongside the named versions for backward compatibility.
List Properties Reference
Shared Properties (Both Source Types)
Property | Type | Description |
|---|---|---|
|
| Data source mode |
| string | Prop name or collection name (required) |
| string | Variable name for templates (default: |
| string or | Container HTML element (default: |
| number | Maximum items to render |
| number | Skip the first N items |
Collection-Only Properties
Property | Type | Description |
|---|---|---|
| string or string[] | Specific item IDs, or a template expression like |
| object or object[] | Filter conditions (see below) |
| object or object[] | Sort configuration (see below) |
| boolean | Exclude the current CMS item from results (useful for "related posts" sections) |
| boolean | Emit a |
Filter Conditions
Each filter condition is an object with:
Field | Description |
|---|---|
| The item field to compare |
| One of: |
| The value to compare against |
Sort Configuration
Field | Description |
|---|---|
| The item field to sort by |
|
|
Container Tag Options
The list node wraps its output in a container element. Choose the tag that matches your semantic intent:
Tag | Use case |
|---|---|
| Generic container (default) |
| Unordered list (children become |
| Ordered list |
| Thematic section |
| Navigation links |
| Self-contained content |
| No wrapper -- items render as siblings (fragment mode) |
List vs. CMS Template Pages
These two features serve different purposes:
Feature | List Node | CMS Template Page |
|---|---|---|
What it does | Loops through items inline | Generates one HTML page per item |
Where it lives | Any page, any position |
|
Typical use | Blog listing, team grid, product catalog | Individual blog post page, product detail page |
Output | One section within a page | Separate |
You usually need both: a List node on a listing page (e.g. /blog) to show
all posts, and a template page (e.g. pages/templates/blog-post.json) to
render each individual post at /blog/{slug}.
Under the Hood
Collection List JSON
{
"type": "list",
"sourceType": "collection",
"source": "posts",
"tag": "div",
"limit": 10,
"sort": { "field": "publishDate", "order": "desc" },
"filter": { "field": "published", "operator": "eq", "value": true },
"style": {
"base": {
"display": "grid",
"gridTemplateColumns": "repeat(3, 1fr)",
"gap": "24px"
}
},
"children": [
{
"type": "node",
"tag": "article",
"children": [
{
"type": "node",
"tag": "img",
"attributes": {
"src": "{{post.cover}}",
"alt": "{{post.title}}"
}
},
{
"type": "node",
"tag": "h3",
"children": "{{post.title}}"
},
{
"type": "node",
"tag": "p",
"children": "{{post.excerpt}}"
}
]
}
]
}Prop-Based List JSON
{
"type": "list",
"sourceType": "prop",
"source": "features",
"itemAs": "feature",
"tag": "ul",
"children": [
{
"type": "node",
"tag": "li",
"children": [
{
"type": "node",
"tag": "strong",
"children": "{{feature.title}}"
},
{
"type": "node",
"tag": "span",
"children": "{{feature.description}}"
}
]
}
]
}Nested Lists
Lists can be nested. A parent list's context is preserved in child lists through the named context system:
{
"type": "list",
"sourceType": "collection",
"source": "categories",
"children": [
{
"type": "node",
"tag": "h2",
"children": "{{category.name}}"
},
{
"type": "list",
"sourceType": "collection",
"source": "posts",
"filter": {
"field": "category",
"operator": "eq",
"value": "{{category._id}}"
},
"children": [
{
"type": "node",
"tag": "p",
"children": "{{post.title}} in {{category.name}}"
}
]
}
]
}In the inner list, both {{post.*}} and {{category.*}} are available.
Related Items (Exclude Current)
On a blog post template page, show related posts excluding the current one:
{
"type": "list",
"sourceType": "collection",
"source": "posts",
"excludeCurrentItem": true,
"filter": {
"field": "category",
"operator": "eq",
"value": "{{cms.category}}"
},
"limit": 3,
"sort": { "field": "publishDate", "order": "desc" },
"children": [
{
"type": "node",
"tag": "a",
"attributes": { "href": "{{post._url}}" },
"children": "{{post.title}}"
}
]
}Next Steps
CMS -- Set up collections and content schemas
Filtering and Search -- Add interactive filtering to list output
Internationalization -- Localize list content
Deployment -- Build and deploy