Skip to content

Create a Theme

This tutorial walks you through creating a basic Basker theme from scratch. By the end, you’ll have a working theme with a layout, page template, content block, and theme settings.

  • Create a theme file structure
  • Build a base layout with required Liquid objects
  • Create a page template
  • Add a reusable content block
  • Configure global theme settings
  • Package and deploy your theme
  • Basic knowledge of HTML and CSS
  • Familiarity with templating concepts
  • Access to a Basker CMS instance

A minimal Basker theme requires these directories and files:

  • Directorytheme/
    • Directorylayouts/
      • default.liquid (required)
    • Directorytemplates/
      • page.liquid
    • Directoryblocks/
      • content.liquid
    • settings_schema.json

The layout is the foundation of your theme. Create layouts/default.liquid with the required Liquid objects:

layouts/default.liquid
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page.title | default: 'My Site' }}</title>
{{ content_for_header }}
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
<main>
{{ content_for_layout }}
</main>
<footer>
<p>&copy; {{ 'now' | date: '%Y' }} My Site</p>
</footer>
</body>
</html>

Templates render specific content types. Create templates/page.liquid to render pages:

templates/page.liquid
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<article class="page">
<header class="page-header">
<h1>{{ page.title }}</h1>
{% if page.description %}
<p class="lead">{{ page.description }}</p>
{% endif %}
</header>
<div class="page-content">
{% stageblocks page %}
</div>
</article>
{% endcapture %}
{% schema %}
{
"name": "page",
"settings": [],
"blocks": ["content"]
}
{% endschema %}

Key elements:

  • {% layout %} specifies which layout to use
  • {% capture content_for_layout %} wraps the template content
  • {{ page.title }} accesses page properties
  • {% stageblocks page %} renders content blocks
  • {% schema %} defines template settings and allowed blocks

Blocks are reusable components editors can add to pages. Create blocks/content.liquid:

blocks/content.liquid
<section id="{{ block.id }}" class="content-block">
{% if block.title %}
<h2>{{ block.title }}</h2>
{% endif %}
{% if block.content %}
<div class="prose">
{{ block.content_html }}
</div>
{% endif %}
</section>
{% schema %}
{
"name": "content",
"singular": "Content",
"plural": "Content Blocks",
"label": "Content Block",
"settings": [
{
"type": "text",
"name": "title",
"label": "Title"
},
{
"type": "richtext",
"name": "content",
"label": "Content"
}
]
}
{% endschema %}

Key elements:

  • {{ block.id }} provides a unique identifier for the block instance
  • {{ block.title }} accesses the text field value
  • {{ block.content_html }} renders richtext as HTML (note the _html suffix)
  • The schema defines the block name and its configurable fields

Global settings let administrators customize the theme. Create settings_schema.json:

settings_schema.json
[
{
"name": "colors",
"label": "Colors",
"settings": [
{
"type": "color",
"name": "primary",
"label": "Primary Color",
"default": "#0066cc"
},
{
"type": "color",
"name": "background",
"label": "Background Color",
"default": "#ffffff"
}
]
},
{
"name": "typography",
"label": "Typography",
"settings": [
{
"type": "select",
"name": "font_family",
"label": "Font Family",
"options": [
{ "label": "System", "value": "system-ui" },
{ "label": "Serif", "value": "Georgia, serif" },
{ "label": "Sans-serif", "value": "Arial, sans-serif" }
],
"default": "system-ui"
}
]
}
]

Access these settings in your layout:

layouts/default.liquid
<style>
:root {
--color-primary: {{ settings.colors.primary }};
--color-background: {{ settings.colors.background }};
--font-family: {{ settings.typography.font_family }};
}
</style>

To deploy your theme:

  1. Create a ZIP file containing your theme directory structure:

    theme.zip
    └── theme/
    ├── layouts/
    ├── templates/
    ├── blocks/
    └── settings_schema.json
  2. Upload the ZIP file through the Basker admin panel under Themes

  3. Activate your theme to make it live

Here’s the final file structure with all files:

  • Directorytheme/
    • Directorylayouts/
      • default.liquid
    • Directorytemplates/
      • page.liquid
    • Directoryblocks/
      • content.liquid
    • settings_schema.json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page.title | default: 'My Site' }}</title>
{{ content_for_header }}
<style>
:root {
--color-primary: {{ settings.colors.primary }};
--color-background: {{ settings.colors.background }};
--font-family: {{ settings.typography.font_family }};
}
body {
font-family: var(--font-family);
background-color: var(--color-background);
margin: 0;
padding: 0;
}
header, footer {
padding: 1rem 2rem;
background: #f5f5f5;
}
main {
padding: 2rem;
max-width: 800px;
margin: 0 auto;
}
.prose { line-height: 1.6; }
</style>
</head>
<body>
<header>
<nav><a href="/">Home</a></nav>
</header>
<main>
{{ content_for_layout }}
</main>
<footer>
<p>&copy; {{ 'now' | date: '%Y' }} My Site</p>
</footer>
</body>
</html>

Now that you have a basic theme, explore the architecture documentation to learn more:

  • Layouts - Learn about layout structure and parameters
  • Templates - Discover all available templates and their objects
  • Blocks - Create more complex content blocks
  • Input Settings - Explore all available field types
  • Liquid Reference - Master the Liquid templating language