Extensibility
Features are self-contained, but products often need to customize them. The extensibility system lets you override services, templates, models, hooks, and routes without forking the original feature.
Mechanism
What it does
Template hooks
Named slots in templates; features fill them with HTML callbacks
Refinement
A new feature overrides services, templates, hooks, or adds routes to an existing feature
Service locator
Features register replaceable service classes; routes resolve them at request time
Extension points
Features declare which parts are safe to override
Validation
Guardrails that prevent invalid overrides at startup and in CI
Quick reference
Mechanism
When to use
Example
Template hook (register)
Feature adds UI to a slot
auth registers layout.navbar.anonymous
Template hook (replace)
Refiner replaces a hook entirely
auth_2fa replaces layout.navbar.authenticated
Inter-feature hook
Feature adds UI to another feature’s template
notes_tags fills notes.create.form_extra
Service locator
Refiner swaps business logic
notes_tags overrides NotesService
Template override
Refiner replaces a page template
auth_2fa overrides auth/login_form.html
Model extension
Refiner adds columns/methods to a model
notes_tags adds tags to Notes
Route addition
Refiner adds new endpoints to a base blueprint
auth_2fa adds /login/2fa
Extra form fields
Base route passes hook-injected form data to service
notes passes **extra to NotesService.create()
Signal
React to domain events across features (no override)
profile listens to user_registered from auth
Table of contents