ProcessWire Structured Content: Choosing Between Repeater, Page Reference, and Blocks
A decision guide for ProcessWire sites needing reusable structured content blocks. Compare core Repeater fields, Page reference patterns and the community Blocks module for editor UX, query performance and template complexity.
13 Jul 2026, 09:17 UTC

Pick the right container for structured content
The problem is not how to add fields, it is where to store reusable structured blocks so editors can work fast and pages stay fast to load. In ProcessWire the three supported patterns are core Repeater fields, Page reference fields pointing to a dedicated content page, and the community Blocks module. The practical rule is: use Repeater for tightly coupled ordered sub-items that belong to one parent, use Page references for loosely coupled reusable content, and consider Blocks when editors need drag-and-drop layout composition across multiple field types.
Options at a glance
| Option | Best fit | Storage | Editor UX | Query pattern |
|---|---|---|---|---|
| Repeater | Ordered sub-items owned by one parent, e.g., hero slides, FAQ rows | Separate repeater items as child pages linked by parent ID | Native field tab, add/reorder inline | $page->repeaterField returns a PageArray |
| Page reference | Reusable blocks shared across pages, e.g., a call-to-action used on multiple landing pages | Page ID stored on source page, target page has its own template and fields | Select from page tree, separate edit screen for target | $pages->get($page->refField) |
| Blocks module | Layout composition with multiple block types per page, visibility rules | Module-managed field storing block type and data | Drag-and-drop builder, per-block type fields | $page->blocks iterated by type |
Trade-offs
Repeater keeps content colocated and simple to query. It is native core, no extra module, and sorting is built in. Duplication is high if the same block is needed elsewhere, and deep nesting or large item counts increase admin save time and page load time because each item is a page row.
Page reference reduces duplication and allows independent publishing workflow for the referenced page. Changes to the target propagate to all referrers. The cost is extra page management, more joins when loading, and permission edge cases where an editor can link to a page they cannot edit, leading to inconsistent visibility.
Blocks improves editor flexibility and layout reuse across field types. It adds a module dependency, a learning curve, and more complex queries because multiple block types must be rendered with different partials. API and UI can differ across ProcessWire core versions, so verify compatibility in your dev environment before adoption.
Concrete validation patterns
Validate each pattern in a dev environment with a test page before committing to a template.
Repeater validation
Create a test page with a Repeater field, for example hero_repeater, containing three items with a headline field. In the template file under /site/templates/, with file edit access, add:
$items = $page->hero_repeater;
foreach($items as $item) {
echo $item->headline;
}
Expected check: the PageArray iterates in the order set in the admin. Risk: large repeaters increase query count and admin save time. Limit item count or paginate in templates.
Page reference validation
Create a content block template with a body field. Create two source pages with a Page reference field content_block pointing to the same target. In the source template:
$block = $pages->get($page->content_block);
if($block) {
echo $block->body;
}
Expected check: updating the target page body is reflected on both source pages. Risk: editors can reference pages outside their permission scope. Restrict selectable pages in the field settings.
Blocks module validation
Install Blocks module in dev only. Add two block types, e.g., text and image. Build a page with mixed blocks. Dump structure to confirm type and data:
foreach($page->blocks as $block) {
// $block->type and $block->data are available per module implementation
}
Expected check: iteration yields expected types and data without extra database round trips in a single request. Risk: module is community maintained; verify compatibility with your core version and test rendering partials per type.
How to decide
- Choose Repeater when items are ordered, belong to one parent, and will not be reused elsewhere.
- Choose Page reference when the same content must be reused, versioned independently, or edited by a different team.
- Choose Blocks when editors need visual layout composition with multiple field sets per page and you can accept a module dependency.
Limitations to keep in mind: Repeater queries scale with item count, Blocks adds complexity to templates, and Page references require careful permission handling. Verify each pattern with a small test page and inspect the resulting PageArray or block structure before scaling to production.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.