Version 3.6 of October CMS contains some major improvements to the platform. Some of these features were scheduled to be released in v4.0 of October CMS, however, since Laravel 11 includes some compatibility changes, we need to wait for those changes to mature. This means we've included the new features in the v3.6 as a backwards compatible release.
Table of Contents
- How to Upgrade to v3.6
- Relation Controller Support in Tailor
- Design Modes for Form Controller
- Nested Relation Controllers
- Masking Author Name in Admin URLs
- Multisite Improvements
- Shorter Mail Templates
- Phosphor Icon Library
- Notable Minor Changes
How to Upgrade to v3.6
There are two ways to upgrade, by clicking the Check for Updates button in the admin panel, or via console commands. For command line interface, please use the following commands:
composer update
php artisan october:migrate
php artisan october:util set build
Using the october:update
command, you may encounter an error Target class [system.cacher] does not exist.. If this occurs, run the command a second time to fix it.
In the event that you find some incompatibilities with your plugins due to this release, lock your composer file to the previous version (v3.5) by modifying your composer file below and then run composer update
.
"require": {
"october/all": "3.5.*",
"october/rain": "3.5.*",
}
Relation Controller Support in Tailor
The entries
field type in Tailor supports managing records using a more advanced interface, including create, update and delete. When setting the display mode to controller
, the records can be managed using the Relation Controller behavior. For example:
guests:
type: entries
source: Event\Guest
displayMode: controller
The new nesteditems
content field supports the Relation Controller behavior natively. It is used when the related items are exclusive to the parent record, and supports inline form fields, including tabs and secondary tabs.
items:
label: Menu Items
type: nesteditems
form:
fields: [...]
tabs:
fields: [...]
- Read the Nested Items content field documentation to learn more.
Design Modes for Form Controller
The FormController
behavior has been improved to include different design modes. A design
property can be specified inside the form configuration YAML file. For example, the following displays a basic form design with a size of 750 wide.
# ===================================
# Form Behavior Config
# ===================================
# ...
design:
displayMode: basic
size: 750
Now, the form can be rendered in the controller view using the formRenderDesign
method, as a single line of code.
<?= $this->formRenderDesign() ?>
A popup display mode is also available that removes the need to create any form view files (update, create, preview).
design:
displayMode: popup
Now, the following recordOnClick
value can be used in the ListController
list configuration YAML file. This will manage the form records using popups, as a single line of code.
# ===================================
# List Behavior Config
# ===================================
# ...
recordOnClick: popup
When the design
property is omitted, the custom design mode is used with the standard formRender
method. We anticipate there will be several new design modes coming in later releases, in addition to different design modes for the list controller.
- Read the Form Designs documentation to learn more.
Nested Relation Controllers
The Relation Controller has been improved to support nesting relations, in other words, managing relations through relations. A nested relationship uses the standard field nesting syntax. For example, the countries[cities]
relation definition makes the cities
relationship available to manage through the countries
relationship.
countries:
label: Country
form: $/october/test/models/country/fields.yaml
list: $/october/test/models/country/columns.yaml
countries[cities]:
label: City
form: $/october/test/models/city/fields.yaml
list: $/october/test/models/city/columns.yaml
This concept has been taken further with self-registration using the relation
field type. This makes it effortless to manage complex relations. You may now define the controller
property on the form field with the relation controller configuration directly on the field.
For example, a product model can specify a related_products
field that registers itself with the Relation Controller automatically, including nested and recursive structures.
related_products:
label: Related Products
type: relation
controller:
label: Related Product
list: $/october/test/models/product/columns.yaml
form: $/october/test/models/product/fields.yaml
view:
toolbarButtons: add|remove
Masking Author Name in Admin URLs
It is now possible to customize the admin panel URLs introduced by plugins. By default, the URL of an admin page is made up of the author name, plugin name, controller name and action name.
admin/[author name]/[plugin name]/[controller name]/[action name]
To use a custom URL segment, specify the hint property in the pluginDetails
method when registering the plugin. The hint should be a unique code that does not conflict with other plugins.
public function pluginDetails()
{
return [
// ...
'hint' => 'user'
];
}
A shorter URL structure becomes available, which is useful for masking the author name in URLs.
admin/[hint name]/[controller name]/[action name]
More Multisite Improvements
Synchronization for multisite has been improved to allow sync between all
sites, sites within the same group
(default) or within the same locale
. These values are available within Tailor Blueprints to control this behavior.
multisite: sync | all | locale | group
Deleted records are also propagated across multisite-enabled models, so when a record is deleted, any linked records will also be deleted. This is the new default, however, it can be disabled using the array format for configuration, and setting the delete
property to false
.
multisite:
sync: group
delete: false
- For PHP implementations, read the updated documentation for more details.
Shorter Mail Templates
It is now possible to register shorter mail template codes, instead of using the fully qualified view path. This feature is optional but may cause some misconfigured plugins to throw an error. Check the registerMailTemplates
method of your plugins. Some older plugins were using this format:
// Invalid syntax from v3.6
[
'vendor.plugin::mail.view-one' => 'vendor.plugin::lang.string_one',
'vendor.plugin::mail.view-two' => 'vendor.plugin::lang.string_two',
// ...
]
The language string (array value) was never used for anything or documented anywhere, however, we noticed some plugins were using this format, including official ones, and it may have replicated from these examples. If you find the mail templates page throws an exception, update the plugin to remove the language strings and return a list array of view paths instead. See the example below:
// Valid syntax (backward compatible)
[
'vendor.plugin::mail.view-one',
'vendor.plugin::mail.view-two',
// ...
]
- See the linked Pull Request for a patch example.
Or, if you wish to use the newer v3.6 syntax, with shorter mail codes:
// Newer syntax
[
'plugin:message-one' => 'vendor.plugin::mail.view-one',
'plugin:message-two' => 'vendor.plugin::mail.view-two',
// ...
]
Phosphor Icon Library
The admin panel now includes Phosphor icons -- a flexible icon family containing 7,488 icons that are now available for use in plugins.
A phosphorIcons
preset is available to use in your form fields:
icon:
label: Icon
type: dropdown
optionsPreset: phosphorIcons
The preset can also be used in list columns with the selectable
type.
icon:
label: Icon
type: selectable
optionsPreset: phosphorIcons
A new documentation page has been created to list all the available icons.
- Read the Available Icons documentation to learn more.
Notable Minor Changes
Flash Progress Messages
The AJAX framework now supports a message
option that contains text to display while the request loads, which is displayed using a flash message. It can be implemented using the data attributes API or the JavaScript interface.
<button
data-request="onSave"
data-request-message="Please wait while we process your request...">
Save
</button>
Partial Types Now Support The Model Directory
The partial
type for form fields and list columns will now check the model directory in addition to the controller directory. This makes it easier to couple your view files with the YAML definition that implements it.
For example, if a model fields.yaml
file defines a partial field called foobar with a generic path
called field_foobar. The partial will be loaded from models/mymodel/_field_foobar.php
first, and then controllers/mycontroller/_field_foobar.php
as a fallback.
Default Path of Partial Types Changed
The partial
type for form fields and list columns previously used a default path
value set as the field name. This created a naming collision between list columns and form fields using the same name. When the path
is omitted, the default value is now prefixed with field_ and column_ respectively.
For backward compatibility, plugin developers should check that YAML definitions containing type: partial
also have a path
specified as the field name.
myfield:
type: partial
path: myfield # ← Add this line
Module Load Order Changed
The load order of service providers (modules, plugins, app) has been changed in this version. This has a low likelihood of impact, however, plugin developers should be aware of this difference.
-
In v3.5 and earlier, the load order was: (1) System module, (2) All plugins, (3) All other modules, (4) App provider
-
In v3.6 and later, the load order is: (1) All modules, (2) All plugins, (3) App provider
Disable Backend Password Resets
By default, administrators can reset their own password using the password reset feature found administrator area. In some cases you may wish to restrict this ability. A new backend.password_policy.allow_reset configuration item is included to allow disabling the reset password feature via self service. When disabled, administrators will need to request a password reset from another administrator or via the october:passwd
artisan command.
'password_policy' => [
'allow_reset' => false,
],
Deferred Binding Support for Sortable Relations
The October\Rain\Database\Traits\SortableRelation
trait now supports deferred binding. The sort order is stored in the deferred bindings table until it is committed and applied to the pivot table. When deferred models are co-mingled with existing models, the results are sorted by a unified sort order column to produce a seamless result.
This implementation has improved the withDeferred
method so pivot and binding data is now available as part of the query. Previously, pivot data was not available since whereExists
sub-queries were used internally, and special consideration had to be given since the pivot data was not always available. Now, the new internals use a leftJoin
query so the pivot columns are always available, although they appear empty for deferred records, they can now be queried normally without any special workarounds.
This is the end of the document, you may read the announcement blog post or visit the changelog for more information.