StarView's own template representation, rendering to HTML and diffing into
element patches. Compiled templates hold a StarView.Template.Program with
evaluated values. Hand-built templates hold StarView.Template.Node trees.
A snapshot holds already-evaluated values. Building one runs every chosen
expression exactly once. Compiled rendering merges static markup; diff/2
materializes both trees and can cost more than rendering a bounded region.
It saves bytes on the wire, not database reads or expression evaluation.
Rendering
Compiled templates have nodes: nil; use nodes/1 to inspect their tree.
A template must hold either nodes or a compiled program, never both.
to_html/1 and to_iodata/1 render server-side HTML. Static text and static
attribute values are trusted compiler output and emitted verbatim. Dynamic
values and attributes are escaped through the public Phoenix.HTML API with
HEEx escaping rules, so rendering dynamic content needs :phoenix_html.
Templates implement Phoenix.HTML.Safe for serialization by the Phoenix
host. The native template tree rejects legacy HEEx values; components and
slots used inside ~STAR must also return StarView.Template.
Diffing
diff/2 compares a previous snapshot with the next one and returns either
{:ok, patches} or {:reset, reason}. Send each StarView.Template.Patch
with StarView.Elements.patch/3; on reset, send the whole region again.
Patches target existing elements by their DOM id. An element is a target
only when:
- its id is the element's only id attribute, matches
[A-Za-z][A-Za-z0-9_-]*and is unchanged; - that id appears exactly once in both snapshots;
- its tag, voidness and namespace are unchanged;
- every ancestor has the same structure, branch keys and keyed order.
Any other change bubbles up to the nearest target ancestor. A patched element replaces all of its descendants' patches, so patches never overlap.
Reset reasons:
:initial- there is no baseline.:template_changed- the template fingerprint changed.{:unaddressable, reason}- a change has no target ancestor.{:duplicate_key, key}and:missing_key- a keyed collection has ambiguous item identity.
Limitations
- Legacy HEEx values are incompatible. Inline
~Hsigils fail during compilation; legacy component/slot results fail with a conversion error during evaluation. Convert the page and its called components together. - Trusted raw HTML remains opaque; ids inside it cannot be checked for duplicates against the template. Keep document-wide ids unique.
- Descendants of
svgandmath,template,head, raw-text elements, custom elements (such as Rocket hosts), elements markeddata-ignore*and nodes withmeta[:browser_owned?]are never targets. Changes there patch the nearest ancestor, which keeps the existing server-markup behavior rather than integrating with browser-owned lifecycles. - Patches always use the
:outermode and the:htmlnamespace. - Targeting assumes the rendered HTML nests validly, so the browser keeps every element where the template put it.
Summary
Functions
Diffs the previous snapshot against next.
Returns the template as a fully expanded StarView.Template.Node list.
Renders the template to an HTML binary.
Renders the template to HTML iodata.
Types
@type t() :: %StarView.Template{ fingerprint: binary() | nil, nodes: [StarView.Template.Node.t() | StarView.Template.Program.t()] | nil, program: StarView.Template.Program.t() | nil, source: map() }
Functions
@spec diff(t() | nil, t()) :: {:ok, [StarView.Template.Patch.t()]} | {:reset, reset_reason()}
Diffs the previous snapshot against next.
Returns {:ok, patches} (empty when the HTML is unchanged) or
{:reset, reason} when next must be sent whole. A nil baseline returns
{:reset, :initial}.
@spec nodes(t()) :: [StarView.Template.Node.t()]
Returns the template as a fully expanded StarView.Template.Node list.
Compiled templates hold a StarView.Template.Program and nodes: nil; this
builds their tree from already-evaluated values without running template
expressions again. Nested native templates under :value and :component
nodes, including lists of them, are expanded too.
Renders the template to an HTML binary.
Renders the template to HTML iodata.