The Cold War

Adding and Managing Themes

Rezilienz CMS features a headless theme engine that allows you to swap the entire look and feel of your site without touching the core logic. Themes are self-contained directories that define templates, partials, and assets.

1. Quick Start: Scaffolding a New Theme

Instead of manually copying folders, use the built-in scaffolding tool to create a clean, standardized theme structure:

php apps/blog/cli-tools/theme-scaffold.php my-custom-theme

This creates a new folder in apps/blog/themes/my-custom-theme/ with all mandatory files and a baseline manifest.

2. Directory Structure

A Rezilienz theme must follow this exact structure. If a mandatory file is missing, the engine will throw a RuntimeException naming the exact file required.

apps/blog/themes/my-custom-theme/
├── theme.json           # Theme manifest (metadata & variables)
├── assets/              # Web-accessible assets
│   ├── css/
│   ├── js/
│   ├── fonts/
│   └── images/          # Images that ship WITH the theme
├── partials/            # Reusable PHP components
│   ├── _header.php      # <head> and opening <body>
│   ├── _footer.php      # Closing </body> and scripts
│   └── _navbar.php      # Navigation layout
└── templates/           # Main page layouts
    ├── base.php         # Used for individual articles/dossiers
    └── index.php        # Used for the archive/home page

3. The Theme Manifest (theme.json)

The manifest defines theme metadata and the variables the engine must provide.

{
  "name": "My Custom Theme",
  "version": "1.0.0",
  "author": "Your Name",
  "license": "MIT",
  "supports": {
    "toc": true,
    "hero_image": true
  },
  "variables": {
    "hero_title": { "type": "string", "required": true },
    "articles":   { "type": "array",  "required": false },
    "hero_image": { "type": "string", "required": false },
    "page_title": { "type": "string", "required": false }
  }
}

4. Theme Engine Helpers

Use the $theme object within your .php files to resolve paths. This ensures your theme works in both dynamic (live) and static (SSG) modes.

Helper Use for
$theme->asset('css/style.css') Assets that ship with the theme (CSS, JS, theme icons)
$theme->contentAsset($hero_image) Assets that come from article content (uploaded by authors)
$theme->partial('navbar') Including a file from the partials/ directory
$theme->inlineCss('css/critical.css') CSS that needs path-rewriting and must be inlined in <head>

5. Validation

Before deploying or running a full static build, validate your theme's integrity:

php apps/blog/cli-tools/theme-validate.php my-custom-theme

This checks for mandatory files, JSON syntax errors, and required manifest fields.

6. Switching Themes

To activate your theme:

  1. Open config.ini in the project root.
  2. Update the [theme] section:
[theme]
active = my-custom-theme
directory = apps/blog/themes

IMPORTANT - Loud Failures: If a required template or partial is missing, the engine will throw an error naming the exact missing file. This prevents silent failures or broken layouts in production.