Skip to main content

Nested Scheduled Content

Nested scheduled content lets a parent piece of scheduled content contain one or more child pieces in designated slots, composing more complex layouts (e.g. a hero with three promo tiles beneath it).


Overview

  • A parent piece of scheduled content defines slots (placeholders) in its template using metadata of type BannerId.
  • A child piece of scheduled content (nested) is assigned to each slot.
  • Parent and child are stored separately; the relationship is tracked via childIds (on the parent) and parentIds (on each child).
  • Only one level of nesting is allowed. Nested scheduled content cannot itself have nested scheduled content.

Scheduled Content Types

TypeDescriptionProperties
ParentHas one or more child items in its layoutchildIds: string[]
Child (nested)Renders inside a parent's slotparentIds: string[]
RegularStandalone; no children, no parentsNo childIds or parentIds

Defining Nested Slots in Code

In a parent's React/JSX template, a slot is declared with the BannerId type:

// Declare a slot: const <variableName> = $(<label>:BannerId)
const Col1 = $(col1:BannerId);
const Col2 = $(col2:BannerId);
const Col3 = $(col3:BannerId);

const ThreeColumnsAcross = () => (
<div className="container">
<Col1 />
<Col2 />
<Col3 />
</div>
);

export default ThreeColumnsAcross;
  • variableName (e.g. Col1) – Used as the component in JSX.
  • label (e.g. col1) – Becomes the slot ID (lowercased, often kebab-case like col1).
  • BannerId – Marks this as a nested scheduled content slot.

Assigning Child Scheduled Content in the Visual Experience Engine

  1. Open a parent piece of scheduled content in the Visual Experience Engine.
  2. In the metadata section, each BannerId field shows Select From Banner List.
  3. Choose scheduled content to assign to that slot.
  4. Save. The Visual Experience Engine updates:
    • Parent: childIds = list of assigned child IDs
    • Each child: parentIds = list of parent IDs (including this one)

Restrictions on which scheduled content can be selected:

  • Cannot select the current (parent) item.
  • Cannot select scheduled content that already has children (they are parents themselves).
  • Cannot select deleted scheduled content.
  • Scheduled content that itself has parents (is already nested) cannot have BannerId metadata – "Nested Banners are not allowed to have Nested Banners."

Backend: Insert Inner Banner (Web Only)

For web scheduled content (appType === 'web'), when a parent is saved, the insertInnerBanner hook runs:

  1. Find BannerId variables – Parses the parent's raw code for const X = $(label:BannerId).
  2. Resolve IDs – Uses metadata value to map each slot to a child ID.
  3. Inline child code – For each assigned child:
    • Fetches the child's variant code
    • Replaces template variables in the child
    • Obfuscates and renames the child component
    • Inlines it into the parent's replaced code
  4. Replace slot placeholders – Each <Col1 />-style tag is replaced with a <div data-inner-filled="col1"><Inner_0_xyz /></div> that renders the inlined child.
  5. Unassigned slots – Replaced with <div data-inner-empty="col1"></div>.
  6. childIds – Set on the parent with the list of assigned child IDs.

This produces a single combined replaced code string used for SSR and pre-rendering.


Backend: Parent–Child Sync

When scheduled content is created or updated, parentChildBannerSync (runs in onResponse) keeps the relationship consistent:

  1. New children – If new IDs appear in childIds, add the current item's ID to each child's parentIds.
  2. Removed children – If IDs are removed from childIds, remove the current item's ID from those children's parentIds.
  3. Propagate to parents – If the current item has parentIds (it is a child), each of its parents is re-processed: insertInnerBanner, fetchImageDims, transpile, preRender, fetchHTMLDims, then saved. This keeps parent compiled code in sync when a child changes.

Workflow Summary

  1. Create parent template – Use BannerId metadata: const Col1 = $(col1:BannerId) and render <Col1 /> in the layout.
  2. Create child scheduled content – Standard scheduled content (images, simple React components, etc.).
  3. Assign children – In the parent's form, use "Select From Banner List" for each BannerId field.
  4. Save – The API runs insertInnerBanner, updates childIds/parentIds, and propagates changes to parents.
  5. On the page – The web script loads scheduled content, initializes NestedBannersContext from metadata, and NestedSlotRenderer renders each child in its slot.

Key Takeaways

  • Parent scheduled content declares slots via BannerId metadata and assigns child scheduled content in the Visual Experience Engine.
  • Child scheduled content is standalone scheduled content that renders inside parent slots; it cannot nest further.
  • Backend (web): child code is inlined into the parent's replaced code for SSR; childIds and parentIds track the relationship.
  • Frontend: NestedSlotRenderer and NestedBannersContext handle runtime assignment and rendering; initialization comes from parent metadata when scheduled content loads.