Skip to Content
TemplatesTheme Inheritance

Theme Inheritance and Template Replacement

Themes in Flute CMS support inheritance — you can create your own theme based on an existing one and override only the necessary parts.

How Inheritance Works

By specifying "extends": "standard" in theme.json, your theme inherits all files from the standard theme. You override only what you want to change.

File Search Order

  1. Your Theme (mytheme)
  2. Parent Theme (if specified in extends)
  3. Standard Theme (standard)

Example

mytheme/views/layouts/header.blade.php ← exists → used mytheme/views/layouts/footer.blade.php ← missing → taken from standard mytheme/views/components/button.blade.php ← exists → used mytheme/views/components/card.blade.php ← missing → taken from standard

Minimal Child Theme

Two files are sufficient:

    • theme.json
          • _variables.scss

theme.json:

{ "name": "My Theme", "version": "1.0.0", "author": "Your Name", "extends": "standard" }

_variables.scss:

:root[data-theme=light] { --accent: #6366f1; } :root[data-theme=dark] { --accent: #818cf8; }

Everything else is automatically taken from standard.


Inheritance Chain

You can create multiple levels of inheritance:

standard (base) └── standard-dark (adds dark styles) └── mytheme (customizes for project)
// standard-dark/theme.json { "name": "Standard Dark", "extends": "standard" } // mytheme/theme.json { "name": "My Theme", "extends": "standard-dark" }

Search order: mythemestandard-darkstandard


Module Template Replacement

Modules (Shop, Forum, News, etc.) have their own templates. You can replace them with your own.

Direct Replacement (replacements)

{ "replacements": { "shop::pages.catalog": "mytheme::shop.catalog", "shop::pages.product": "mytheme::shop.product", "news::components.card": "mytheme::news.card" } }

Now when the system requests shop::pages.catalog, it will receive mytheme::shop.catalog.

File Structure:

      • catalog.blade.php
      • product.blade.php

Mass Replacement (wildcard_replacements)

Replace all module templates with one line:

{ "wildcard_replacements": { "shop::pages.*": "mytheme::shop.pages.*", "shop::components.*": "mytheme::shop.components.*", "forum::*": "mytheme::forum.*" } }
  • shop::pages.catalogmytheme::shop.pages.catalog
  • shop::pages.productmytheme::shop.pages.product
  • forum::widgets.onlinemytheme::forum.widgets.online

Regex Replacement (module_replacements)

For complex patterns:

{ "module_replacements": { "/^shop::pages\\.(.+)$/": "mytheme::shop.$1", "/^forum::(widgets|pages)\\.(.+)$/": "mytheme::forum.$1.$2" } }

Resource Replacement (SCSS/JS)

asset_replacements

Replace asset files:

{ "asset_replacements": { "Themes/standard/assets/sass/app.scss": "Themes/mytheme/assets/sass/app.scss", "Themes/standard/assets/scripts/app.js": "Themes/mytheme/assets/scripts/app.js" } }

asset_scss_append

Add your styles on top of standard ones (without replacing):

{ "asset_scss_append": { "main": [ "Themes/mytheme/assets/sass/overrides.scss", "Themes/mytheme/assets/sass/custom.scss" ] } }

These files are compiled after the main app.scss, so they can override styles.


Variables for Layouts (layout_arguments)

Passing data to all templates:

{ "layout_arguments": { "showSidebar": true, "sidebarWidth": "280px", "containerMaxWidth": "1400px", "headerStyle": "sticky" } }

Usage in templates:

@if ($showSidebar ?? false) <aside style="width: {{ $sidebarWidth ?? '250px' }}"> @include('partials.sidebar') </aside> @endif <div class="container" style="max-width: {{ $containerMaxWidth ?? '1200px' }}"> @yield('content') </div>

Theme Settings (settings)

Settings that can be changed in the admin panel:

{ "settings": { "primary_color": { "name": "Primary Color", "description": "Choose the main theme color", "value": "#007aff" }, "show_footer": { "name": "Show Footer", "description": "Enable/disable site footer", "value": true }, "header_layout": { "name": "Header Style", "description": "Choose layout style", "value": "default" } } }

Custom Colors (colors.json)

Colors for the page editor:

{ "light": { "--background": "#ffffff", "--secondary": "#f8fafc", "--accent": "#007aff", "--text": "#1a1a2e" }, "dark": { "--background": "#121212", "--secondary": "#1e1e1e", "--accent": "#0a84ff", "--text": "#e0e0e0" } }

Overriding Components

Full Replacement

Create a file with the same path:

standard/views/components/button.blade.php ← original mytheme/views/components/button.blade.php ← your version

Extending a Component

If you want to add functionality:

{{-- mytheme/views/components/button.blade.php --}} @props([ 'type' => 'primary', 'size' => 'medium', 'disabled' => false, 'icon' => null, {{-- New parameter --}} 'iconPosition' => 'left', {{-- New parameter --}} ]) @php $classes = "btn btn-{$type} btn-{$size}"; if ($icon) { $classes .= " btn-with-icon btn-icon-{$iconPosition}"; } @endphp <button {{ $attributes->merge(['class' => $classes]) }} @disabled($disabled)> @if ($icon && $iconPosition === 'left') <x-icon :path="$icon" /> @endif {{ $slot }} @if ($icon && $iconPosition === 'right') <x-icon :path="$icon" /> @endif </button>

Caching

Clearing Cache

After changes in the theme:

php flute template:cache:clear php flute cache:clear

Automatic Recompilation

In development mode, SCSS is recompiled automatically when files change. In production, cache is used.


Full Example of theme.json

{ "name": "My Corporate Theme", "version": "2.0.0", "author": "Company Name", "description": "Corporate theme with custom design", "extends": "standard", "settings": { "accent_color": { "name": "Accent Color", "value": "#0066cc" }, "show_social_links": { "name": "Show Social Links in Footer", "value": true } }, "layout_arguments": { "maxWidth": "1400px", "showBreadcrumbs": true }, "replacements": { "flute::pages.home": "mytheme::pages.home" }, "wildcard_replacements": { "shop::pages.*": "mytheme::shop.*" }, "asset_scss_append": { "main": ["Themes/mytheme/assets/sass/corporate.scss"] } }