Back to October

Backend Module

modules/backend/README.md

4.4.010.3 KB
Original Source

Backend Module

The Backend module is October CMS's administration panel. It provides user authentication, a complete CRUD framework driven by YAML configuration, reusable widgets, navigation management, and Vue-based components for building rich admin interfaces. Where most frameworks require writing boilerplate controllers, form templates, and validation logic for every model, October CMS generates fully functional admin pages from a few lines of YAML -- with sorting, searching, filtering, relationships, and file uploads all handled automatically.

Architecture Overview

The backend is built around controllers, behaviors, and widgets. This architecture eliminates repetitive CRUD development while remaining fully customizable when you need to go beyond the defaults:

  • Controllers handle routes and render pages. All backend controllers extend Backend\Classes\Controller.
  • Behaviors add CRUD patterns to controllers (forms, lists, relations) via the $implement property and YAML configuration files. A single controller can combine multiple behaviors to get a complete admin interface with zero hand-written HTML.
  • Widgets are self-contained UI components (form fields, filters, toolbars) that can be embedded in any controller. Over 15 form widgets ship out of the box, from code editors to file uploaders to repeating field groups.

Key Services

The module registers these singletons in the container:

ServiceClassDescription
backend.helperBackend\Helpers\BackendURL generation and backend utilities
backend.authBackend\Classes\AuthManagerAdministrator authentication
backend.menuBackend\Classes\NavigationManagerBackend menu system
backend.rolesBackend\Classes\RoleManagerRole and permission management
backend.widgetsBackend\Classes\WidgetManagerWidget registry

Facades

FacadeResolves to
BackendBackend\Helpers\Backend
BackendAuthBackend\Classes\AuthManager
BackendMenuBackend\Classes\NavigationManager
BackendUiBackend\Classes\UiFactory

Controllers

Backend controllers extend Backend\Classes\Controller which provides AJAX handling, view rendering, widget management, and authentication. Built-in controllers:

ControllerPurpose
AuthLogin, password reset, sign out
AuthGatesTwo-factor and authentication gates
UsersAdministrator management
UserRolesRole management
UserGroupsGroup management
PreferencesUser preferences
AccessLogsAccess log viewer
IndexBackend dashboard redirect
FilesSecure file downloads

Behaviors

Behaviors are attached to controllers via the $implement property. They add complete CRUD functionality driven by YAML configuration.

FormController

Provides create, update, and preview actions with YAML-configured form fields.

php
class Posts extends \Backend\Classes\Controller
{
    public $implement = [
        \Backend\Behaviors\FormController::class,
    ];

    public $formConfig = 'config_form.yaml';
}

Configuration file (config_form.yaml) defines the model class, form fields file, and page titles. Fields are defined in a separate fields.yaml file with field types, labels, spans, and options.

ListController

Provides an index action with sortable, searchable, filterable lists.

php
public $implement = [
    \Backend\Behaviors\ListController::class,
];

public $listConfig = 'config_list.yaml';

Configuration defines columns (columns.yaml), default sort order, records per page, and available scopes (scopes.yaml) for filtering.

RelationController

Manages model relationships (hasMany, belongsToMany, morphMany, etc.) with inline forms and lists.

php
public $implement = [
    \Backend\Behaviors\RelationController::class,
];

public $relationConfig = 'config_relation.yaml';

ImportExportController

Bulk import and export in CSV and JSON formats. Uses ImportModel and ExportModel base classes.

ReorderController

Drag-and-drop reordering for sortable models.

Widgets

Core Widgets

WidgetDescription
FormRenders form fields from YAML configuration
ListsRenders data tables with sorting and pagination
ListStructureTree-structured list with drag-and-drop
FilterScope-based list filtering
ToolbarButton toolbar with search integration
SearchSearch input widget
TableSpreadsheet-style data editor
ReportContainerDashboard report widget container
SiteSwitcherMultisite selector
RoleImpersonatorPermission testing via role impersonation

Form Widgets

Form widgets extend Backend\Classes\FormWidgetBase and provide specialized form field types:

WidgetDescription
CodeEditorSyntax-highlighted code editor
RichEditorWYSIWYG HTML editor
MarkdownEditorMarkdown editor with preview
FileUploadFile attachment with drag-and-drop
RelationDropdown/list for model relationships
DatePickerDate and time selection
ColorPickerColor selection
DataTableEditable spreadsheet
RecordFinderPopup record selector
RepeaterRepeating field groups
TagListTag input
NestedFormEmbedded sub-forms
SensitiveMasked input for secrets
PermissionEditorPermission checkbox matrix
PaletteEditorColor palette editor

