Interface composition
Docara builds the interface like a construction kit on three levels. A layout sets the page regions, a section fills a region with blocks, and a Smart component or a view draws the final element. All of these are settings from checked descriptions in registries, not a second template engine.
Three levels
- A layout is responsible for the page geometry and the names of its regions.
- A section goes into a suitable region and lays out blocks in slots.
- A block, Smart component or view receives checked data. It creates the
final HTML through the shared registries and
SmartComponentGateway.
The page Markdown is parsed separately, into a typed in-memory document
(Document IR). The length of a ::: fence does not pick the composition
level.
The checked settings and the parsed Markdown turn into a shared recipe (Composition Recipe). The standard SIMAI Framework builder creates a Composition Document from it — the finished page tree. Docara restores its renderers’ input from the tree and creates the HTML. The author files are not rewritten along the way.
The path from a file to a page
Each step is described in its own registered file:
| Step | File or place | Responsible for |
|---|---|---|
| Layout | resources/layouts/docara.docs.json |
regions, whether they are required, container width |
| Layout tree | resources/views/layout.docara.docs.json |
allowed elements and region places |
| Region | header, sidebar, main, outline, footer from the layout description |
an insertion place, not a code branch by component ID |
| Section | resources/sections/docara.article.json, docara.header.json, docara.navigation.json, docara.outline.json, docara.shell.json |
suitable regions and allowed blocks |
| Section tree | resources/views/section.docara.article.json, section.docara.header.json, section.docara.shell.json |
allowed slots |
| Block | resources/blocks/content.document.json, content.markdown.json, content.smart.json, shell.element.json, shell.smart.json |
the block data schema and its capability |
| Smart component | from the Docara package, SIMAI Framework or the project | parameters, views, presets, slots, assets, browser hydration |
| View | a registered view, preset or template | final HTML, assets, provenance |
| Shared presentation | src/PortableSite/SurfacePresentation.php |
the single outer frame of Surface, Hero, Showcase and Promo |
This is how an ordinary documentation page goes through:
Markdown owner
-> typed Document IR
-> Layout docara.docs
-> region main
-> Section docara.article
-> slot content
-> Block content.document
-> generated Composition Recipe
-> Framework resolveRecipe
-> Composition Document
-> Docara renderer projection
-> SmartComponentGateway when a Smart leaf is present
-> registered View
-> DeclarativePageRenderer: regions into the layout View Tree
-> PageBuilder result
Who checks compatibility
For each container, Atlas shows the nesting rules: allowed_children,
slots, min_children, max_children, order, max_depth and
depth_semantics. The value relative_subtree_root_level_1 means that each
container counts itself as level 1.
The registry rejects an unknown node kind, tag, attribute, utility, region or slot in the markup tree (View Tree). This happens before registration. Project settings only pick admitted IDs. They cannot name a class, a callback, PHP code or a template path.
Shared presentation does not change the owner
Surface is a container for author content. Hero, Showcase and Promo are typed
blocks of their own with their own meaning. Their owner, states, parameters
and provenance come from their own descriptions. The outer frame — width,
container and background — is assembled for all of them by one immutable
Surface presentation. You cannot wrap these blocks in Surface. The whole page
and <head> still belong to the application, and DeclarativePageRenderer
places the regions into the layout tree.
The project atlas
Atlas is the list of everything you can put on a page: layouts, sections,
blocks, views, bindings and presets. docara atlas --json outputs it, and it
is built only from the admitted DesignRegistry, SmartRegistry and
BindingRegistry registries. The build records the Atlas fingerprint in its
receipt. Atlas is only a computed view of the registries; you cannot edit it as
a source. Below is its current content, with no hand-written list:
docara.brandingbindingsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.brand.docara.navigationbindingsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.primary-navigation,shell.secondary-navigation.docara.outlinebindingsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.outline.content.documentblocksupportedOwner:
simai/docara; namespace:content; origin:docara; provider:docara.builtin; authoring:configuration.content.iconblockrejectedOwner:
simai/docara; namespace:content; origin:requirement; provider:component.catalog.product_requirement; authoring:block.Capabilities:
add_semantic_icon.content.markdownblocksupportedOwner:
simai/docara; namespace:content; origin:docara; provider:docara.builtin; authoring:configuration.content.smartblocksupportedOwner:
simai/docara; namespace:content; origin:docara; provider:docara.builtin; authoring:configuration.docara.alertblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
report_status.docara.backlinksblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_pages_linking_here.docara.badgeblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.inline_definition; authoring:inline.Capabilities:
label_status.docara.bannerblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_bounded_page_announcement.docara.buttonblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.inline_definition; authoring:inline.Capabilities:
link_as_action.docara.cardblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
content.embeddable.docara.codeblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
include_external_code.docara.component_referenceblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_component_reference_from_manifest.docara.detailsblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
disclose_optional_content.docara.diagramblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
render_declarative_diagram.docara.downloadblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
download_file.docara.embedblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
embed_external_content.docara.exampleblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_live_example_and_source.docara.figureblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_illustration_with_caption.docara.gridblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:container.Capabilities:
content.embeddable.Container:
allowed_children=[docara.card]; slots=[]; min_children=1; max_children=12; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.heroblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
explain_product_value,primary_landing_action.docara.htmlblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
render_isolated_trusted_html.docara.iconblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.inline_definition; authoring:inline.Capabilities:
add_semantic_icon.docara.kbdblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.inline_definition; authoring:inline.Capabilities:
name_keyboard_input.docara.logosblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_ecosystem_members,show_trust_signals.docara.mathblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
render_tex_formula.docara.mediablocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
pair_content_with_media.docara.stepsblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
content.embeddable.docara.surfaceblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:container.Capabilities:
present_content_surface.Container:
allowed_children=[]; slots=[content]; min_children=1; max_children=64; order=declared; max_depth=3, depth_semantics=relative_subtree_root_level_1.docara.tabsblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:container.Capabilities:
switch_between_equivalent_views.Container:
allowed_children=[docara.example, docara.code, docara.figure, docara.alert]; slots=[content]; min_children=1; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.treeblocksupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:component.catalog.typed_definition; authoring:block.Capabilities:
show_file_structure.native.codeblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
show_code.native.description_listblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
define_terms.native.footnotes_and_sourcesblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
cite_source_with_footnote.native.headings_and_textblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
mark_text,structure_prose.native.links_and_imagesblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
illustrate_content,link_content.native.lists_and_quotesblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
list_items,quote_content.native.tableblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
compare_small_datasets.native.task_listblocksupportedOwner:
simai/docara; namespace:native; origin:native; provider:component.catalog.portable_markdown_profile; authoring:markdown.Capabilities:
track_checklist_items.project.footer-smartblockprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:configuration.shell.elementblocksupportedOwner:
simai/docara; namespace:shell; origin:docara; provider:docara.builtin; authoring:configuration.shell.set-passportblocksupportedOwner:
simai/docara; namespace:shell; origin:docara; provider:docara.builtin; authoring:configuration.shell.smartblocksupportedOwner:
simai/docara; namespace:shell; origin:docara; provider:docara.builtin; authoring:configuration.ui.badgeblockproposalOwner:
simai/docara; namespace:ui; origin:requirement; provider:component.catalog.product_requirement; authoring:block.Capabilities:
label_status.ui.dataviewblockproposalOwner:
simai/docara; namespace:ui; origin:requirement; provider:component.catalog.product_requirement; authoring:block.Capabilities:
present_structured_data.ui.tabsblockrejectedOwner:
simai/docara; namespace:ui; origin:requirement; provider:component.catalog.product_requirement; authoring:block.Capabilities:
switch_content_panels.docara.docslayoutsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Container:
allowed_children=[section]; slots=[header, sidebar, main, outline, footer]; min_children=1; max_children=7; order=layout_regions; max_depth=3, depth_semantics=relative_subtree_root_level_1.docara.branding:compactpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.brand.docara.branding:defaultpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.brand.docara.branding:logopresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.brand.docara.branding:textpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.brand.docara.navigation:compactpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.primary-navigation,shell.secondary-navigation.docara.navigation:defaultpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.primary-navigation,shell.secondary-navigation.docara.navigation:headerpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.primary-navigation,shell.secondary-navigation.docara.navigation:treepresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.primary-navigation,shell.secondary-navigation.docara.outline:defaultpresetsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin-bindings; authoring:configuration.Capabilities:
shell.outline.ui.checkbox:defaultpresetsupportedOwner:
simai/bx-simai.main; namespace:ui; origin:framework; provider:framework.lock; authoring:configuration.Capabilities:
smart.preset.ui.dropdown:defaultpresetsupportedOwner:
simai/bx-simai.main; namespace:ui; origin:framework; provider:framework.lock; authoring:configuration.Capabilities:
smart.preset.ui.input:defaultpresetsupportedOwner:
simai/bx-simai.main; namespace:ui; origin:framework; provider:framework.lock; authoring:configuration.Capabilities:
smart.preset.ui.list-item:defaultpresetsupportedOwner:
simai/bx-simai.main; namespace:ui; origin:framework; provider:framework.lock; authoring:configuration.Capabilities:
smart.preset.docara.articlesectionsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Capabilities:
content.document.Container:
allowed_children=[content.document, content.markdown, content.smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.headersectionsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Capabilities:
shell.brand,shell.primary-navigation.Container:
allowed_children=[shell.smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.navigationsectionsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Capabilities:
shell.secondary-navigation.Container:
allowed_children=[shell.smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.outlinesectionsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Capabilities:
shell.outline.Container:
allowed_children=[shell.smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.docara.shellsectionsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:container.Capabilities:
shell.brand,shell.content-after,shell.content-before,shell.footer,shell.outline,shell.primary-navigation,shell.secondary-navigation.Container:
allowed_children=[shell.element, shell.set-passport, shell.smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.project.footersectionprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:container.Capabilities:
shell.footer.Container:
allowed_children=[project.footer-smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.layout.docara.docsviewsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:configuration.section.docara.articleviewsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:configuration.section.docara.headerviewsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:configuration.section.docara.shellviewsupportedOwner:
simai/docara; namespace:docara; origin:docara; provider:docara.builtin; authoring:configuration.section.project.footerviewprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:configuration.
Shell parts
One site shell serves the docs, site and landing page types. Variants
change the registered presentation, and the rendering path stays the same.
| Interface part | Who is responsible | Capability or presentation | Can the project replace it |
|---|---|---|---|
| Logo and name | docara.brand through the docara.branding binding |
full, compact, logo, text |
through an admitted brand capability |
| Header menu | docara.navigation |
header |
yes |
| Section tree in the sidebar | docara.navigation |
tree |
yes |
| Compact menu for phones | docara.navigation |
compact |
yes |
| Page contents | docara.toc |
the docara.outline binding |
yes |
| Search | a registered search Smart component | the search capability in the shell | yes |
| Breadcrumbs | a registered Smart component | reading context | yes |
| “Previous” and “Next” links | a registered Smart component | reading context | yes |
| Reading settings | docara.preferences |
side panel | yes |
| Footer | a package or project Smart component | the footer capability | yes |
The whole document: <head>, canonical address, metadata, asset list |
PageBuilder and the application |
belongs to the application | no |
header, tree and compact are three views of one docara.navigation.
BindingRegistry picks the right one by the capability and the provider
description. SmartComponentGateway, the renderer, DeclarativePageRenderer
and PageBuilder stay the same. If view is not given, the previous default
behaviour is kept.
A project contribution cannot replace the canonical address, the language
metadata, the build receipt, the provenance of search and the menu, or an
arbitrary <head> fragment. These parts belong to the application. This way
verify-static can check the site, and a full build and a single-page build
give the same result.
Shell data bindings
The shell.smart block can pick only a registered binding in the bind
field. A binding connects page data with an already registered Smart
component. It is not a PHP function or a template path. The built-in registry
holds three bindings:
| ID | Capabilities | Smart component |
|---|---|---|
docara.branding |
shell.brand |
docara.brand |
docara.navigation |
shell.primary-navigation, shell.secondary-navigation |
docara.navigation |
docara.outline |
shell.outline |
docara.toc |
These commands show the binding description and its provenance:
docara list binding
docara inspect binding docara.navigation
docara schema binding
The layout region and the section declare suitable capabilities. Before rendering, the build rejects an unknown binding and an incompatible capability. It also rejects an attempt to pass parameters owned by the binding or to substitute a package ID. Project JSON cannot set a class, a function, or a path to a PHP file, a template or any other file.
Your own project layouts and blocks
A project can add its own layout, section, block and safe markup tree to the
design/ folder. This needs no changes to the engine. The chain is the same:
Layout → Region → Section → Slot → Block → Smart or a safe element
One DesignRegistry reads all definitions. Built-in IDs belong to the
package, and project IDs to the namespace from docara.json:
{"smart":{"namespace":"project"}}
A project ID must start with project.. It cannot replace docara.*,
content.*, shell.* or ui.*. Repeats, symbolic links, leaving the root and
unknown definitions stop the build.
Files
design/
├── layouts/project.docs.json
├── sections/project.article.json
├── blocks/project.document.json
└── views/
├── layout.project.docs.json
└── section.project.article.json
The layout sets the safe markup tree, the regions, their defaults and the place of the document:
{
"schema": "docara.layout.v1",
"key": "project.docs",
"default": false,
"view": "layout.project.docs",
"configuration": {
"container": {"max": 7},
"scrollbar": {"preset": "overlay"},
"content": {"gap": 0}
},
"document": {
"region": "stage",
"section": "project.article",
"slot": "content",
"block": "project.document"
},
"regions": {
"stage": {
"required": true,
"default_enabled": true,
"default_sections": [],
"section_types": ["content"]
}
},
"assets": []
}
The section declares suitable regions, slots and blocks. The block picks one of the already registered safe renderer kinds. JSON does not accept PHP, a template path, a function, arbitrary HTML or CSS.
To pick the project layout, reset the inherited branch:
{
"layout": {
"$reset": true,
"key": "project.docs"
}
}
A project contribution to the shell
A shell part from the project is data files in the allowed design/ or
smart/ folder and a reference to an admitted binding ID. You do not need to
change the engine’s src/. The connection order:
- Choose your namespace in
docara.json. - Create the files with
docara scaffold: first--dry-run, then--applywith the plan hash. - Check the description, schema, namespace and capabilities.
- Make sure with
docara atlas --jsonthat the element hasowner=projectandsupport=project. - Look at the result in a separate preview on a real page.
- Only after that, build the whole site.
The build stops if:
- a project ID matches a package or SIMAI Framework ID;
- the settings try to override parameters owned by the binding;
- a capability, region or slot conflicts with ones already taken;
- a path leaves the root, goes through a symbolic or hard link, matches another one ignoring case, or points to an arbitrary file;
- a shell contribution tries to change the whole page or
<head>.
The starter contains a small footer example. The project section and block
admit only the registered project.footer-links into the footer region.
Neither the settings nor Markdown pick a path to a PHP file or a template. The
ordinary project Smart component provider finds the component, its view and
assets.
The footer works as a shell part, and project.install-builder and
project.product-configurator as page content. All three go through the same
registries and SmartComponentGateway. The project elements on this site:
project.footer-smartblockprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:configuration.project.footersectionprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:container.Capabilities:
shell.footer.Container:
allowed_children=[project.footer-smart]; slots=[content]; min_children=0; max_children=64; order=declared; max_depth=2, depth_semantics=relative_subtree_root_level_1.project.footer-linkssmartprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:block.Capabilities:
smart.render.project.install-buildersmartprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:container.Capabilities:
smart.children,smart.hydration,smart.render.Container:
allowed_children=[ui.checkbox, ui.dropdown, ui.input]; slots=[controls]; min_children=1; max_children=64; order=declared; max_depth=8, depth_semantics=relative_subtree_root_level_1.project.product-configuratorsmartprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:container.Capabilities:
content.embeddable,smart.children,smart.hydration,smart.render.Container:
allowed_children=[ui.checkbox, ui.dropdown]; slots=[controls]; min_children=1; max_children=64; order=declared; max_depth=8, depth_semantics=relative_subtree_root_level_1.section.project.footerviewprojectOwner:
project/project; namespace:project; origin:project; provider:project.project; authoring:configuration.
Preview
The preview has no renderer of its own. PreviewKernel runs the ordinary
PortableSiteBuilder with the same Markdown parsing, DesignRegistry,
SmartComponentGateway, renderer, asset builder, DeclarativePageRenderer
and PageBuilder. It takes the needed part from the finished page.
Full composition
The docs type
The landing type
Commands
The docara preview smart|region|layout|page command builds the chosen part
into .docara-preview/output/<target>/:
docara preview page --page=/en/components/alert/
docara preview layout --page=/en/components/alert/
docara preview region --page=/en/components/alert/ --selector=main
docara preview smart --page=/en/components/alert/ --selector=ui.alert
For automation, add --json. With --watch, the command watches everything
the chosen page depends on. That is the interface labels for its language and
the layout, section, block, Smart component, template and assets from the
package and the project that are actually used:
docara preview region --page=/en/components/alert/ --selector=main --watch
The result folder holds three files:
artifact.html— exactly the chosen fragment;index.html— the same page as in the working build, for checking in the browser;preview.json— assets, provenance, dependencies and hashes.
The needed local CSS, JS, SIMAI Framework files and page assets are published
next to them. So open index.html over HTTP from the
.docara-preview/output/<target>/ folder. The working build receipt and other
pages are not copied there. The preview does not overwrite the ordinary
build_* folders.
A change to an unrelated project Smart component does not rebuild the chosen
part. A change, addition or removal of a file inside a project or package
element that is actually used triggers one rebuild of this page. The
target_only=true flag is derived from this and from the rebuild result, not
set in advance.
Why the preview does not reach the site
The preview result is isolated in .docara-preview/ and does not count as a
working build. Its receipt records build.purpose=preview, so verify-static
fails with PREVIEW_BUILD_PURPOSE_FORBIDDEN. The protection comes from the
receipt itself, not from a separate service marker next to it. Publishing
needs an ordinary full build.
Checking
php vendor/bin/phpunit --filter 'DesignRegistryTest|ProjectDesignCompositionTest|PreviewKernelTest'
cd docs/site
php ../../docara build production
php ../../docara verify-static build_production
Do not add project IDs to the engine’s PHP code or to schema enumerations. If you need a new executable renderer or API, that is a separate platform extension, not project JSON.
See also
- Layout regions — how a site author sets up regions
- Smart components — the component description, providers and the gateway
- Architecture — the build path from Markdown to HTML
- SDK for developers and AI agents — the
inspect,schema,scaffoldandpreviewcommands - Glossary
- Examples for developers