TruCMS is a modular Laravel website builder and application platform. This guide shows you how to use every part of it, how to create your own plugins and themes, and how to extend the platform through the hooks it exposes.
TruCMS is a server-rendered Laravel application. A core provides content management, a visual page builder, themes, multilingual content, media, roles and permissions, menus, widgets, settings, updates and a plugin system. On top of that core sit installable modules: TruCommerce (shop and POS), Booking (appointments), TruPayments (payment hub) and four gateway add-ons (Stripe, PayPal, Braintree, Mollie). Your own extensions are built exactly like these modules.
Two documentation sets
Site owners have their own user guide, which covers installation, everyday administration and the bundled modules screen by screen. This developer guide is for people who read, extend or maintain the code, and it does not repeat the user guide's step-by-step screens.
| You want to… | Go to |
|---|---|
| Understand how everything fits together | Architecture overview |
| Set up a machine and run the tests | Local development |
| Learn what each admin screen does and which code backs it | Using TruCMS |
| Understand modules, plugins and their lifecycle | How the plugin system works |
| Build something end to end | Tutorial: build a plugin |
| Pick the right extension point for a goal | What can I extend? |
| Build or customise a theme | Creating a theme |
| Look up a facade, helper, command, permission or hook | Reference |
+---------------------------------------------------------------------------+
| CORE (app/, routes/, config/, resources/themes/) |
| pages posts taxonomy menus widgets ads users roles teams |
| tickets settings themes plugin manager page builder slugs |
+---------------------------------------------------------------------------+
| HOOK LAYER (the only way modules touch the core) |
| AdminBooting event | MenuManager | SettingsManager | Dashboard |
| Shortcode registry | Widgets | AppPages | BindingSourceRegistry | Roles |
+----------------+----------------+----------------+------------------------+
| TruPayments | TruCommerce | Booking | YOUR PLUGIN |
| payment hub | shop + POS | wizard+cabinet| Modules/YourPlugin |
+----------------+----------------+----------------+------------------------+
| Gateway add-ons: Stripe | PayPal | Braintree | Mollie |
+---------------------------------------------------------------------------+The core never needs to know about a business module, and modules reach the core only through the hook layer. That is what makes it safe to add or remove a plugin without editing core files, and why core updates never touch your plugin. The few places where the code does not follow this rule yet are listed in Known quirks.
You only need to know a few of the libraries underneath TruCMS, because their APIs show through in plugin code:
| Concern | What TruCMS uses | Where you meet it |
|---|---|---|
| Framework | Laravel 13 on PHP 8.4 or newer | Everywhere |
| Views | Blade, server-rendered. There is no single-page front end | Admin and public screens |
| Modules | nwidart/laravel-modules | Plugin structure, module:* commands, the Module facade |
| Admin UI / public UI | CoreUI 4 and Bootstrap 5.3 / Bootstrap 5.3 with Echo's styles, built with Vite | Your markup |
| Page builder | GrapesJS with TruCMS's shortcode, template and binding layers | Shortcodes and data-bound sections |
| Permissions | spatie/laravel-permission | Permission, Role, ->can() |
| Media | spatie/laravel-medialibrary | HasMedia models and uploads |
| Widgets | arrilot/laravel-widgets | Front and dashboard widget classes |
| Payments and shop | The Vanilo framework | Payable, payment events, gateway contracts |
| Quality | Pest, Laravel Pint, PHPStan (Larastan) | Tests and checks |
.env, or to uploads; or add theme options. See Settings screens.They apply to everything you add, and Conventions and rules explains each one.
resources/themes/admin/… (or in your module's resources/views); public screens under resources/themes/echo/….Modules/{Name}, never in app/. Do not add Modules\* references to app/Models.->can('permission name'). Policies exist only for Team and Ticket.sync and broadcasting is dormant. Verify the deployment before relying on either.__() and language files).| Goal | Mechanism | Guide |
|---|---|---|
| A new admin area with its own tables and screens | Plugin + routes + sidebar item | Tutorial |
| A configuration page | SettingsManager::add() inside an AdminBooting listener | Settings |
| A block editors drag into pages | Shortcode class + Blade component | Shortcodes |
| A section that shows live records but stays editable | BindingSource | Data-bound sections |
| A box on the admin dashboard | Dashboard::admin()->row()->widget() | Dashboard |
| A sidebar/footer widget | Arrilot widget + Widgets::register() | Widgets |
| A new public page type (like "Shop page") | AppPages::register() and/or a resolvable slug | Page types |
| A new payment method | Gateway module on TruPayments | Payments |
| A new public look | Theme extending default | Themes |