Package authoring jobs
Start with the job the package performs, then choose the smallest extension points that make that job installable and testable.
Add a page type
Section titled “Add a page type”Use this when the package owns a new kind of content, not just extra fields on an existing type.
- Declare
contentand usuallyadminincapell.jsonsurfaces. - Add a
page-typecontribution with the class that registers the type. - Register the page type from a runtime provider with
CapellCore::registerPageType(...). - Add admin configurators or schema extenders only for fields the package owns.
- Add tests that assert the page type appears in the registry and unsupported contexts fall back to the base type list.
Keep rendering data outside public Blade. Load page data in Actions, controllers, payload builders, or view components before rendering.
Add a frontend widget
Section titled “Add a frontend widget”Use this when the package renders public HTML through Layout Builder, a frontend component alias, or a render hook.
- Declare
frontendinsurfaces. - Declare the closest contribution type:
frontend-component,render-hook,asset,route, orsection. - Register frontend behavior from the frontend/runtime provider, not an admin-only provider.
- Pass hydrated data into Blade. Public package views must not query models, lazy-load relations, or inspect the current admin user.
- Add anonymous public-output safety tests proving no authoring selectors, model IDs, field paths, permissions, package internals, or signed admin URLs leak.
Use RenderHookRegistry::registerView() for view-name hooks, registerInlineBlade() for inline Blade snippets, registerCallable() for closures, and registerExtension() for class-based render hooks. Package-owned keyed hooks should use RenderHookContributionData::view(), inlineBlade(), or extension() so diagnostics, stable dedupe keys, and cache-safety metadata stay attached.
Add publishing workflow
Section titled “Add publishing workflow”Use this when the package changes editorial state, review, approval, reminders, or release windows.
- Declare
workflowandadminsurfaces. - Put state changes in Actions. UI, commands, jobs, and subscribers should delegate to those Actions.
- Declare permissions and settings in
capell.json. - Register admin pages, widgets, table columns, notifications, or validation subscribers through Admin bridges or typed extenders.
- Test the Action directly, then test the UI/command only for delegation, permissions, prompts, and visible state.
Packages that affect publishing should also document whether they block publish, warn editors, or provide advisory information only.
Add cache invalidation
Section titled “Add cache invalidation”Use this when package data can change public output.
- Declare
deliveryand any public surface the package affects. - Declare cache-related capabilities such as
cache-invalidation,cache-blocking,public-static, orfrontend-assetswhere accurate. - Register model dependencies with
CacheInvalidationRegistry::registerDependency(...). - Set
performance.cacheSafetyaccurately incapell.json. For a package with a frontend contribution andcacheable: true,capell:extension-auditreports an error (“unsafe public cache variance”) whenvariesBylists any ofauth,locale,preview-token,role,site,userorworkspace. Output that genuinely varies on one of those axes is not publicly cacheable: declarecacheable: falserather than removing the axis to pass the audit. - Test both the invalidation path and the safe fallback when the package is missing or disabled.
If public output varies by user, role, preview token, workspace, or other private state, mark it clearly. Cached HTML must be safe for anonymous visitors, normal signed-in users, admins, crawlers, and static exports.
Add marketplace proof
Section titled “Add marketplace proof”Use this when the package will be listed, sold, bundled, or installed through Marketplace.
- Fill
product,commercial, andmarketplacemetadata incapell.json. - Declare every shipped contribution; do not leave
contributesempty for a package with runtime surfaces. - Add screenshots with useful alt and caption text, and commit referenced assets.
- Document setup, support, compatibility, safety caveats, and screenshot capture instructions.
- Add tests that validate manifest metadata, contribution contracts, screenshot paths, docs links, commercial tier, support policy, and compatibility.
Marketplace copy should explain the outcome the package improves before naming implementation details.
Build one package
Section titled “Build one package”The normal path is:
- Scaffold with
php artisan capell:make-extension vendor/example --profile=minimal --path=packages. - Fill
capell.jsonwith identity, surfaces, provider buckets, dependencies, contributions, capabilities, performance, commercial, and marketplace metadata. - Put domain behavior in
src/Actionsand structured state insrc/Data. - Register runtime behavior from the provider bucket that owns it.
- Add the admin/editor surface through an Admin bridge when there is more than one admin concern.
- Add public output through frontend registries with safe hydrated render data.
- Add migrations and settings migrations with existence guards.
- Add tests for Actions, manifest/contribution contracts, install/setup behavior, public-output safety, and safe fallbacks.
- Add screenshots and docs when the package is Marketplace-ready.
- Run the package tests, audit the manifest, and verify docs links before release.
Use extension point chooser when deciding which registry or contract fits the job. Use extension point API reference only after the job and surface are clear.