VoltexaHubDocumentation1.8.0Install the beta
Browse documentation

Development

Develop a web plugin

Scaffold a plugin with documented hooks, routes, permissions and safe migrations.

On this page

Scaffold locally#

Work in a disposable development install. Run:

php artisan forum:make-plugin hello-board
php artisan forum:plugin install hello-board
php artisan forum:plugin enable hello-board

The scaffold includes a manifest, Plugin.php and escaped Blade examples. Never patch core. The example uses a public slot and /extensions/hello-board/example; explicitly grant hello-board.view to the intended group to access its endpoint/navigation.

Use documented web extension points#

Implement App\Extensions\Plugin::boot(Hooks $hooks). Public slots are forum.top and post.after. Slot output is HTML, so escape user text in the Blade view. Filter application is opt-in, not a hook into every core operation. ThreadCreated occurs after commit; side effects must be idempotent.

$hooks->slot('forum.top', fn (array $context) => view('hello-board::banner')->render());
$hooks->webRoute('example', 'GET', 'hello-board.view', fn () => view('hello-board::example'));
$hooks->navigation('example', 'Hello board');

Register your view namespace. Declare the namespaced ability in plugin.json. Public endpoints use the fixed dispatcher and support GET/POST. POST requires authentication, CSRF and current ability checks. Your handler must further validate input and authorize each referenced object's reads, writes, search and counts. A global ability is insufficient for object-level access.

Settings, personal actions and editors#

Use ConfigurablePlugin for settings; CustomSettingsPlugin can supply a richer plugin-namespaced administration view. Personal POST routes derive the owner from the authenticated request and separately authorize referenced objects. Editor adapters replace text controls but preserve the body field, preview contract and core attachment input. Read the complete reference before using these contracts.

Dependencies and migrations#

Use stable major.minor.patch versions and documented dependency constraints. Use globally unique migration filenames and plugin-prefixed owned tables. Design migrations for retries after partial nontransactional DDL. Never edit released migrations: ship corrective migrations and preserve all published files. Bump the version and use the normal upgrade lifecycle; do not write installed-version records yourself.

Verify and distribute#

Test permitted/denied guests and members, direct routes, writes, escaping, CSRF, dependency failures, install/upgrade/disable/re-enable/uninstall, and migrations on an existing database. Package only plugins/hello-board with supported versions and instructions. Public plugin boot does not run in CLI/queued listeners; unsupported queued registration must not be assumed. The billing-provider contract is a documented separate lazy-loading integration.

See full plugin tutorial, lifecycle and architecture.