Skip to content
docsv0.34.0

ComponentBook

The components the panel can compose with: the dashboard primitives of `milpa/live`, the shell's own two (`admin-sidebar`, `admin-section-header` — painted by {@see ShellHtmlRenderer}), plus every custom component the sections bring — one or a whole {@see \Milpa\Admin\Section\DeclaredView} of them. Built fresh per request — the registry of `milpa/live` is a plain map with no discovery, and the sections are discovered per request too, so the book follows them. A section that names a component nobody registered fails here, with the list of what exists. **One registry, in layers** (greenhouse decisions/0211). The book is a {@see CompositeComponentRegistry}: the panel's own layer first, then ONE layer per section that brought components, labelled with the section's id. That is what lets a single live endpoint serve the host's components and every guest's, and what makes shadowing loud instead of silent: two sections binding one name to DIFFERENT definitions throw {@see ComponentNameConflictException} naming the component and both sections, exactly as two plugins declaring one section id throw {@see \Milpa\Admin\Section\SectionConflictException}. The rule is `milpa/live`'s own — identity or a stateless class — not a second one invented here: two sections that reuse the SAME instance, or two instances of a class with no state, are one definition and no conflict. The RENDERER is held to the same rule, by the book itself ({@see RendererConflictException}). Two sections that legitimately share one definition may still each bring their own renderer, and the renderer registry resolves the last one registered: without this the first section's surface would be painted by the second's renderer, silently, in the one place whose whole point is that a collision is loud. Sharing the renderer instance (or a stateless class) is agreement; anything else names both. The names the book registers itself — the primitives and the shell's own two — are the host's: a section may NAME one (a `metric-card` section is the normal case) but never bring its own definition under it. A layer of its own would not save it: the panel's layer resolves first, so the guest's definition would be dead weight the endpoint could never reach; the book refuses instead ({@see ReservedComponentException}), which is what lets the header say a section never names its own declarer.

ComponentBook::__construct()

public function __construct(Milpa\Live\Contracts\Transport\StateTransferCodecInterface $codec, ?Milpa\Interfaces\Event\MilpaEventDispatcherInterface $events = null):

Parameters

Parameters of __construct()
NameTypeDescription
$codecMilpa\Live\Contracts\Transport\StateTransferCodecInterface
$events?Milpa\Interfaces\Event\MilpaEventDispatcherInterface

ComponentBook::forSections()

public static function forSections(Milpa\Admin\Section\SectionCatalogue $catalogue, Milpa\Live\Contracts\Transport\StateTransferCodecInterface $codec, ?Milpa\Interfaces\Event\MilpaEventDispatcherInterface $events = null): self

A book that has already adopted every section of a catalogue — what a page compiles with and what the live wire re-renders from, built the same way on both sides so an envelope signed by one is resolvable by the other.

Parameters

Parameters of forSections()
NameTypeDescription
$catalogueMilpa\Admin\Section\SectionCatalogue
$codecMilpa\Live\Contracts\Transport\StateTransferCodecInterface
$events?Milpa\Interfaces\Event\MilpaEventDispatcherInterface

Throws

UnknownComponentException when a section names a component nothing registered

ReservedComponentException when a section redefines one of the panel's own

ComponentNameConflictException when two sections bind one name to different definitions

RendererConflictException when two sections bring different renderers for one name

ComponentBook::register()

public function register(string $name, Milpa\Live\Contracts\Component\ComponentDefinitionInterface $definition, Milpa\Live\Contracts\Rendering\ComponentRendererInterface $renderer): void

Registers one component under a name, with the renderer that paints it — the book's one way in.

Parameters

Parameters of register()
NameTypeDescription
$namestring
$definitionMilpa\Live\Contracts\Component\ComponentDefinitionInterface
$rendererMilpa\Live\Contracts\Rendering\ComponentRendererInterface

ComponentBook::adopt()

public function adopt(Milpa\Admin\Section\AdminSection $section): void

Makes a section renderable: registers everything it brings — one component or the whole tree of a declared view — under its own layer, or checks that the one it names exists.

Parameters

Parameters of adopt()
NameTypeDescription
$sectionMilpa\Admin\Section\AdminSection

Throws

UnknownComponentException when the section names a component nothing registered

ReservedComponentException when the section brings its own definition under a name the book registered itself — a primitive, or one of the shell's own

ComponentNameConflictException when another section already bound one of those names to a different definition

RendererConflictException when another section already bound one of those names to a different renderer

ComponentBook::registry()

public function registry(): Milpa\Live\Contracts\Component\ComponentRegistryInterface

The registry the compiler and the live endpoint resolve component names against — every layer.

ComponentBook::renderers()

public function renderers(): Milpa\Live\Rendering\ComponentRendererRegistry

The renderers, answering per component name — the pair of the composite registry.

ComponentBook::names()

public function names(): array

The names the book can render — the primitives, then the shell's own, then the sections' — in registration order, each once.

ComponentBook::compiler()

public function compiler(array $defaults = []): Milpa\Live\Rendering\XhtmlComponentCompiler

A compiler over this book, with default props per component name.

Parameters

Parameters of compiler()
NameTypeDescription
$defaultsarray<string, array<string, mixed>>component name → props merged under the markup's attributes