Sections
A section is a file containing a Twig template, a schema which defines the required data for the section, and an Editor Config which defines configurable options for the section as well as the section name.
Sections are useful for contained feature reuse and are usable in global containers and section containers. Upcoming functionality will allow sellers to add sections to the containers via the design editor.
Section Tags
Schema
The schema for a section defines what data the section/page requires in order to be rendered. Schemas are JSON enclosed between {% schema %}
and {% endschema %}
tags. An example schema for a Featured Product section would look like this:
{% schema %}
{
"title": {
"type": "string"
},
"product": {
"type": "item",
"optional": true
}
}
{% endschema %}
Editor config
The Editor config for a section defines how section editing will show up in the Design Editor. The config isn’t used directly when rendering buyer-facing pages, but is only displayed for sellers to manipulate page and section properties.
Within the config we can define a name
and controls
for a Section. Here’s an example that gives it a clear seller-facing name and adds two controls to manipulate the title
and the product
. For more information about controls see the how to guide.
{% editor %}
{
"name": "Featured Product Section",
"controls": [
{
"control": "input",
"value": {
"$ref": "#/schema/title"
}
},
{
"control": "item-chooser",
"value": {
"$ref": "#/schema/product"
}
}
]
}
{% endeditor %}
Section Templates
Section templates are self contained Twig templates that accept a section
resource, a section
can define a schema
that the caller must satisfy before the section can render.
components/sections/featured-products.html.twig
<div>
<h1>{{ title }}</h1>
<p>Item Name: {{ item.name }}</p>
</div>
{% schema %}
{
"title": {
"type": "string"
},
"item": {
"type": "item"
}
}
{% endschema %}
Using Sections in a Template
Sections can be rendered in a page template by using the section
function and passing in two parameters: the name of the section file and a section
resource that satisfies the section’s schema
.
Let’s look at an example page template which renders a section:
site/pages/home.json
{
"props": {
"featuredProduct": {
"props": {
"title": "My featured product",
"item": {
"filters": {
"id": "WUH4RMB3WUDBQJQAOMYN56WD"
}
}
}
}
},
"template": "templates/pages/home",
"route": "/"
}
templates/pages/home.html.twig
{{ section('featured-product', featuredProduct) }}
{% schema %}
{
"featuredProduct": {
"type": "section"
}
}
{% endschema %}
{% editor %}
{
"name": "Test Page",
"controls": [
{
"control": "section",
"value": {
"$ref": "#/schema/featuredProduct"
}
}
]
}
{% endeditor %}
In this example the page schema
requires a section
resource with the name featuredProduct
, the values of this resource must match what featured-product.twig.html
has defined in it’s own schema
or the render will fail.
It also includes an editor
tag to expose the section’s controls to the design editor on the page. This allows the sellers to manipulate the home
properties with the Editor controls.
If all the schema
requirements are satisfied, the page will render with the section.
section merge function
The merge
function allows you to merge additional properties into a section’s existing properties. This can be useful for dynamically adding context-specific data to a section, ensuring flexibility and reusability.
merge(additionalProps)
theme/components/sections/textSection.html.twig
<div class="text-section">
<span>{{ initialProp }}</span>
<span>{{ additionalProp }}</span>
</div>
{% schema %}
{
"initialProp": {
"type": "string"
},
"additionalProp": {
"type": "string"
}
}
{% endschema %}
site/pages/page1.json
{
"props": {
"textSection": {
"props": {
"initialProp": "initialValue"
}
}
}
}
theme/templates/pages/page1.html.twig
{{ section('textSection', textSection.merge({'additionalProp': 'mergedValue'})) }}
The merge
function supports complex property structures, such as arrays and nested objects.
Example with Array Properties
theme/components/sections/arraySection.html.twig
<div class="array-section">
<span>{{ initialProp }}</span>
<span>{{ arrayProp.key1 }}</span>
<span>{{ arrayProp.key2 }}</span>
</div>
{% schema %}
{
"initialProp": {
"type": "string"
},
"arrayProp": {
"key1": {
"type": "string"
},
"key2": {
"type": "string"
}
}
}
{% endschema %}
site/pages/page1.json
{
"props": {
"arraySection": {
"props": {
"initialProp": "initialValue"
}
}
}
}
theme/templates/pages/page1.html.twig
{{ section('arraySection', arraySection.merge({'arrayProp': {'key1': 'value1', 'key2': 'value2'}})) }}
Example with Nested Array Properties
theme/components/sections/nestedArraySection.html.twig
<div class="nested-array-section">
<span>{{ initialProp }}</span>
<span>{{ nestedArrayProp.innerKey.key1 }}</span>
<span>{{ nestedArrayProp.innerKey.key2 }}</span>
</div>
{% schema %}
{
"initialProp": {
"type": "string"
},
"nestedArrayProp": {
"innerKey": {
"key1": {
"type": "string"
},
"key2": {
"type": "string"
}
}
}
}
{% endschema %}
site/pages/page1.json
{
"props": {
"nestedArraySection": {
"props": {
"initialProp": "initialValue"
}
}
}
}
theme/templates/pages/page1.html.twig
{{ section('nestedArraySection', nestedArraySection.merge({'nestedArrayProp': {'innerKey': {'key1': 'mergedValue1', 'key2': 'mergedValue2'}}})) }}
When merging properties, the additional properties will take precedence over the existing properties if there are conflicts. For example, if the section already has a property initialProp with a value of initialValue, and the additionalProps contains initialProp with a value of overriddenValue, the final value of initialProp will be overriddenValue.
Injected wrapper
Please note that all section templates will be rendered with a <div>
wrapper around the content. For example the final output of the featured-products.html.twig
section may look like this:
<div data-so-data="..." data-so-template="..." style="display: contents;">
<div>
<h1>My featured product</h1>
<p>Item name: My product</p>
</div>
</div>
Please do not rely on any of the <div>
attributes to exist aside from style="display: contents"
. This wrapper is required by the platform and utilizes display: contents
to be as unobtrusive as possible with your layout. Please account for this in your DOM structure if you are doing any DOM manipulation.
The data attributes will differ from in editor preview versus published sites.
Inline names
A section template can specify the name
of the template within it’s Editor Config, but in cases where you are using multiple instances of the section you can use the optional last parameter to override the name of the section making it easier for sellers to distinguish between them within the Design Editor:
{{ section('featured-product', headerProducts, 'Featured Header Products') }}
...
{{ section('featured-product', footerProducts, 'Featured Footer Products') }}
Inline names can also be used for section_container
, global_section
, and global_section_container
as the second optional argument.
{{ section_container(list, 'My section container') }}
...
{{ global_section('global_section', 'My global section') }}
...
{{ global_section_container('global_section_container', 'My global section container') }}
Custom section icons
Each section in the editor allows for a custom icon to be used. For a full list of icons, see the editor control icons.
Section and global section icons
Sections and global sections can define an icon three different ways, through section
and global_section
as the fourth optional argument for section
and third optional argument for global_section
, through section and global section properties JSON, or through the editor config for the section.
Passing the icon through section
and global_section
:
{{ section('example_section', exampleSection, 'Example Section', 'star') }}
...
{{ global_section('example_global_section', 'Example Global Section', 'star') }}
Defining the icon in section and global section properties JSON:
Example Section:
{
"props": {
"exampleSection": {
"props": {
"title": "Example Section"
},
"icon": "star"
}
},
"template": "templates/pages/home",
"route": "/"
}
Example Global Section:
{
"props": {
"title": "Example Global Section"
},
"icon": "mirror-up"
}
Defining the icon in section and global section editor configs:
{% editor %}
{
"name": "Example controls",
"icon": "star",
"controls": [
{
"control": "input",
"value": {
"$ref": "#/schema/title"
}
}
]
}
{% endeditor %}
Section container and global section container icons
Inline icons can be used for section_container
, and global_section_container
as the third optional argument.
{{ section_container(list, 'My section container', 'folder') }}
...
{{ global_section_container('global_section_container', 'My global section container', 'folder') }}