Filter Widgets

Filter widgets extend Backend\Classes\FilterWidgetBase and provide list filter types:

WidgetDescription
TextText/string filter
DateDate range filter
NumberNumeric range filter
GroupGroup/checkbox filter

Form Designs

Form designs control the visual layout of forms:

DesignDescription
BasicDesignStandard stacked form
DocumentDesignDocument-style with header and body
PopupDesignModal/popup form
SidebarDesignForm with sidebar panel
SurveyDesignSurvey/wizard-style form

Vue Components

The backend provides reusable Vue 3 components that extend Backend\Classes\VueComponentBase:

ComponentDescription
AutocompleteTypeahead input
CodeEditorCode editor wrapper
MonacoEditorMonaco-based code editor
RichEditorRich text editor
DocumentMarkdownEditorMarkdown editor for documents
DocumentDocument layout frame
DropdownDropdown selector
DropdownMenuContext menu
DropdownMenuButtonButton with dropdown
ModalModal dialog
PopoverPopover tooltip
TabsTabbed interface
TreeViewHierarchical tree
SplitterResizable split panels
ScrollablePanelScrollable container
SpreadsheetSpreadsheet editor
UploaderFile upload handler
InspectorProperty editor / inspector
InfoTableKey-value display table
LoadingIndicatorLoading spinner

Models

ModelDescription
UserBackend administrator accounts
UserRolePermission roles
UserGroupUser groups
UserPreferencePer-user preferences
BrandSettingBackend branding (colors, logo)
EditorSettingCode editor preferences
PreferenceGlobal backend preferences
AccessLogLogin/access audit log
ImportModelBase class for CSV/JSON import
ExportModelBase class for CSV/JSON export

Creating a Backend Controller

This controller class -- combined with two YAML config files for form fields and list columns -- produces a complete admin CRUD interface with create, update, delete, search, sort, pagination, and permission checks:

php
<?php namespace Acme\Blog\Controllers;

use Backend\Classes\Controller;

class Posts extends Controller
{
    public $implement = [
        \Backend\Behaviors\FormController::class,
        \Backend\Behaviors\ListController::class,
    ];

    public $formConfig = 'config_form.yaml';
    public $listConfig = 'config_list.yaml';

    public $requiredPermissions = ['acme.blog.manage_posts'];
}

The controller's YAML config files and view partials live in a subdirectory matching the controller name (e.g., controllers/posts/). Every aspect of the generated interface can be overridden with PHP hooks or custom view partials when the defaults are not enough.

Creating Custom Widgets

Form Widget

php
<?php namespace Acme\Blog\FormWidgets;

use Backend\Classes\FormWidgetBase;

class MyWidget extends FormWidgetBase
{
    public function render()
    {
        $this->prepareVars();
        return $this->makePartial('mywidget');
    }

    public function prepareVars()
    {
        $this->vars['value'] = $this->getLoadValue();
    }

    public function getSaveValue($value)
    {
        return $value;
    }
}

Register in your plugin:

php
public function registerFormWidgets()
{
    return [
        \Acme\Blog\FormWidgets\MyWidget::class => 'mywidget',
    ];
}

Filter Widget

Extend Backend\Classes\FilterWidgetBase and register via registerFilterWidgets().

Extension Points

Events

EventDescription
backend.menu.extendItemsExtend backend navigation menu
backend.roles.extendPermissionsAdd custom permissions
backend.list.extendQueryBeforeModify list query before execution
backend.list.extendRecordsModify list results
backend.list.refreshAfter list refresh
backend.user.loginAfter successful login
backend.layout.extendHeadAdd markup to backend <head>
backend.layout.extendFooterAdd markup before </body>
backend.beforeRouteBefore backend route resolution
backend.routeCustom backend route handling

Extending Controllers

php
\Acme\Blog\Controllers\Posts::extend(function ($controller) {
    // Add extra behavior, modify config, etc.
});

Extending Models

php
\Backend\Models\User::extend(function ($model) {
    $model->hasMany['posts'] = \Acme\Blog\Models\Post::class;
});

Skinning

The backend supports theming via Backend\Classes\Skin. The active skin is configured with config('backend.skin'). Skins are located in modules/backend/skins/.