community.dhcf.eu Sign in

AI briefing - layouts and themes

Guide for AI assistants helping users author or modify a lazysite layout or theme.

Who this is for

This briefs an AI assistant working on the visual layer of a lazysite site - the layout template (layout.tt) and its themes. For content, see AI briefing - authoring. For configuration, see AI briefing - configuration.

Terminology (D013)

Layout: the Template Toolkit file (layout.tt) that wraps every page. Provides <head>, header, navigation, footer. Installed at lazysite/layouts/NAME/layout.tt with optional lazysite/layouts/NAME/layout.json metadata.

Theme: colours, fonts, spacing, and assets that sit on top of one or more layouts. Installed nested at lazysite/layouts/LAYOUT/themes/THEME/. Declares compatibility in theme.json's layouts[] array.

Manager UI: has its own internal template at lazysite/manager/layout.tt. Outside the layout+theme system. Do not modify unless explicitly asked.

On-disk example:

lazysite/
  layouts/
    default/
      layout.tt
      layout.json
      themes/
        odcc/
          theme.json
          main.css
          assets/
  manager/
    layout.tt
    assets/manager.css
lazysite-assets/
  default/
    odcc/
      main.css
      assets/

TT variables in layout.tt

Always available:

D013 additions:

Auth variables:

theme.json schema (D013)

Required fields:

Optional:

Example:

{
  "name": "odcc",
  "version": "1.0.0",
  "description": "OpenDigitalCC brand theme",
  "author": "OpenDigitalCC",
  "layouts": ["default"],
  "config": {
    "colours": {
      "primary": "#332b82",
      "text": "#2a2a2a"
    },
    "fonts": {
      "body": "Open Sans"
    }
  },
  "files": ["theme.json", "main.css"]
}

Auto-generated CSS variables

The processor walks theme.config and emits a <style> block with CSS custom properties at :root, exposed as [% theme_css %]:

<style>
:root {
  --theme-colours-primary: #332b82;
  --theme-colours-text: #2a2a2a;
  --theme-fonts-body: Open Sans;
}
</style>

Naming: --theme-GROUP-KEY.

Use in the theme's CSS:

body {
  color: var(--theme-colours-text);
  font-family: var(--theme-fonts-body);
}

This is the recommended pattern: layout.tt emits theme_css; the theme's own main.css references the variables. A theme fork that only tweaks colours edits theme.json and doesn't need to duplicate CSS structure.

Minimum layout.tt

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>[% page_title %][% IF site_name %] - [% site_name %][% END %]</title>
  [% theme_css %]
  [% IF theme_assets %]
  <link rel="stylesheet" href="[% theme_assets %]/main.css">
  [% END %]
</head>
<body>
  [% IF nav.size %]
  <nav>
    [% FOREACH item IN nav %]
    <a href="[% item.url %]">[% item.label %]</a>
    [% END %]
  </nav>
  [% END %]
  <main>
    <h1>[% page_title %]</h1>
    [% IF page_subtitle %]<p>[% page_subtitle %]</p>[% END %]
    [% content %]
  </main>
</body>
</html>

Activating layout + theme

In lazysite.conf:

layout: default
theme: odcc

Both values are sanitised to [A-Za-z0-9_-] at resolve time.

Theme incompatibility

If theme.json.layouts does NOT contain the active layout:

What NOT to do