Skip to main content

ui:template

View as Markdown

Wraps its children in a <template> element and, for the duration of rendering them, makes them behave as if they were genuinely nested inside the named enclosing component - so ui:ref (used completely unmodified) resolves correctly even though this content is, structurally, plain slot content rather than a dedicated component's own template body.

This is needed because a component's slot content (the markup a consumer writes between two component tags, e.g. everything inside <ui:combobox.content>...</ui:combobox.content>) is always evaluated against the calling rendering context, not the component's own internal one. A bare ui:ref call written directly inside such slot content therefore doesn't, by default, know which component (or rootId) it belongs to.

ui:template fixes this generically for any component, by reading the real, currently-active component context (which - unlike the plain component/context variables ui:ref reads - is threaded correctly through slot-content nesting) and temporarily re-exposing it as those ordinary variables (component, context and rootId). ui:ref itself accepts the same context argument directly, for hand-authored elements that need this without being wrapped in a <template> - see its own docblock for when to reach for that instead.

Intended for content whose real data doesn't exist yet at server-render time and is filled in later, client-side (e.g. a combobox's async search results, file-upload item previews, recurring/array form-field rows) - clone the <template>'s content, find its ui:ref'd elements, and populate them directly.

Also marks a isRenderStencil flag on the component context for the duration of rendering children, so a nested component (e.g. combobox.item) can detect on its own that it's being rendered as a client-filled stencil rather than a real instance, without the template author having to pass an explicit prop for it.

name follows the same camelCase convention as ui:ref's own name argument - the <template> itself is marked like any other part (e.g. itemTemplate -> data-combobox-item-template="{rootId}").

context is only required when this ui:template sits inside slot content passed into another component - the common case: item/row markup a consumer authors for a primitive like combobox/fileUpload to clone, where the ambient component is whatever encloses that slot content, not the primitive itself. Omit it when ui:template is written directly inside a component's own template body instead (e.g. a custom, single-file component) - it then defaults to whichever component is already ambiently active there, the same way a bare ui:ref (no context argument) already does.

<ui:combobox.root>
  ...
  <ui:combobox.content>
    <ui:combobox.list>
      <ui:template name="itemTemplate" context="combobox">
          <ui:combobox.item>
              <span {ui:ref(name: 'title')}></span>
          </ui:combobox.item>
      </ui:template>
    </ui:combobox.list>
  </ui:combobox.content>
</ui:combobox.root>
Name Type Description Required Default
name string Ref name for the wrapping &lt;template&gt; element, camelCase (e.g. "itemTemplate") like ui:ref's own name argument. Yes -
context string camelCase base name of the enclosing component this template belongs to, e.g. "fileUpload". Only needed when this ui:template is slot content passed into another component - omit it when writing ui:template directly inside a component's own template body, where it defaults to whichever component is already ambiently active (the same fallback a bare ui:ref uses). No ''