Variants and theme settings
Give the homepage a distinctive layout with a variant template, and expose site-wide options through theme settings
So far every page renders with the same template. Two missing pieces:
- Variants. An editor working on a hero-led landing page and an editor maintaining a standard "About" page want different layouts. Variants let one content type (
page) have multiple template options. The editor picks which one applies to each record. - Theme settings. Things that stay the same across the whole site (site name, social links, footer copyright) do not belong on individual page records. They belong in theme settings instead. The editor configures theme settings once, and every template can read them.
You will add both.
Step 1: Create a homepage variant
Variants are template files named <content-type>.<variant-name>.liquid. A variant called homepage for the page content type lives at templates/page.homepage.liquid.
Create it:
{% assign template_settings = page.theme.settings %}
{% if template_settings.heroTitle or template_settings.heroImage %}
<section class="hero">
{% if template_settings.heroImage %}
<img class="hero__image" src="{{ template_settings.heroImage.url }}" alt="">
{% endif %}
{% if template_settings.heroTitle %}
<h1 class="hero__title">{{ template_settings.heroTitle }}</h1>
{% endif %}
</section>
{% endif %}
<article class="page-content">
{% if page.richDescription_html %}
<div class="page-content__body s-prose">
{{ page.richDescription_html }}
</div>
{% endif %}
{% stageblocks page %}
</article>
{% schema %}
{
"settings": [
{
"type": "text",
"name": "heroTitle",
"label": "Hero title"
},
{
"type": "upload",
"name": "heroImage",
"label": "Hero image",
"relationTo": "media"
}
],
"blocks": ["text-section", "image-feature", "feature-grid"]
}
{% endschema %}A few new ideas:
- The
{% schema %}here declares two template-level settings. These appear as fields on records that use this variant, and the editor enters values there. The first line assignspage.theme.settingsto the shorter local variabletemplate_settings. - The
blocksarray repeats from the default template. The variant supports the same three blocks as the default page template.
Step 2: Pick the variant in the admin
Open a page record in your Basker admin. Look for the template option in the sidebar. The dropdown lists every variant available for the page content type, including your new homepage one. Choose it and save.
The hero title and hero image fields appear on the record once you select homepage. Enter values for both fields. Save the record again. Switch to your dev-server browser. The page now renders the hero block above the body.
You can use this variant for your homepage or for any landing page that needs a hero. It is a regular template, not tied to the site's root URL.
Step 3: Add theme-wide settings
You declare theme settings in config/settings_schema.json. The file is a JSON array of setting groups. Each group has a name and a list of fields. The editor configures values once in the admin's theme settings panel, and you read them in Liquid as settings.<group>.<field>.
Create config/settings_schema.json:
[
{
"name": "theme_settings",
"theme_name": "Remarkable Theatre",
"theme_version": "1.0.0"
},
{
"name": "site",
"label": "Site",
"type": "group",
"fields": [
{
"type": "text",
"name": "name",
"label": "Site name",
"default": "Remarkable Theatre"
},
{
"type": "text",
"name": "tagline",
"label": "Tagline"
}
]
},
{
"name": "social",
"label": "Social links",
"type": "array",
"fields": [
{
"type": "text",
"name": "label",
"label": "Label"
},
{
"type": "text",
"name": "href",
"label": "URL"
}
]
}
]Three things to note:
- The first entry is special. A group named
theme_settingscarries metadata about the theme itself: the human-readable name and the version. It is not a settings group that editors interact with. siteis agroup: fields nest underneath it and are read assettings.site.name,settings.site.tagline.socialis anarray: the editor adds as many entries as they like, each withlabelandhref. You iterate it with{% for link in settings.social %}.
Step 4: Use the settings in your components
Update components/global-header.liquid to read the site name from settings:
<header class="site-header">
<a href="/" class="site-header__logo">{{ settings.site.name }}</a>
<nav class="site-header__nav">
<a href="/about">About</a>
<a href="/events">What's on</a>
<a href="/contact">Contact</a>
</nav>
</header>Update components/global-footer.liquid to render the social links:
<footer class="site-footer">
<p>© {{ 'now' | date: '%Y' }} {{ settings.site.name }}</p>
{% if settings.social.size > 0 %}
<ul class="site-footer__social">
{% for link in settings.social %}
<li>
<a href="{{ link.href }}">{{ link.label }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</footer>Step 5: Configure the values
Before the editor can enter values, you must upload the theme. Until then, local development reads settings from a fallback. You do the upload on the Validate and upload page. After you upload the theme, the theme settings panel in the admin shows the fields you defined here.
A default value in the schema pre-fills the field the first time the editor opens the theme settings panel. The dev server does not read the default value. Until the theme is uploaded and its settings are saved, settings.* renders empty locally. Guard with {% if settings.site.name %} or a | default: filter, or hard-code placeholder values in the component while you develop.
What's next
Pull live event data: connect a calendar block to the FrontStage API.
Going deeper
- Settings: full schema reference for theme and template settings.
- Field types: every field type available in any settings array.
- Templates overview: variant naming rules per content type.