What a component says it should look like the moment it is dropped — declared by whoever wrote it, rather than guessed by this CMS.
Why this exists
MishkaCmsCore.Runtime.PageBuilder.Starter can furnish a dropped component without being told
anything: it reads Phoenix's own inner_block convention and the conventional slot names, and
falls back to a generic line. That works, and it works for a kit this install has never seen — but
it is inference. The word "alert" in a component's name is a guess about what the component means,
and nobody who ships a component library should have to name things this CMS's way to get a good
drop.
So a component may declare its own, and a declaration always wins:
"extra": {
"furnishing": {
"body": "<tr><td>Ada Lovelace</td><td>Active</td></tr>",
"slots": [
{"name": "header", "body": "Name"},
{"name": "header", "body": "Status"},
{"name": "option", "body": "First choice", "attrs": {"value": "one"}}
]
}
}Both keys are optional. body alone furnishes the content between the tags; slots alone
furnishes a component whose content is a list of entries; declaring body: "" explicitly says "put
nothing inside", which a spinner wants and the heuristics would otherwise override.
Untrusted by construction
This is a third party's JSON, on the same footing as the bundle itself — see
MishkaCmsCore.UiKit.Contract, which is why anything malformed answers :none and the heuristics
take over, rather than raising into a palette render. A slot entry that fails validation is dropped
on its own; the rest of the furnishing stands.
Two things it deliberately does NOT do. It does not accept a function or a module reference: a
furnishing may travel through a MishkaInstaller hook payload, which is plain-map only — the
MishkaCmsCore.Dashboard.Widget rule. And it does not template anything; the strings are HEEx
fragments written verbatim, so a component that wants a random id asks for one through the ordinary
seeding path rather than through a placeholder syntax invented here.
Summary
Functions
Reads a declared furnishing, or answers :none when there is none to read.
Whether a declaration says anything at all.
A sample %MishkaCmsCore.Builder.Furnishing{} populated from defaults + type-based fallbacks.
Types
Functions
Reads a declared furnishing, or answers :none when there is none to read.
:none is not a failure — most components declare nothing, and the heuristics are the answer for
them. It is also what a malformed declaration gets, for the reason in the moduledoc.
Whether a declaration says anything at all.
A furnishing that validated but carries neither a body nor a slot is treated as absent, so a kit
writing "furnishing": {} does not silently strip the content the heuristics would have given.
A sample %MishkaCmsCore.Builder.Furnishing{} populated from defaults + type-based fallbacks.