October CMS 2.2 - Feature Release

Release Note 29

Version 2.2 of October CMS contains several features that we just couldn't wait to share with you.

Table of Contents

Tailor Coming in v3.0

Tailor was planned to be released in this version, however, during the development we have made enough internal improvements that it can justify its own release. There are countless improvements and bug fixes, in the release note we will cover some of the major changes to the software that benefit all developers and their plugins.

Tailor is still on track for its beta release early this year. We are making good progress each cycle and are excited to release Tailor in the next feature version (v3.0). We hope Tailor takes your development process to the next level. Thanks for your support and patience.

Demo Theme Upgraded

The demonstration theme that ships with new installations of October CMS has received some technology upgrades. It now uses the following:

Twig Strictness

You can now improve your theme development process by enabling the cms.strict_variables setting. When a variable cannot be accessed an exception is thrown so you can fix any syntaxical errors in your templates.

Missing CMS components used on a page will no longer throw an exception. Use the cms.strict_components setting to re-enable this functionality.

/*
|--------------------------------------------------------------------------
| Template Strictness
|--------------------------------------------------------------------------
|
| When enabled, an error is thrown when a component, variable, or attribute
| used does not exist. When disabled, a null value is returned instead.
|
*/

'strict_variables' => env('CMS_STRICT_VARIABLES', false),

'strict_components' => env('CMS_STRICT_COMPONENTS', false),

New Safe Mode Policy Coming in v3

An improved Twig security policy will be introduced in the next major version that offers greater performance and security when using the safe mode feature (cms.safe_mode) for the CMS. When safe mode is enabled, or when using the system Twig engine, objects should specify which methods can be called in Twig using these interfaces.

  • October\Contracts\Twig\CallsMethods
  • October\Contracts\Twig\CallsAnyMethod

The new policy will take effect in v3.0 and you can prepare your theme by testing it. It can be enabled by adding the environment variable CMS_SECURITY_POLICY_V2=true to your configuration.

Improved Controls

The repeater control has been refactored to include several improvements. It now supports Has-Many relationships in addition to jsonable properties. A new displayMode is available to show as a builder or accordion. The UI has been improved so items can be checked, reordered and duplicated.

blocks:
    label: Blocks
    type: repeater
    displayMode: builder
    groups: []

The mediafinder control has been improved so that multiple items can be selected and a maximum number of items can be specified with maxItems property.

gallery:
    label: Gallery
    type: mediafinder
    mode: image
    maxItems: 3

The relation widget can be used to interact with the RelationController to check for definitions and render them, this is preferred instead of using a partial. This can be enabled with the useController property and will be the default for v3.0.

country:
    label: Country
    type: relation
    useController: true

See the forms documentation to learn more.

Sortable Relation Support Added

Structured List support has been added to the RelationController behavior. Practically this feature will only work with Has-Many and Belongs-To-Many relationship types. When using Belongs-To-Many, the sort column will exist in the pivot table and a special trait is used to enable the functionality.

roles:
    #...
    structure:
        showReorder: true
        showTree: false

See the Sorting Records documentation for more details.

New implementClassWith method

When two or more plugins extends a controller with a behavior, it often creates a conflict because an error will be thrown when attempting to extend the same object twice using extendClassWith and manipulating the $implement property can be complicated.

A new implementClassWith method has been introduced to safely extend objects using an idempotent approach. The following code will implement the class with the behavior and can be called multiple times without throwing an error.

\RainLab\User\Controllers\Users::extend(function ($controller) {
    $controller->implementClassWith(\Backend\Behaviors\FormController::class);
});

Note: The implementClassWith method should only be used in conjunction with the ::extend constructor method. For extending an object after it has been constructed, continue to use extendClassWith.

New Backend Password Policy

In previous versions it was not possible for plugins to completely enforce a password policy. This has been fixed and also a simple policy definition has been introduced natively. Add the new config section to your config/backend.php to define one:

/*
|--------------------------------------------------------------------------
| Password Policy
|--------------------------------------------------------------------------
|
| Specify the password policy for backend administrators.
|
| min_length        - Password minimum length between 4 - 128 chars
| require_uppercase - Require at least one uppercase letter (A–Z)
| require_lowercase - Require at least one lowercase letter (a–z)
| require_number    - Require at least one number
| require_nonalpha  - Require at least one non-alphanumeric character
|
*/

'password_policy' => [
    'min_length' => 4,
    'require_uppercase' => false,
    'require_lowercase' => false,
    'require_number' => false,
    'require_nonalpha' => false,
],

A new local event has been added to the Backend\Models\User model that allows plugins to define their own policy.

$model->bindEvent('user.validatePasswordPolicy', function ($password) {
    throw new ValidationException(['password' => 'Prevent anything from validating ever!']);
});

Handling Not Found Exceptions

A new NotFoundException exception has been created to instruct the application that the requested resource was not found. When this exception is encountered, October CMS will respond with a 404 (not found) status code and display the 404 page where applicable.

The following classes are handled as not found exceptions:

  • October\Rain\Exception\NotFoundException
  • Illuminate\Database\Eloquent\ModelNotFoundException
  • Symfony\Component\HttpKernel\Exception\NotFoundHttpException

Throwing a Not Found exception is possible via twig using {% do abort(404) %}.

{% if not record %}
    {% do abort(404) %}
{% endif %}

See Markup > Abort Function docs for more info.

Relation Definition Improvements

The scope parameter in relations can now refer to a static method.

public $belongsToMany = [
    'categories' => [
        \Acme\Blog\Models\Category::class,
        'scope' => [self::class, 'myFilterMethod']
    ]
];

The relationClass parameter can now specify a custom relationship object.

public $belongsToMany = [
    'users' => [
        \Backend\Models\User::class,
        'relationClass' => \Backend\Classes\MyBelongsToMany::class
    ]
];

See the Relationships article for more details.

Nested Fields in Theme Data

In previous versions when working with fields using array syntax (contact[name], contact[email] etc.) you would need to add the top level to the ThemeData model's jsonable array using the following.

\Cms\Models\ThemeData::extend(function ($model) {
    $model->addJsonable('contact');
});

This is no longer required and nested fields are automatically made jsonable based on the form field definitions.

Template Properties Support Variables

CMS Templates have been improved so you can use variables from the page lifecycle inside page or layout properties.

url = "/blog/post"
title = "{{ blog.title }} - Blog"

The put and placeholder nodes have been improved to support complex use cases:

{% put pageTitle = searchTerm ~ ' - Search Results' %}

An example of supporting both approaches in your layout.

<title>October CMS - {{ placeholder('pageTitle') ?: this.page.title }}</title>

See the Placeholder Tag documentation for more details.

Thank you

We hope you enjoy this release. Thanks for your support in helping October CMS reach its full potential.

comments powered by Disqus