Botble Plugin Development
Use Botble conventions first, then apply this plugin-specific workflow.
Workflow
- Inspect nearby plugins before adding new structure.
- Prefer Botble generators where available:
php artisan cms:plugin:create,cms:make:model,cms:make:form,cms:make:table,cms:make:controller,cms:make:request,cms:make:route. - Create the plugin under
platform/plugins/{plugin}with predictable namespaces, translations, routes, providers, migrations, andplugin.json. - Register admin routes through
AdminHelper::registerRoutes(). Prefer implicit route model binding; usewherePrimaryKey()on custom raw-ID routes. - Register permissions in
config/permissions.phpand attach them to dashboard menu items and routes. - Implement
activate(),deactivate(), andremoved()only when lifecycle work is needed.removed()must drop all plugin tables and clean plugin settings. - Run syntax, formatting, and targeted tests.
Required Structure
platform/plugins/your-plugin/
config/general.php
config/permissions.php
database/migrations/
resources/lang/en/your-plugin.php
resources/js/
resources/sass/
resources/views/
public/
routes/web.php
routes/api.php
src/Database/
src/Enums/
src/Forms/
src/Http/Controllers/
src/Http/Requests/
src/Models/
src/Providers/
src/Repositories/
src/Services/
src/Tables/
src/Widgets/
src/Plugin.php
vite.build.mjs
plugin.json
Implementation Rules
- Models extend
Botble\Base\Models\BaseModel. - Use
casts(): array, not a$castsproperty, unless local code clearly still uses the property. - Migrations use
foreignId()and include proper cascade/null behavior. - Controllers use Botble response helpers such as
withCreatedSuccessMessage()andwithUpdatedSuccessMessage(). - Forms extend
FormAbstractand use typed field classes with FieldOptions. - Tables use typed column classes; use
FormattedColumnfor custom display. - Use
trans('plugins/{plugin}::file.key'), never__()in plugin code. - Register SlugHelper, SeoHelper, LanguageAdvancedManager, DashboardMenu, hooks, and assets only when the plugin needs them.
- Use
BaseHelper::clean()for unescaped HTML andRvMedia::getImageUrl()for media. - Declare assets in
vite.build.mjs; do not createwebpack.mix.js. Runnpm run productionwhen distributable assets must be mirrored into the plugin'spublic/directory.
Load References
- Read
references/examples.mdfor model, form, table, provider, and route examples. - Read
../botble-conventions/references/quick-reference.mdfor baseline Botble rules.