ContentBlocks ContentBlocks 2.x Input Types List
The list input type provides a visual nested list editor. Editors work directly in real <ul> / <ol> markup with keyboard-driven nesting, optional ordered/unordered switching, and an ordered-list start value.
Table of Contents
Supported properties
| Property | Type | Default | Description |
|---|---|---|---|
listType |
"unordered" | "ordered" |
— | Locks the list type. Hides the toolbar toggle. |
defaultListType |
"unordered" | "ordered" |
"unordered" |
Default type of list, while letting the editor switch types. |
defaultStart |
number | 1 |
Initial start value for new blocks (ordered lists). |
placeholder |
string | "List item" |
Placeholder text for each item input. |
minItems |
number | 1 |
Minimum number of root-level items. Nested lists may be empty. |
maxItems |
number | — | Maximum number of sibling items in one list. Applies to the root list and to each nested list. Omit for no limit. |
maxDepth |
number | — | Maximum nesting depth. Root items are depth 1, so 1 is a flat list and 2 allows one level of children. Omit for no limit. |
Enter does not add another sibling once that list is at maxItems. Tab and drag do not nest an item, or its subtree, past maxDepth. Outdent is also blocked when it would push the destination list, or the item’s children after absorbing following siblings, past maxItems. Items already saved above a limit stay in place. Reordering within the same list is still allowed. maxItems should be greater than or equal to minItems.
Keyboard shortcuts
| Key | Action |
|---|---|
| Enter | Insert sibling below, unless that list is at maxItems |
| Backspace (empty) | Remove item |
| Tab | Indent under previous sibling, unless that would pass maxDepth, maxItems, or leave fewer than minItems at the root |
| Shift+Tab | Outdent |
| Arrow Up / Down | Move focus in tree order |
Drag and drop from the handle to move items around.
Returned values
items: recursive array of list nodes, each with:value: item text (plain text)items: nested child items (array)
listType:"unordered"or"ordered"start: integer start value for the root ordered list (default1)
Example block
{
"title": "List",
"description": "Visual nested list",
"icon": "unorderedlist",
"category": "Structure",
"inputs": {
"content": {
"type": "list",
"width": 100,
"properties": {
"placeholder": "Add a list item..."
}
}
}
}
Limited nesting
{
"content": {
"type": "list",
"width": 100,
"properties": {
"maxItems": 5,
"maxDepth": 2
}
}
}
Locked ordered list with custom start
{
"content": {
"type": "list",
"width": 100,
"properties": {
"listType": "ordered",
"defaultStart": 1
}
}
}
v1 migration
v1 had separate list and ordered_list field types. In v2, use a single list input:
| v1 field type | v2 equivalent |
|---|---|
list |
{ "type": "list", "properties": { "listType": "unordered" } } |
ordered_list |
{ "type": "list", "properties": { "listType": "ordered" } } |
Saved data shape (items with nested value / items) is compatible with v1. Templates that looped items can be adapted to read content.items, content.listType, and content.start.
Example template structures
Twig
For nested lists, we can use a twig macro like the example below.
{% macro renderListItems(items, type) %}
{% if type == 'ordered' %}
<ol>
{% else %}
<ul>
{% endif %}
{% for item in items %}
{% if item.value or item.items|length %}
<li>
{{ item.value }}
{% if item.items|length %}
{{ _self.renderListItems(item.items, type) }}
{% endif %}
</li>
{% endif %}
{% endfor %}
{% if type == 'ordered' %}</ol>{% else %}</ul>{% endif %}
{% endmacro %}
{% if content.items|length %}
{% set listType = content.listType|default('unordered') %}
{% if listType == 'ordered' %}
<ol{% if content.start and content.start > 1 %} start="{{ content.start }}"{% endif %}>
{% else %}
<ul>
{% endif %}
{% for item in content.items %}
{% if item.value or item.items|length %}
<li>
{{ item.value }}
{% if item.items|length %}
{{ _self.renderListItems(item.items, listType) }}
{% endif %}
</li>
{% endif %}
{% endfor %}
{% if listType == 'ordered' %}</ol>{% else %}</ul>{% endif %}
{% endif %}
tpl
We don’t recommend using MODX templates for the list input.