Наследование и замена шаблонов
Темы в Flute CMS поддерживают наследование — можно создать свою тему на базе существующей и переопределить только нужные части.
Как работает наследование
Указав "extends": "standard" в theme.json, ваша тема наследует все файлы от стандартной темы. Переопределяете только то, что хотите изменить.
Порядок поиска файлов
- Ваша тема (
mytheme) - Родительская тема (если указана в
extends) - Стандартная тема (
standard)
Пример
mytheme/views/layouts/header.blade.php ← есть → используется
mytheme/views/layouts/footer.blade.php ← нет → берется из standard
mytheme/views/components/button.blade.php ← есть → используется
mytheme/views/components/card.blade.php ← нет → берется из standardМинимальная дочерняя тема
Достаточно двух файлов:
- 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;
}Всё остальное автоматически берётся из standard.
Цепочка наследования
Можно создавать несколько уровней наследования:
standard (базовая)
└── standard-dark (добавляет темные стили)
└── mytheme (кастомизирует для проекта)// standard-dark/theme.json
{
"name": "Standard Dark",
"extends": "standard"
}
// mytheme/theme.json
{
"name": "My Theme",
"extends": "standard-dark"
}Порядок поиска: mytheme → standard-dark → standard
Замена шаблонов модулей
Модули (Shop, Forum, News и т.д.) имеют свои шаблоны. Их можно заменить на свои.
Прямая замена (replacements)
{
"replacements": {
"shop::pages.catalog": "mytheme::shop.catalog",
"shop::pages.product": "mytheme::shop.product",
"news::components.card": "mytheme::news.card"
}
}Теперь когда система запросит shop::pages.catalog, она получит mytheme::shop.catalog.
Структура файлов:
- catalog.blade.php
- product.blade.php
Массовая замена (wildcard_replacements)
Заменить все шаблоны модуля одной строкой:
{
"wildcard_replacements": {
"shop::pages.*": "mytheme::shop.pages.*",
"shop::components.*": "mytheme::shop.components.*",
"forum::*": "mytheme::forum.*"
}
}shop::pages.catalog→mytheme::shop.pages.catalogshop::pages.product→mytheme::shop.pages.productforum::widgets.online→mytheme::forum.widgets.online
Замена по regex (module_replacements)
Для сложных паттернов:
{
"module_replacements": {
"/^shop::pages\\.(.+)$/": "mytheme::shop.$1",
"/^forum::(widgets|pages)\\.(.+)$/": "mytheme::forum.$1.$2"
}
}Замена ресурсов (SCSS/JS)
asset_replacements
Заменить файлы ассетов:
{
"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
Добавить свои стили поверх стандартных (не заменяя):
{
"asset_scss_append": {
"main": [
"Themes/mytheme/assets/sass/overrides.scss",
"Themes/mytheme/assets/sass/custom.scss"
]
}
}Эти файлы компилируются после основного app.scss, поэтому могут переопределять стили.
Переменные для макетов (layout_arguments)
Передача данных во все шаблоны:
{
"layout_arguments": {
"showSidebar": true,
"sidebarWidth": "280px",
"containerMaxWidth": "1400px",
"headerStyle": "sticky"
}
}Использование в шаблонах:
@if ($showSidebar ?? false)
<aside style="width: {{ $sidebarWidth ?? '250px' }}">
@include('partials.sidebar')
</aside>
@endif
<div class="container" style="max-width: {{ $containerMaxWidth ?? '1200px' }}">
@yield('content')
</div>Настройки темы (settings)
Настройки, которые можно изменять в админке:
{
"settings": {
"primary_color": {
"name": "Основной цвет",
"description": "Выберите основной цвет темы",
"value": "#007aff"
},
"show_footer": {
"name": "Показывать футер",
"description": "Включить/выключить подвал сайта",
"value": true
},
"header_layout": {
"name": "Стиль шапки",
"description": "Выберите вариант оформления",
"value": "default"
}
}
}Кастомные цвета (colors.json)
Цвета для редактора страниц:
{
"light": {
"--background": "#ffffff",
"--secondary": "#f8fafc",
"--accent": "#007aff",
"--text": "#1a1a2e"
},
"dark": {
"--background": "#121212",
"--secondary": "#1e1e1e",
"--accent": "#0a84ff",
"--text": "#e0e0e0"
}
}Переопределение компонентов
Полная замена
Создайте файл с тем же путём:
standard/views/components/button.blade.php ← оригинал
mytheme/views/components/button.blade.php ← ваша версияРасширение компонента
Если хотите добавить функциональность:
{{-- mytheme/views/components/button.blade.php --}}
@props([
'type' => 'primary',
'size' => 'medium',
'disabled' => false,
'icon' => null, {{-- Новый параметр --}}
'iconPosition' => 'left', {{-- Новый параметр --}}
])
@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>Кеширование
Очистка кеша
После изменений в теме:
php flute template:cache:clear
php flute cache:clearАвтоматическая перекомпиляция
В режиме разработки SCSS перекомпилируется автоматически при изменении файлов. В продакшене используется кеш.
Полный пример theme.json
{
"name": "My Corporate Theme",
"version": "2.0.0",
"author": "Company Name",
"description": "Корпоративная тема с кастомным дизайном",
"extends": "standard",
"settings": {
"accent_color": {
"name": "Цвет акцента",
"value": "#0066cc"
},
"show_social_links": {
"name": "Показывать соцсети в футере",
"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"]
}
}