Find your goal, then follow the link. Each guide in this section stands on its own.
The two example plugins
Examples use one of two plugins. Testimonials is the complete plugin from the tutorial; its full source is in the tutorial and in the downloadable testimonials-1.0.0.zip. Playground is a smaller illustrative plugin with a Note model (table playground_notes, alias playground), used where Testimonials does not need a feature. Its snippets are complete for the feature they show, but there is no separate download.
| I want to… | Use… | Registered where | Guide |
|---|---|---|---|
| Add a whole new feature with its own database tables | A plugin (module) | Modules/{Name} | Tutorial |
| Add an entry to the admin sidebar | MenuManager::make() | AdminBooting listener | Admin menu and dashboard |
| Show a card, chart or list on the admin dashboard | Dashboard::admin()->row()->widget() | Provider boot() | Admin menu and dashboard |
| Show something on the visitor account dashboard | Dashboard::user()->row()->widget() | Provider boot() | Admin menu and dashboard |
| Add a settings screen or field | SettingsManager::add() | AdminBooting listener | Settings screens |
| Add a theme colour, typography or layout option | The defaults block of theme.json | Theme | Theme options |
| Control who can do what | Spatie permissions + ->can() | Migration/seeder + routes | Permissions and roles |
| Add admin or public pages | Route provider + controllers + views | Module RouteServiceProvider | Routes, controllers and views |
| Store data with translations, media or slugs | BaseModel, Translatable, HasMedia, HasSlug | Models | Models, migrations and media |
| Let admins choose "which page is the Shop page" | AppPages::register(PageDefinition) | Provider boot() | Page types and public URLs |
Give my records pretty URLs like /my-thing | ResolvableSlug + ResolvedSlugRenderer | Model + config('slugs.models') | Page types and public URLs |
| Add a draggable block to the page builder | Shortcode class + Blade component | Provider boot() | Shortcodes |
| Let editors pick records inside a designed section | BindingSource | Provider boot() | Data-bound sections |
| Add a widget for sidebars and footers | Widgets::register() + Arrilot widget | Provider boot() | Widgets and widget areas |
| Add links of my content to the menu builder | MenuBuilder::register() | AdminBooting listener | Menus and navigation |
| Ship ready-made page layouts | Template sources + a seeder | Module resources/page-templates | Template library |
| Ship a whole demo site | A niche seeder / .trucms.zip package | Seeders or package | Template library |
| Accept payments for my own records | PaymentManager on a Payable | Your controllers | Payments and gateways |
| Add a payment provider | A gateway plugin on TruPayments | Module provider | Payments and gateways |
| React to bookings, payments, tickets or my own events | Event listeners | Provider or EventServiceProvider | Events, jobs and schedules |
| Run something on a schedule or in the background | configureSchedules(), jobs | Module provider | Events, jobs and schedules |
| Translate the interface or content | Lang files, Translatable | Module lang/ | Localization |
| Make pages cacheable (or not) | doCache, CacheProfile, invalidator | Routes + models | Caching |
| Make my block available to the AI assistant | ->ai([...]) on the shortcode definition | Shortcode | AI assistant |
| Change how the public site looks | A theme (or view overrides) | resources/themes | Creating a theme |
| Restyle a plugin without editing it | Theme view override | resources/themes/{theme}/vendor/{alias}/… | Routes, controllers and views |
| Remove or reorder core admin items | MenuManager::remove(), Dashboard::...->removeRow() | Listener / boot() | Admin menu and dashboard |
| Moment | Examples |
|---|---|
Every request (register(), boot()) | Config merge, bindings, translations, breadcrumbs, shortcodes, widget classes, binding sources, app pages, dashboard rows, Blade components, listeners, observers |
Admin requests (AdminBooting) | Sidebar entries, settings sections, menu-builder sources, removing/reordering core admin items |
| Render time | Shortcode components, widget run(), dashboard widget run(), binding resolve() (bake time) |
| Deploy time | Migrations, permission migrations/seeders, module:publish, template seeders, composer dump-autoload |
| Schedule / queue | Cleanup commands, notification jobs, calendar sync, refresh of baked pages |
Being explicit about limits saves time. At present these require a core change (or a workaround):
App\Services\Settings\Fields builds a fresh registry on every call, so there is no runtime hook; you can compose the existing 18 types (see Settings screens).PageBuilderAiRegistry. The OpenAI-compatible adapter covers most self-hosted and third-party endpoints.module.json can require other plugins but not a TruCMS version.