MishkaCmsCore. Runtime. PageBuilder. Tree. Serializer
(Mishka CMS Core v0.0.1)
Copy Markdown
View Source
Turns a MishkaCmsCore.Runtime.PageBuilder.Tree back into a HEEx template — the other half of the
round trip MishkaCmsCore.Runtime.PageBuilder.Tree.parse/1 opens.
This is what the editor saves. The React editor's serializer only understood palette-dragged
elements, so saving a loaded page rewrote every original node as <div class="element-...">;
that whole failure mode is gone because there is only one node shape to emit.
Two steps, deliberately separate
serialize/1 is total: it walks the tree and emits source, never raising and never consulting a
parser. format/1 then runs Phoenix.LiveView.HTMLFormatter over that source and returns
{:ok, binary} | {:error, reason}.
Keeping them apart is what lets the save path be safe without a rescue around the whole thing:
serialize, re-parse to prove the output is readable, and only then format. A template that fails
either check is refused with a message instead of being written over a working page.
ADR-11: formatting on save is an explicit, documented normalization. A hand-written template will come back formatted the first time it is saved through the editor, and the round-trip tests assert that the second save is a fixed point.
Attribute fidelity
name="literal", name={expression}, a bare disabled, and a root {@rest} are four different
things and all four survive. The old JSON encoding collapsed the middle two into the string
"{expr}" and recovered them with a binary_part guess, which is why viewBox and friends kept
getting mangled.
Summary
Functions
Formats generated HEEx with the LiveView formatter.
Emits the tree as HEEx source, unformatted. Total — an unreachable node or an unknown kind is skipped rather than raising.
Emits one node and its descendants as HEEx source — what the code drawer shows for a selection.
The full save-time pipeline: serialize, prove the output re-parses, then format.
Functions
Formats generated HEEx with the LiveView formatter.
Returns {:error, reason} when the formatter cannot read the source. That only happens if we
emitted something invalid, so the save path treats it as a refusal rather than writing the
template anyway.
@spec serialize(MishkaCmsCore.Runtime.PageBuilder.Tree.t()) :: String.t()
Emits the tree as HEEx source, unformatted. Total — an unreachable node or an unknown kind is skipped rather than raising.
@spec serialize_node(MishkaCmsCore.Runtime.PageBuilder.Tree.t(), String.t()) :: String.t()
Emits one node and its descendants as HEEx source — what the code drawer shows for a selection.
@spec to_heex(MishkaCmsCore.Runtime.PageBuilder.Tree.t()) :: {:ok, String.t()} | {:error, term()}
The full save-time pipeline: serialize, prove the output re-parses, then format.
Returns {:error, reason} if the emitted source cannot be read back, which is the guarantee that
a save never replaces a working template with one the compiler would reject.