Basker Docs

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 assigns page.theme.settings to the shorter local variable template_settings.
  • The blocks array 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_settings carries metadata about the theme itself: the human-readable name and the version. It is not a settings group that editors interact with.
  • site is a group: fields nest underneath it and are read as settings.site.name, settings.site.tagline.
  • social is an array: the editor adds as many entries as they like, each with label and href. 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>&copy; {{ '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.

On this page