Overview
Let other extensions add columns, actions, buttons and tabs to your own engine's tables and details views — what it takes, in five steps, and a checklist.
Making Your Views Extensible
The pages before this one are about adding to other engines' views. This section is about the other side: making your engine's views accept additions, the same way Fleet-Ops, Storefront, Ledger, IAM and Developers do.
When your views are extensible, any extension can register a column into acme:shipment:table:columns, and your shipments table renders it, with no change to your engine.
What It Takes
Name your resources
Choose the registry names for each resource, <your-extension>:<resource>. If your action services extend ResourceActionService, they work the names out for you.
Declare your registries
Create them when your extension boots, so they exist before others register into them.
Pass @registry to your layouts
Layout::Resource::Tabular and Layout::Resource::Panel merge registered items for you when given a registry.
Accept registered filters
Build your index controllers' query params with queryParamsFor(), so filterable columns others register can filter.
Give your built-in items stable ids
Others place their items before and after yours, by id.
Views that don't use the resource layouts, such as a hand-built table or a dialog, can merge registered items themselves; see Custom Views.
Checklist
- Action services extend
ResourceActionService, withregistryResourceset where the model name differs from the resource name -
declare('<extension>', [...resources])is called insetupExtension - Tables pass
@registry="<extension>:<resource>:table" - Details panels pass
@registry="<extension>:<resource>:details", and side panelsregistry: this.detailsRegistry - Index controllers build
queryParamswithqueryParamsFor() - Built-in columns, actions and buttons have stable ids, and the delete action's id is
delete - Your registries and built-in ids are documented, so other extension authors can find them