Developers
Custom blocks
Custom blocks are created from the back-office, without writing a plugin: a form, optional data sources and a Twig template. They are reserved for superusers.
Why superusers only
The template of a custom block is compiled by the CMS Twig engine. It therefore runs on the server.
- Without October's safe mode (
cms.safe_mode), a template can run commands on the server and read its secrets. Managing custom blocks is then equivalent to being able to run code, like editing CMS templates. - Even with safe mode, the Twig sandbox blocks a list of dangerous methods but does not fully isolate the template. Template authors must be trusted.
This is why:
- the
lucaspalomba.pagetree.manage_custom_blockspermission is not offered to any role: only superusers have access; - the editor and the controller reject anyone else;
- the form shows the "Safe mode is disabled" warning when
cms.safe_modeis disabled.
Editors who only have Manage block pages use custom blocks in their pages, but cannot edit them.
To enable the Twig sandbox, set CMS_SAFE_MODE=true in your site configuration. First check that your themes and plugins remain compatible with this mode.
Create a custom block
- Open Block Pages. In the navigator, in the Custom blocks section, click Create, then New custom block.
- In the header, type the Name (shown in the library). A Code is suggested from the name.
- Build the form in the Fields tab.
- Add data sources in the Data tab if needed.
- Write the HTML in the Template tab.
- Fill in the Settings tab, then save.
The block appears in the library, in its category ("Custom blocks" by default).
The block list of a page is loaded when its tab opens. After creating or editing a custom block, close and reopen the pages that are already open to see the change.
The block code
The code is the block identifier: lowercase letters, digits and dashes, starting with a letter. The type stored in pages is custom.<code>.
- The name can change at any time.
- The code can no longer change once the block is used by a page: the field is disabled and lists the pages concerned.
The Fields tab
The form builder is modeled on the RainLab.Builder one (without depending on it):
- each field list ends with Add control, which opens a palette grouped into Standard, Widgets and UI;
- click a field to edit its properties in the inspector, on the right;
- drag a field onto another one to place it before it;
- the cross of a field deletes it, after confirmation.
The type of a field cannot be changed: delete it and add another one.
Field types
| Type | Value in the template |
|---|---|
| Text, Multiline text, Number, Dropdown, Color | String |
| Rich text | HTML, to output with |raw |
| Checkbox, Switch | Boolean |
| Media | Media library path, to output with |media |
| Link | Link reference, to output with pagetreeLink(data.name) |
| Repeater | List of objects with the subfields |
| Section title | None (heading in the form) |
A repeater cannot contain another repeater. The field names isActive, id, type, children and cells are reserved. Form tabs are not offered.
The Displayed? checkbox is added automatically, as for every block.
The Data tab
A data source lists records in the template: the latest blog posts, the members of a team, and so on. Each source becomes a Twig variable.
| Field | Purpose |
|---|---|
| Variable name | Name used in the template, for example posts. |
| Source | A Tailor section of the active theme or a model of an installed plugin. |
| Number of records | From 1 to 100. |
| Number set by the field | Optional: a number or dropdown field of the block whose value replaces the number. |
| Sort by and Direction | A column of the source, in ascending or descending order. |
| Model scope | Models only: a scope without arguments, for example published. |
The tab shows a usage example and the attributes available for each source.
Allowed sources
- Tailor sections of type entry, stream, structure or single. Submission sections are excluded: they contain data sent by visitors. Only the entries visible on the website are listed (enabled, published, not expired, current site).
- Plugin models of enabled plugins, located in their
models/folder. October core models and settings models are excluded.
A model has no publication rule known to PageTree: everything the source lists is displayed. Use a scope to list only public records, and do not output private attributes.
An unreadable source (deleted source, invalid column, database error) gives an empty list and a line in the log: the page never breaks.
The Template tab
The template is written in Twig in a code editor. Available variables:
data: the field values (data.title,data.items…);id: the block identifier in the page;- one variable per data source;
- the PageTree functions
pagetreeLink(),pagetreeIsBackend(),pagetreeBlockAssets()and the October filters (|media,|page,|trans,|raw…).
{% set items = data.items is iterable ? data.items : [] %}
<section class="team team--{{ data.style ?: 'light' }}">
{% if data.title %}<h2>{{ data.title }}</h2>{% endif %}
{% for item in items %}
<figure>
{% if item.image is defined and item.image %}
<img src="{{ item.image|media }}" alt="">
{% endif %}
<figcaption>{{ item.text ?? '' }}</figcaption>
</figure>
{% endfor %}
</section>
With a posts data source:
{% for post in posts %}
<a href="{{ 'blog/post'|page({ slug: post.slug, id: post.id }) }}">{{ post.title }}</a>
{% else %}
<p>No posts yet.</p>
{% endfor %}
- Twig escapes values by default. Rich text fields must be output with
|raw, deliberately. - The
pagetreeEditablefilter makes a field editable in place, in the preview and on the website:{{ data.title|pagetreeEditable('title') }}. See Editing on the website. - PHP code is not executed:
<?phpin a template is displayed as text. - On save, the syntax is checked: an error is reported with its line number.
- A runtime error does not prevent the page from rendering: the block renders nothing on the website, a short message appears in the preview and the error is logged.
The Settings tab
| Field | Purpose |
|---|---|
| Code | Block identifier, editable as long as no page uses the block (see The block code). |
| Description | Short help shown in the library. |
| Icon | CSS classes of a Phosphor icon, for example ph ph-cube. |
| Category | Group of the block in the library. Defaults to "Custom blocks". |
| Active | An inactive block can no longer be added to a page. Blocks already placed are still displayed. |
Delete or deactivate a block
- Deletion is refused as long as a page uses the block, including inside a section, a grid cell or a translation. The message lists the pages concerned.
- To retire a block without touching the pages, deactivate it (Active unchecked). It is then marked as inactive in the navigator.
Multisite and translations
- The definition of a block is shared by all sites.
- Labels are plain text. A translation key (
author.plugin::lang.key) also works. - The block content is translated with the page, when RainLab.Translate is installed.