CartistoDocs

Sections & blocks

Merchant-composable content around a protected commerce core, with mixed-type blocks and presets.

Sections let a merchant compose the content of a template — add, remove, reorder, and configure them — without touching code. Cartisto’s model is deliberately commerce-safe: merchants compose content around a protected commerce core.

The model

  • Each composable template (product, collection, cart) has one protected commerce core the merchant can’t remove or reorder — the product buy-box, the cart summary, and so on.
  • Around the core are content zones (above / below) where the merchant places content sections — testimonials, FAQ, banners, newsletter, and the like.
  • The invariant is enforced in the render pipeline, not the UI, so no path (customizer, API, or AI tools) can drop or tamper with the core.

The homepage (index) is pure content — it has no core.

Rendering sections

The platform resolves each section instance and hands you its full partial path on section.partialyou never build the path yourself. Render it directly:

{% for section in theme.templateSections.index %}
  {% if section.display %}
    {% render section.partial, component: section, sindex: forloop.index %}
  {% endif %}
{% endfor %}

Section partials live at views/sections/<path>.liquid. Because the platform owns path resolution, that location can change in a future SDK version without editing a single theme — so always render section.partial, never a hardcoded folder.

Product content zones render above and below the core, and the core’s info column is a list of platform blocks you render from block.partial:

{% for section in theme.templateSections.product.above %}
  {% render section.partial, component: section, product: product %}
{% endfor %}

<div class="pdp-info">
  {% for block in theme.templateSections.product.coreBlocks %}
    {% render block.partial, block: block, product: product %}
  {% endfor %}
</div>

{% for section in theme.templateSections.product.below %}
  {% render section.partial, component: section, product: product %}
{% endfor %}

Each section instance carries its resolved settings (and resolved picker data — see Dynamic sources), so one partial styles the merchant’s chosen values.

Authoring a section type

Add the type to sections in theme.json with a path and its settings schema, and ship the partial at views/sections/<path>.liquid. A content section renders identically anywhere, so the same partial works in any zone. The quality gate rejects a theme that declares a section whose partial file is missing.

Blocks: mixed content inside one section

A content section can hold blocks — reorderable child items of different types, each with its own settings. Declare the allowed block types in the section’s catalog entry:

{
  "path": "rich-columns",
  "name": { "en": "Rich columns", "ar": "أعمدة" },
  "settings": [{ "name": "heading", "type": "text" }],
  "blocks": [
    { "type": "text",  "name": { "en": "Text" },  "settings": [{ "name": "body", "type": "textarea" }] },
    { "type": "image", "name": { "en": "Image" }, "settings": [{ "name": "src", "type": "image" }], "limit": 4 }
  ]
}

The merchant places blocks of those types in any order; the platform validates each block’s type and settings on save (limit caps how many of a type are allowed) and resolves each block’s data. Render them from block.partial — one partial per block type at views/blocks/<type>.liquid:

{% for block in component.blocks %}
  {% render block.partial, block: block %}
{% endfor %}

Presets: demo content on add

Give a section a preset so it isn’t empty the moment a merchant drops it in. On a fresh add (no settings of the merchant’s own), the platform seeds the section from its preset:

{
  "path": "rich-columns",
  "preset": {
    "settings": { "heading": "Featured" },
    "blocks": [{ "type": "text", "settings": [{ "name": "body", "value": "Tell your story here." }] }]
  }
}
Note

The core is platform-defined You render the core’s markup (it’s your buy-box), but its presence, position rules, and the block types allowed inside it are platform-owned. Required core blocks (title, price, variant picker, buy buttons) can be reordered but never removed — that’s what keeps “compose your storefront” from ever meaning “remove add-to-cart.”