Theme blocks

Write a block once and use it in any section that accepts it, nested up to four levels.

A theme block is a block in its own file, blocks/<name>.vasc, that any section can accept: a heading, a button, a slide. Merchants add theme blocks to those sections and arrange them like local blocks.

A theme block#

vascula
<a class="button button--{{ settings.style }}" href="{{ settings.url }}">{{ settings.label }}</a>
{% schema %}
{
  "name": "button",
  "kind": "block",
  "icon": "square",
  "settings": [
    { "id": "label", "type": "text", "default": "Shop now",
      "editor": { "label": "Label", "group": "content" } },
    { "id": "url", "type": "url", "default": "/shop",
      "editor": { "label": "Link", "group": "content" } },
    { "id": "style", "type": "select", "default": "solid",
      "options": [ { "value": "solid", "label": "Solid" }, { "value": "outline", "label": "Outline" } ],
      "editor": { "label": "Style", "group": "design" } }
  ]
}
{% endschema %}

The file name and name match. A theme block has its own settings and its own ctx_needs: it does not see the data or settings of the section it sits in. Its name in the editor comes from sectionName.<name> in the theme's editor translations.

Accept theme blocks in a section#

Set accept_theme_blocks and place {% blocks %} where the blocks should render:

vascula
<div class="hero">
  <div class="hero__content">{% blocks %}</div>
</div>
{% schema %}
{
  "name": "hero",
  "blocks": { "accept_theme_blocks": true, "max": 8 }
}
{% endschema %}

{% blocks %} renders the section's theme and app blocks in the merchant's order, skips hidden ones and makes each selectable in the editor. A section can define local block types as well; {% blocks %} renders only the theme and app blocks.

To place blocks one at a time, for example between local blocks, pass one block to the tag:

vascula
{% for b in settings.blocks %}
  {% if b.type == "quote" %}
    {{ b._editor_block_open }}<blockquote>{{ b.settings.text }}</blockquote>{{ b._editor_block_close }}
  {% else %}
    {% blocks b %}
  {% endif %}
{% endfor %}

Set accept_app_blocks to accept blocks from the merchant's installed apps too. Every theme also offers a built-in "Custom code" block, where merchants write their own Vascula.

Theme blocks are stored with the type theme:<name>, and app blocks as app:<app>:<key>, so they never clash with local block types.

Nesting#

A theme block can hold theme blocks of its own: give its schema a blocks slot with accept_theme_blocks and place {% blocks %} in its markup.

vascula
<div class="slide">
  {% if settings.image %}<img src="{{ settings.image | image_url: width: 1080 }}" alt="">{% endif %}
  <div class="slide__content">{% blocks %}</div>
</div>
{% schema %}
{
  "name": "slide",
  "kind": "block",
  "blocks": { "accept_theme_blocks": true, "max": 6 },
  "settings": [
    { "id": "image", "type": "image", "editor": { "label": "Image", "group": "content" } }
  ]
}
{% endschema %}

A block's blocks slot accepts only theme blocks. Blocks nest up to four levels: the blocks in a section are level one.

Rules#

  • A theme block's settings, bound settings included, work exactly as on a section.
  • {% blocks %} needs accept_theme_blocks or accept_app_blocks.
  • A block file has no target and no presets.
  • Style theme blocks with stable class names from the sections that use them.