Most tutorials on dynamic templates stop at the moment the data appears on the page. For agency work that is roughly the halfway point, because the template still has to survive a non-technical client editing the content every week for the next three years.
That constraint changes the decisions. It is why this guide is organised around editability rather than around features, and why several of the recommendations below are about what not to build.
This covers Bricks specifically. If you are doing the same work in Oxygen, that is covered in Oxygen Builder integrations for agencies, and this guide assumes you already know what ACF is and how to register a field group.
The design constraint: what the client will touch
Decide this before you build anything, because it determines the whole architecture.
There are two workable models. In the first, content lives in ACF fields and the client edits those fields in the normal WordPress admin, never opening Bricks. In the second, the client edits inside the builder, which means giving them access to a tool that can delete a section as easily as change a heading.
For client work the first model wins almost every time. A field labelled Hero heading with a character hint underneath is a thing a receptionist can update safely. The same text as an editable element inside a builder canvas is a thing a receptionist can accidentally drag into a footer. Choosing fields over builder access is the single highest-leverage decision in this whole area, and it is free.
The trade-off is honest: fields are less flexible for the client. They cannot add a new section that you did not anticipate. On a client site that is usually a feature.
Query loops: the workhorse
The query loop is where most dynamic templates begin. You attach a loop to a container, point it at a post type, and Bricks repeats the container’s contents for each result.
Three things worth settling early. Decide ordering explicitly rather than accepting the default, because a default that happens to look right with eight posts will look wrong at eighty. Set a sensible result limit and decide what pagination does. And decide what an empty result renders, because the state nobody designs is the state the client will screenshot and email you about.
Keep the loop’s markup as simple as it can be. Every extra wrapper inside a loop is multiplied by the number of results, and a structure that is merely untidy at three items is genuinely heavy at fifty.
Where a loop needs to filter on a custom field rather than a taxonomy, expect to write a meta query. This is the point at which the visual interface stops being sufficient and it is worth knowing before you promise a filter UI to a client.
Repeaters and flexible content
Repeaters are the field type that makes client-editable pages genuinely possible. A repeater of team members, service items, FAQ entries or logos gives the client a list they can add to, reorder and shorten without touching layout.
Design the repeater around what varies. If every row has an icon, a heading and two lines of text, the repeater has three fields and the template controls everything else. The failure mode is a repeater with a colour picker, an alignment control and a width setting, which is a page builder with extra steps and hands the client exactly the power you were trying to withhold.
Flexible content is the next step up, letting the client assemble a page from a set of layouts you defined. It is powerful and it is the point where the maintenance cost turns real: every layout is a template you build, style, test and support. Two or three layouts on a service page template is usually the sweet spot. Twelve is a bespoke page builder that you now maintain.
Set minimum and maximum row counts on both. A design that works with three columns and collapses with seven should be prevented from having seven, and the field settings are where you prevent it.
Relationship and post object fields
Relationship fields are how you connect content that genuinely relates: a case study to the services it used, a staff member to their department, a product to related products.
The practical trap is the return format. A relationship field can return post objects or post IDs, and the two behave differently when you feed them into a query loop or a conditional. Pick one convention across the whole project and document it, because mixed return formats produce bugs that look like builder problems and are not.
Be careful with bidirectional relationships. Wanting the connection to appear from both sides is a reasonable request and it is a genuine maintenance burden if you implement it by asking the client to set it in two places. Either automate it or decide that one direction is enough.
Conditional output
Conditions are what stop a template looking broken when a field is empty, and they are the most commonly skipped step in a build.
The rule is simple and worth applying mechanically: every optional field gets a condition on its wrapper, not just on the field. Hiding an empty heading while leaving its padded container behind produces a mysterious gap that the client will report as a bug and you will spend twenty minutes reproducing.
Conditions also let you handle the states a design brief never mentions. What the card looks like with no image. What the section does when the repeater has one row instead of four. What happens when a date has passed. Deciding these at build time is far cheaper than discovering them from a client email.
Do not use conditional display for anything that must be secure. A hidden element is still in the markup and still readable by anyone who opens developer tools.
Making it genuinely handover-safe
A few habits make the difference between a template that survives and one that generates support tickets.
- Label fields for the person editing, not for you. Homepage hero heading, max 60 characters beats hero_h1. Use the field instructions area; it is the cheapest documentation you will ever write.
- Constrain what can break the design. Character limits, image size guidance, required fields, minimum and maximum repeater rows. Every constraint is a support ticket you do not receive.
- Never let a client edit a template. Content is theirs, structure is yours. That boundary is the whole game.
- Use an options page for site-wide values. Phone number, address, footer copy. Editing those in one place beats hunting them across templates.
- Test the template empty and overfull. A template proven only against ideal content has not been tested.
The permissions and white-labelling side of this, including what to lock in Bricks itself, is covered in handing over a Bricks site.
Where this sits in the stack
Dynamic templating is the capability that separates a builder you can run an agency on from a builder you use to make pages. Both Bricks and Oxygen do it well, which is why the choice between them comes down to team fit rather than capability, as set out in our Bricks vs Oxygen comparison.
What matters more than the tool is the discipline: fields for content, templates for structure, conditions on everything optional, and a client who never needs to open the builder.
Frequently Asked Questions
Do I need ACF Pro to build dynamic templates in Bricks?
For anything beyond simple text and image fields, yes in practice. Repeaters, flexible content and the options page are Pro features, and those are exactly what agency templates rely on. The free version is fine for a handful of custom fields on a post type and runs out quickly after that.
Should I use ACF or Meta Box with Bricks?
Both are well supported and the decision is rarely technical. ACF has the larger community, more documentation and more freelancers who already know it, which matters at handover. Meta Box is strong on developer ergonomics and registering fields in code. If you have no existing preference, ACF is the safer default for client work.
How do I stop clients breaking a dynamic template?
Keep them out of the builder entirely. If content lives in ACF fields, the client edits fields in the WordPress admin and never opens Bricks, which means there is no layout for them to damage. That single decision prevents most post-handover damage, and it is a design choice made at build time, not a permission setting applied later.
Why is my query loop returning nothing?
Usually the post type or the field name does not match, the field is empty on the posts being queried, or a relationship field is storing an object where the query expects an ID. Check what the field actually contains in the database before assuming the loop is wrong; the query is usually correct and the data is usually the problem.
Can I output a repeater inside a query loop?
Yes, and it is a common pattern for things like a team page where each member has a list of specialisms. Nest the repeater loop inside the post loop and be careful about which context each field is reading from, because a field name that exists on both levels will resolve to the innermost one and give you confusing results.
Build the field structure first and the template second. If you can hand the client a set of clearly labelled fields and never give them builder access, the template will still be intact in two years, which is the only real measure of whether this was built properly.
Need a WordPress developer?
Let's build something fast, scalable, and SEO-ready — from a custom theme to a full headless stack.
Get in Touch