Build a theme

An Eldorados theme is Liquid, laid out the way a Shopify Online Store 2.0 theme is. If you have written one of those, you already know this.

The directories

A theme is these eight directories and nothing else. Anything beside them — a package.json, a .github/ folder, your tooling — is ignored rather than refused, so a repository can hold a theme and its build setup together.

DirectoryHolds
assets/Images, CSS, JavaScript and fonts, served from the website's own origin.
blocks/Theme blocks: reusable pieces an editor can place inside any section that accepts them.
config/`settings_schema.json` declares the theme's own settings; `settings_data.json` holds their values.
layout/`theme.liquid`, the shell every page renders inside.
locales/Translations. `<code>.default.json` is the source language; `.schema.json` translates the editor's own labels.
sections/Sections, plus `.json` section groups such as `header-group`.
snippets/Partials, rendered with `{% render %}`.
templates/One `.json` per page type, listing the sections it holds and their order.

How a page is assembled

A request resolves to a template — templates/index.json for the home page, templates/page.json for a page. The template lists the sections it holds and their order. Each section renders inside layout/theme.liquid, which also pulls in the header and footer section groups.

layout/theme.liquid
  {% sections 'header-group' %}
  {{ content_for_layout }}   ← the template's sections
  {% sections 'footer-group' %}

Sections and blocks

A section is a piece of a page with its own settings, declared in a {% schema %} at the bottom of the file. A block is a repeatable piece an editor can add inside a section that accepts it. Anything that repeats should be a block rather than a fixed number of settings — that is what lets one section render three tiles or thirty without a redesign.

<div class="grid">{% content_for 'blocks' %}</div>

{% schema %}
{
  "name": "Tiles",
  "blocks": [{ "type": "tile" }],
  "max_blocks": 24,
  "presets": [{ "name": "Tiles" }]
}
{% endschema %}

Settings

Settings are declared in the schema and read as section.settings.<id> or block.settings.<id>. Every available type is in the setting type reference.

To make a field editable by clicking it in the visual editor, mark it with the editable filter:

<h1 {{ 'settings.headline' | editable }}>{{ section.settings.headline }}</h1>

The section wrapper

A schema may set tag and class to control the element a section is wrapped in. Allowed tags: article aside div footer header section .

Where this differs from Shopify

  • {% form %} renders a form built in the admin by handle, rather than being a block you fill with inputs. The field set belongs to the admin, so a form can be changed without touching Liquid.
  • The editable filter is required for in-place editing; Shopify infers it.
  • Assets are served from the website’s own origin, never a shared CDN hostname.
  • There are no commerce objects — no product, no cart. The content objects are pages, posts, menus, forms and metafields.

Validation

A theme is validated before it is stored: path safety, required files, schema parsing, the platform limits, JSON validity, and then Shopify’s Theme Check. Nothing half-valid is ever written, so a stored theme is always a theme that can be published.