Skip to content

Authoring blocks ​

A block type is a YAML file (the content contract) plus a default partial (the presentation).

Block YAML anatomy ​

yaml
# teaser.yaml
handle: teaser               # required; a plain slug (a vendor:name handle never renders)
name: Teaser                 # text or lang key; defaults to the handle
icon: icon-star
group: components            # inserter group
partial: teaser              # partial file name; defaults to the handle
container: false             # true = holds child blocks (section, grid)
allowChildren: null          # containers: handle whitelist for children (null = any)
childOnly: false             # true = only insertable inside a container
fullBleed: false             # true = spans the viewport; a host's rootWidth never boxes it in
defaultChildren: null        # containers: starter children, e.g. [{ type: heading, data: { text: Hi } }]
defaultSettings:             # generic settings preset on insert (scalars)
    spacing_top: lg
fields:                      # content fields, October form field syntax
    image:
        label: Image
        type: mediafinder
        mode: image
    title:
        label: Title
        type: text
    link:
        label: Link
        type: pagefinder
        translatable: false  # opt out of AI translation

fields may not contain a nested contenteditor. allowChildren is enforced in the editor and on save, childOnly in the editor. AI Translate sends every non-empty string of a text, textarea, richeditor, richtext or markdown field, repeater items included; a field without type counts as text. Set translatable: false on a text field that holds no copy, such as a CSS class, a form field name, coordinates or a price. Other field types (dropdowns, switches, colors, icons, media, page links, numbers) are never translated, and neither is a text field named url, href, link, src, id, anchor, class, css, icon, color, email, phone, lat, lng, slug, embed or ending in one of them after an underscore (button_url). Blocks without a definition fall back to the field names text, html, caption, alt, title, author and label.

The default partial ​

Every block ships <sourcePath>/<partial>.htm. A definition whose partial is missing or whose YAML fails to parse is skipped with a logged warning. The partial renders in a standalone Twig environment with:

NameContents
datathe block's content fields
settingsthe block's generic settings
childrenpre-rendered child HTML; containers output {{ children|raw }}
attributesready-made class="…" id="…" string built from the settings
blockIdstable document id ('' in legacy documents), for deterministic element ids
previewtrue in the editor preview
localelocale code of the render site
media filtermedia path → URL
rc_resize(w, h, options) filterresized image URL; the plain media URL without a resizer
rc_embed filterYouTube/Vimeo URL → privacy embed URL, '' if unrecognised
rc_url filterpasses http, https, mailto, tel and relative links; resolves october:// to the active site's URL
rc_css_url filterescapes a URL for CSS url()
rc_icon(name, size, class)inline Lucide SVG, empty for unknown names
rc_t(key, replace, locale)a renick.content::lang string
rc_image_size(path)[width, height] of a media image, or null
rc_filesize(path)readable media file size
rc_map_csv(path)marker rows from a media CSV
rc_entries(section, options)published Tailor entries; options limit (1–24, default 6), order, direction, with
rc_page_url(page, params)CMS page URL
rc_tailor_submission_form(data)form model of the Submission form block
twig
{# teaser.htm #}
<a {{ attributes|raw }} href="{{ data.link|rc_url }}">
    <img src="{{ data.image|rc_resize(600, 400) }}" alt="">
    <h3>{{ data.title }}</h3>
</a>

Registration sources ​

On a handle collision the plugin wins, then the theme, then the first event listener. Themes restyle blocks with partial overrides, not by redefining them.

  • Plugin: plugins/renick/content/blocks/<handle>/<handle>.yaml + .htm.
  • Theme: themes/<theme>/content-blocks/<handle>/<handle>.yaml + .htm. A child theme inherits its parent's blocks and partial overrides, nearest theme first, so a Marketplace <theme>-child keeps them.
  • Event: other plugins return configs with a sourcePath (the partial's directory). A config without it is skipped with a warning.
php
Event::listen('renick.content.registerBlocks', fn () => [[
    'handle' => 'pricing-table',
    'name' => 'Pricing table',
    'group' => 'components',
    'fields' => ['plans' => ['label' => 'Plans', 'type' => 'textarea']],
    'sourcePath' => plugins_path('acme/shop/blocks/pricing-table'),
]]);

Field types ​

Values are stored as strings, except repeater and tailorfields (row arrays) and checkbox and switch (booleans). A field's default is written into data on insert. row: <name> on consecutive fields shows them side by side. A field's trigger (October's action: show|hide, field, condition: value[a][b]|checked|unchecked) shows or hides it in the Inspector depending on a sibling field. Blocks of an unregistered type keep their data and render a placeholder.

TypeNotes
textsingle line; also used for unknown types
textarea, richeditormulti-line text
numbermin, max, step
dropdownoptions
checkbox, switchboolean
colorpickerhex color, clearable
mediafindermedia library path
pagefinderoctober:// reference or a typed URL; singleMode, allowCustomUrl (default true), allowedTypes, excludedTypes. Render with rc_url
iconpickerLucide icon name for rc_icon()
taglisttags, stored as one string
repeatersortable rows of sub-fields
tailorcolumna column of the Tailor blueprint picked in the dependsOn field; kind: sortable (default), image, text
tailorfieldsfields of the submission blueprint picked in dependsOn, stored as name/label rows

Localizing labels ​

name and each field's label, comment, commentAbove, emptyOption and option labels (repeater sub-fields included) may be lang keys. They resolve server-side to the backend locale: a :: key through trans(), a dotted key without spaces through the theme's JSON translations when it exists. Other strings pass through. :: keys also work in defaultChildren data.