FieldtypeRepeater
Stores a collection of repeating field groups
Each item in the collection is a RepeaterPage
(extends Page), and the collection is a RepeaterPageArray (extends PageArray). Items are stored as real pages in the ProcessWire admin page tree under page/repeaters/ (relative to your
admin root, which is /processwire/ by default but is configurable).
FieldsetPage (extends RepeaterPage, which extends Page). Always a single object —
never a PageArray. The fieldset page is created automatically when the field is first used.
// Access fields on the fieldset page
echo $page->fieldset_field->title;
echo $page->fieldset_field->some_other_field;
// Set a field value
$page->fieldset_field->title = 'New value';
$page->save('fieldset_field');
// Check if a subfield is populated
if($page->fieldset_field->title) { ... }
// Access the owner page and field
$ownerPage = $page->fieldset_field->getForPage();
$ownerField = $page->fieldset_field->getForField();
$ownerTitle = $page->fieldset_field->getForPage()->title;// Always turn off output formatting when manipulating items
$page->of(false);
// Add a new item
$item = $page->repeater_field->getNewItem();
$item->title = 'New item';
$item->save();
$page->save('repeater_field'); // saves item order, count, and membership
// Remove an item
$page->repeater_field->remove($item);
$page->save('repeater_field');
// Reorder items: manipulate the RepeaterPageArray, then save the parent page
// The order of the array is what determines saved order.
$items = $page->repeater_field;
$itemA = $items->first();
$itemB = $items->last();
$items->append($itemA); // move first item to end
$items->prepend($itemB); // move last item to beginning
$items->insertBefore($itemA, $itemB); // move $itemA to just before $itemB
$items->insertAfter($itemA, $itemB); // move $itemA to just after $itemB
$items->reverse(); // reverse the order of all items
$items->sort('title'); // sort items by a sub-field value
$page->save('repeater_field'); // persists the new order
// Add multiple items, then save the parent page once at the end
$rows = [
[ 'title' => 'First item', 'body' => '<p>Hello</p>' ],
[ 'title' => 'Second item', 'body' => '<p>World</p>' ],
];
foreach($rows as $data) {
$item = $page->repeater_field->getNewItem();
foreach($data as $key => $value) $item->set($key, $value);
$item->save();
}
$page->save('repeater_field');Save workflow:
$item->save()writes the item's field values to the database.$page->save('repeater_field')updates the parent page's field record (item order, count, and which items belong to it). Both calls are required when adding items; only$item->save()is needed for in-place edits to an existing item.
The non-obvious part is that a repeater field requires a dedicated template and fieldgroup
to hold its sub-fields. Call _getRepeaterTemplate() after saving the field — it creates
the template/fieldgroup automatically if they don't exist yet.
$fields = $wire->fields;
$templates = $wire->templates;
// 1. Create and save the repeater field
/** @var RepeaterField $field */
$field = $fields->new('repeater', 'my_repeater', 'My Repeater');
// ------------------- ^Fieldtype --- ^Name -------- ^Label
// 2. Get/create the repeater's internal template and fieldgroup
$fieldgroup = $field->getRepeaterFieldgroup();
// 3. Add sub-fields to the repeater's fieldgroup
$fieldgroup->add('title');
$fieldgroup->add('body');
$fieldgroup->save();
// 4. Add the repeater field to your template
$template = $templates->get('your-template');
$template->fieldgroup->add($field);
$template->fieldgroup->save();Notes on programmatic creation:
$field->getRepeaterTemplate()creates and returns the repeater's internal template and fieldgroup if they don't exist yet, and storestemplate_idon the field. Always call this after creating the field.- The repeater template is named
repeater_{field_name}automatically. - Sub-fields are added directly to
$repeaterTemplate->fieldgroup— the fieldgroup membership IS the field list. $field->getRepeaterParent()returns the parent page under which repeater item pages are stored (e.g./processwire/page/repeaters/for-field-123/).$field->getBlankRepeaterPage($page)returns a new unsaved repeater item page for the given owner page — useful when creating items without going throughgetNewItem().
Supports the same subfield selectors as Fieldtype
$pages->find('fieldset_field.title*=keyword');
$pages->find('fieldset_field.some_field=value');// Iterate and output
foreach($page->repeater_field as $item) {
echo "<h3>{$item->headline}</h3>";
echo "<p>{$item->body}</p>";
}
// Template syntax with each()
echo $page->repeater_field->each("<div><h3>{headline}</h3><p>{body}</p></div>");
// Depth-aware output (when repeaterDepth field setting is enabled)
foreach($page->repeater_field as $item) {
$indent = str_repeat(' ', $item->depth);
echo $indent . $item->title . "\n";
}- The value is always a single
FieldsetPageinstance, never aPageArray. - Fields on the fieldset page exist in their own namespace, so
titleon one fieldset is independent oftitleon another — even if both fieldsets use the same field. - The fieldset page mirrors the output formatting (
of()) state of its owner page automatically. - Compatible fieldtypes:
FieldtypeFieldsetPageonly.
For documentation about how Fieldtypes work, see: wire/core/Fieldtype.php wire/core/FieldtypeMulti.php
Page status notes for repeater items:
- Unpublished & Hidden: Ready page, not yet used. Appears in unformatted repeater PageArray but user has not saved it.
- Unpublished & On: Publish requested and can be published as long as no input errors.
- Unpublished & NOT On: Item has been unpublished.
Unpublished or hidden pages do not appear in formatted PageArray value, only in unformatted.
Click any linked item for full usage details and examples. Hookable methods are indicated with the icon. In addition to those shown below, the Fieldtype class also inherits all the methods and properties of: Fieldtype, WireData and Wire.
Common
Saving
| Name | Return | Summary | |
|---|---|---|---|
Fieldtype Fieldtype Fieldtype | bool | Move this field’s data from one page to another. |
Configuration
| Name | Return | Summary | |
|---|---|---|---|
Fieldtype Fieldtype Fieldtype | array | Export configuration values for external consumption | |
Fieldtype Fieldtype Fieldtype | array | Convert an array of exported data to a format that will be understood internally |
Properties
| Name | Return | Summary | |
|---|---|---|---|
| Fieldtype | int |
Additional methods and properties
In addition to the methods and properties above, Fieldtype
API reference based on ProcessWire core version 3.0.259