Skip to content

docs(ui): make generated wrappers the public Template default #236

Description

@linkdata

Summary

Public ui.Template APIs currently treat an empty outerHTMLTag as an unwrapped partial. An unwrapped Template has no single DOM node carrying its Element JID, so it cannot safely serve as a reusable or reconciled UI value. In particular, Container removal and ordering require each logical child to have one addressable direct DOM node.

No production or example call site in this repository uses $.Template with an empty wrapper. Existing occurrences are tests and benchmarks. Structural fragments that need no wrapper can use native html/template inclusion so the enclosing Template owns their DOM.

Make an empty public wrapper default to "div" and document that public Template values always have an addressable wrapper. Whole-page rendering remains unwrapped through the private pageTemplate path in ui.Handler.

Class / severity

API documentation / safe defaults — Low. The current API makes a lifecycle-invalid reusable value easy to construct, but ordinary callers already supply a wrapper.

Current behavior

tmpl := ui.NewTemplate("", "partial", dot)
// tmpl.OuterHTMLTag == "" and rendering emits no JID-owning wrapper.

RequestWriter.Template("", ...) has the same unwrapped behavior. The documentation also describes unwrapped Templates as Register updaters and discusses Template reuse in Containers without qualifying that children must be wrapped.

Intended behavior

tmpl := ui.NewTemplate("", "partial", dot)
// tmpl.OuterHTMLTag == "div"

RequestWriter.Template("", ...) should render the same generated div wrapper. Callers needing an unwrapped static/structural partial should use Go's native template action:

{{template "partial" .}}

JaWS-managed partials should use their semantic root element as the wrapper, such as tr, td, li, or option.

Why this matters

Container reconciliation sends Remove and Order operations using each child Element's JID. An unwrapped Template emits no node with that JID, so browser removal/order cannot target its output even though the server removes or reorders the logical Element.

Defaulting public construction to div prevents that invalid state without introducing a constructor error or panic.

Acceptance criteria

  • NewTemplate("", name, dot) stores "div" as OuterHTMLTag.
  • RequestWriter.Template("", name, dot, ...) renders a generated div wrapper with the JaWS ID and wrapper attributes.
  • ui.Handler continues to render whole-page templates without a generated wrapper through its private page-rendering path.
  • Document native {{template ...}} inclusion for unwrapped structural fragments.
  • Remove or revise public documentation claiming that an unwrapped Template is a supported Register updater.
  • Qualify Template/Container identity documentation so reusable children always have one addressable wrapper.
  • Update lib/ui tests, README, examples, and the JaWS skill to the same contract.
  • Add regression coverage showing a Container built with NewTemplate("", ...) can remove and reorder its child normally.

Notes

Template has exported fields, so direct struct literals remain an escape hatch unless separately restricted. The public contract should direct callers through NewTemplate and state that reusable Template values require a non-empty wrapper.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationgoPull requests that update go codeseverity:low

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions