modules/system/README.md
The System module is October CMS's core infrastructure layer, built on top of Laravel. It manages plugin lifecycle, database migrations, mail templates, settings, asset compilation, image resizing, multisite configuration, and the Twig markup engine. It bootstraps before all other modules and is required for the entire CMS to function. The System module is what makes October CMS a true plugin-based platform -- every feature beyond core infrastructure is delivered as a self-contained plugin with its own migrations, permissions, settings, and navigation, all discovered and managed automatically.
The System module is responsible for:
| Service | Class | Description |
|---|---|---|
system.plugins | System\Classes\PluginManager | Plugin discovery, loading, and lifecycle |
system.updater | System\Classes\UpdateManager | Migrations and marketplace updates |
system.versions | System\Classes\VersionManager | Plugin version tracking |
system.mailer | System\Classes\MailManager | Email template rendering |
system.settings | System\Classes\SettingsManager | Settings page registry |
system.sites | System\Classes\SiteManager | Multisite management |
system.combiner | System\Classes\CombineAssets | CSS/JS asset compilation |
system.resizer | System\Classes\ResizeImages | Image resize and thumbnailing |
system.markup | System\Classes\MarkupManager | Twig extension registry |
system.manifest | System\Classes\ManifestCache | Manifest file caching |
Plugins are self-contained packages that live in plugins/{author}/{name}/ and have a Plugin.php registration file extending System\Classes\PluginBase. Each plugin brings its own migrations, models, controllers, components, permissions, settings, and navigation -- installed by dropping it in a directory or running a single command. No service provider wiring, no manual route registration, no config publishing.
Phase 1 - Discovery: PluginManager scans the plugins/ directory for Plugin.php files, respects the disabled list, and sorts by dependency order.
Phase 2 - Registration: For each plugin, the manager loads the composer autoloader, registers config/views/language namespaces, and calls register().
Phase 3 - Boot: After all plugins are registered, the manager calls boot() on each plugin.
| Method | Description |
|---|---|
register() | Register services, listeners, and bindings |
boot() | Boot logic after all plugins are registered |
registerComponents() | CMS components |
registerMarkupTags() | Twig functions and filters |
registerNavigation() | Backend menu items |
registerPermissions() | Permission definitions |
registerSettings() | Settings pages |
registerMailTemplates() | Mail template definitions |
registerMailPartials() | Mail partials |
registerMailLayouts() | Mail layouts |
registerFormWidgets() | Form field widgets |
registerFilterWidgets() | List filter widgets |
registerReportWidgets() | Dashboard report widgets |
registerContentFields() | Tailor content fields |
registerSchedule($schedule) | Scheduled tasks |
registerConsoleCommand($key, $class) | Artisan commands |
Plugins declare dependencies with the $require property:
public $require = ['Acme.User', 'Acme.Billing'];
The PluginManager resolves and sorts by dependency order automatically.
The mail system intercepts Laravel's mailer to render emails using Twig templates stored in the database.
MailTemplate::syncAll() imports plugin templates into the databaseMailManager intercepts the content and renders the Twig template with the database-stored version (if customized)| Component | Description |
|---|---|
MailTemplate | Email template content (subject, body, code) |
MailLayout | Wrapper template (default, system, or custom) |
MailPartial | Reusable email components (header, footer, button, panel) |
MailSetting | SMTP/mail driver configuration |
public function registerMailTemplates()
{
return [
'acme.blog:new-post' => 'acme.blog::mail.new-post',
];
}
Features include CSS inlining for email clients and full Twig syntax support with custom token parsers.
System\Models\SettingModel is the base class for plugin settings. Settings are stored in the system_settings table with per-site isolation for multisite.
<?php namespace Acme\Blog\Models;
class Settings extends \System\Models\SettingModel
{
public $settingsCode = 'acme_blog_settings';
public $settingsFields = 'fields.yaml';
}
Read and write settings:
Settings::get('api_key');
Settings::set('api_key', 'new-value');
The SettingsManager organizes settings pages into categories. Plugins register settings pages with registerSettings():
public function registerSettings()
{
return [
'settings' => [
'label' => 'Blog Settings',
'description' => 'Configure the blog plugin',
'category' => 'Blog',
'icon' => 'icon-pencil',
'class' => \Acme\Blog\Models\Settings::class,
'order' => 500,
],
];
}
The CombineAssets class combines and minifies CSS/JS files:
The ResizeImages class generates thumbnails on demand:
storage/app/resources/resize/The SiteManager handles multisite routing and configuration:
SettingModelThe MarkupManager registers Twig extensions from modules and plugins.
Over 40 functions including: input(), post(), get(), url(), route(), asset(), config(), env(), session(), trans(), str_*(), md() (markdown), html_*(), time_since(), time_tense(), collect(), carbon(), dump()
Plugins register Twig functions and filters via registerMarkupTags():
public function registerMarkupTags()
{
return [
'functions' => [
'myFunction' => [$this, 'myFunctionHandler'],
],
'filters' => [
'myFilter' => [$this, 'myFilterHandler'],
],
];
}
The Twig security policy (System\Twig\SecurityPolicy) prevents dangerous operations in templates, controlling which methods and properties can be accessed.
| Command | Description |
|---|---|
october:migrate | Run all pending migrations |
october:update | Check for and apply updates |
october:fresh | Reset the demo theme |
october:up | Bring the application online |
october:down | Put the application into maintenance mode |
october:passwd | Change an admin password |
october:mirror | Mirror public files for symlink-free hosting |
october:optimize | Optimize the application |
october:util | Utility commands |
october:about | Display application information |
| Command | Description |
|---|---|
plugin:install | Install a plugin |
plugin:remove | Remove a plugin |
plugin:enable | Enable a disabled plugin |
plugin:disable | Disable a plugin |
plugin:refresh | Re-run a plugin's migrations |
plugin:seed | Run a plugin's seeder |
plugin:list | List installed plugins |
plugin:check | Check plugin dependencies |
plugin:test | Run a plugin's tests |
| Model | Description |
|---|---|
File | File attachments (used by $attachOne / $attachMany) |
MailTemplate | Email template content |
MailLayout | Email layout wrappers |
MailPartial | Reusable email components |
MailSetting | Mail driver configuration |
Parameter | Internal key-value store |
EventLog | System event and error log |
PluginVersion | Plugin version tracking |
SiteDefinition | Multisite configuration |
| Trait | Description |
|---|---|
AssetMaker | Register CSS/JS assets in controllers and widgets |
ViewMaker | Render partials and views with variable injection |
ConfigMaker | Parse YAML configuration files |
ResponseMaker | Create AJAX and redirect responses |
EventEmitter | Fire and listen to local events on objects |
| Table | Description |
|---|---|
system_files | File attachments |
system_settings | Plugin and module settings |
system_parameters | Internal parameters |
system_plugin_versions | Installed plugin versions |
system_plugin_history | Migration history per plugin |
system_mail_templates | Email templates |
system_mail_layouts | Email layouts |
system_mail_partials | Email partials |
system_event_logs | Error and event log |
system_request_logs | HTTP request log |
system_site_definitions | Multisite definitions |
system_site_groups | Site groups |
deferred_bindings | Temporary model relationships |
| Event | Description |
|---|---|
system.settings.extendItems | Extend settings pages |
system.updater.migrate | After migrations complete |
mailer.beforeAddContent | Override email content rendering |
exception.beforeReport | Before an exception is reported |
exception.beforeRender | Before an exception is rendered |
backend.ajax.beforeRunHandler | Before AJAX handler execution |
console.schedule | Register scheduled tasks |