Looping content sections
Pro
A Content sections field is a list where each row has its own layout: a Hero, a Quote, a Gallery. To display it, you loop over the field once and give each layout its own design.
Generate the sections
- Select a Group block and loop it over the Content sections field. The looped block must be able to hold other blocks.
- In the Data Loop panel, click Generate layout sections.
VX adds one group per layout inside the loop, with a block bound to each of that layout's fields. Each group has a visibility rule so it only shows on rows of its own layout. Style the groups however you like.
Running Generate layout sections again only adds groups for layouts that don't have one yet, so it's safe after you add a new layout to the field.
How the paths work
A section's fields are reached through their layout:
text
@post(sections.hero.heading)
@post(sections.quote.attribution)@post(sections.hero.heading) only has a value on rows whose layout is hero. That's why two layouts can both have a heading without mixing them up.
Two extra paths describe the row itself: @post(sections._layout) is the layout's key (hero), for rules; @post(sections._layout_label) is its label ("Hero banner"), for display.
What you see in the editor
Visibility rules normally don't apply in the editor. Layout groups are an exception: in the preview rows, groups for other layouts are hidden, so each preview looks like the published row. The row you're editing still shows every layout's group, so you can reach them all.
This only works for a group whose single rule compares @post(sections._layout) to a layout key, which is what Generate layout sections creates. If you add another rule, the group shows in every preview row, though the published page still follows all the rules.
Technical details for LLMs
- Generated gate per group:
{ "type": "dynamic", "expression": "@post(sections._layout)", "comparator": "is_equal_to", "args": ["hero"] }. - Editor gate recognition: exactly one enabled rule, unmodified
_layouttag, comparatoris_equal_to,is_not_equal_tooris_one_of, literal argument(s). Otherwise the block always renders in the canvas. - A layout segment asserts the row's layout:
@post(sections.hero.heading)resolves to nothing on non-hero rows; outside a loop, aggregators only see matching rows.@post(sections.hero)alone resolves to nothing. - The gate is still required even though paths are scoped: a bound block with an unresolved tag renders empty rather than disappearing.