Файл theme.json и настройки темы
Как описать настройки, которые владелец магазина увидит в панели, и как прочитать их значения в шаблоне.
На этой странице
theme.json — единственный обязательный файл темы. Он говорит магазину, как
тема называется, какой версии магазина требует и какие настройки владелец
увидит в панели.
Минимальный файл
{
"id": "my-theme",
"name": "Моя тема",
"version": "1.0.0",
"requires": { "core": "2.0.0" }
}
| Поле | Обязательно | Что означает |
|---|---|---|
id |
да | идентификатор темы; обязан совпадать с именем папки |
name |
да | название, которое видит владелец магазина |
version |
да | версия темы |
requires.core |
нет, но нужно | с какой версии магазина тема работает |
settings |
нет | настройки темы: панель строит форму по этому описанию |
Поля author, preview и locales записать можно, но магазин их сейчас нигде
не показывает — на работу темы они не влияют.
Если theme.json испорчен и не читается как JSON, магазин всё равно считает
папку темой, но без имени и версии: в списке она называется по имени папки.
Витрина при этом работает. А вот без самого файла папка темой не считается, и
витрина, назначенная на неё, падает.
Совместимость с версией магазина
"requires": { "core": "2.0.0" } эта версия и новее
"requires": { "core": ">=2.0.0" } то же, со знаком
"requires": { "core": { "min": "2.0.0", "max": "3.0" } } с верхней границей
Обычный случай — только нижняя граница. Верхняя нужна, когда вы точно знаете, что следующая большая версия магазина ломает вашу тему.
Ставьте ту версию, возможностями которой тема действительно пользуется, и убедитесь, что эта версия магазина уже вышла. Тема, рассчитанная на магазин новее установленного, обратится к тому, чего ещё нет, и покупатель встретит ошибку вместо страницы.
Проверка идёт до подмены папки, поэтому отказ безопасен: прежняя тема остаётся на месте, магазин продолжает работать. Владелец увидит понятное сообщение: «Это дополнение рассчитано на CartiX 3.1.0 и новее, а у вас установлена версия 2.5.0. Сначала обновите магазин».
Что тема ведёт сама
Поведение витрины — корзину, выбор варианта, отбор в разделе, окно аксессуаров — магазин подключает сам, и тема получает всё это рабочим. Если вы написали свою замену какой-то части, объявите её в манифесте, и магазин свой код подключать не станет:
"runtime": {
"sku": "theme",
"catalog": "theme",
"accessories_popup": "theme"
}
| Ключ | Что перестанет подключать магазин |
|---|---|
sku |
выбор варианта товара на карточке |
catalog |
отбор товаров в разделе (галочки, цена, «показать ещё») |
accessories_popup |
окно «возьмите к этому» после покупки из каталога |
Объявляйте только то, что действительно заменили: две копии поведения ответят на
одно нажатие дважды, а без замены покупатель останется без возможности вовсе.
Заявленное приходит скриптам в window.CartiX.runtime — по нему ваш код узнаёт,
что работает он.
Настройки темы
Настройки описываются схемой: вы перечисляете группы и поля, а панель строит форму сама. Ни верстать её, ни писать код для сохранения не нужно.
"settings": {
"groups": [
{
"id": "colors",
"name": "Цвета",
"fields": [
{ "key": "primary", "type": "color", "label": "Основной", "default": "#4f46e5" },
{ "key": "accent", "type": "color", "label": "Акцент",
"hint": "Цвет звёзд рейтинга и кнопки предзаказа.", "default": "#f59e0b" }
]
},
{
"id": "catalog",
"name": "Каталог",
"fields": [
{ "key": "per_page", "type": "number", "label": "Товаров на странице", "default": 24 },
{ "key": "products_per_row", "type": "select", "label": "Товаров в ряд",
"options": [2, 3, 4, 5], "default": 4 },
{ "key": "show_sku_on_card", "type": "boolean",
"label": "Показывать артикул на карточке", "default": true }
]
}
]
}
Поля группы
| Ключ | Что задаёт |
|---|---|
id |
идентификатор группы; по нему настройка доступна как {$theme.colors.primary} |
name |
заголовок группы в форме |
fields |
список полей |
Поля настройки
| Ключ | Что задаёт |
|---|---|
key |
имя настройки; по нему значение доступно как {$theme.primary} |
type |
вид поля |
label |
подпись поля |
default |
значение по умолчанию |
hint |
пояснение под полем |
placeholder |
подсказка внутри пустого поля |
options |
список вариантов — только для select |
Виды полей
type |
Что рисует панель |
|---|---|
text |
однострочное поле |
textarea |
многострочное поле |
number |
число |
boolean |
переключатель |
color |
выбор цвета |
select |
выбор из списка options |
font |
выбор шрифта из готового списка |
image |
ссылка на файл картинки |
image пока рисуется обычным текстовым полем: владелец вставляет туда адрес
файла, выбора картинки из галереи нет.
Как прочитать настройку в шаблоне
Два способа, оба работают всегда:
{$theme.primary} плоско, по имени настройки
{$theme.colors.primary} через группу
Плюс два набора есть в теме всегда, даже если вы их не объявляли:
{$theme.assets} /theme-assets/имя-темы — адрес папки статики
{$theme.colors.primary} {$theme.colors.accent} {$theme.colors.bg} {$theme.colors.text}
Все поля схемы присутствуют в $theme, даже незаполненные — они приходят
пустыми. Шаблон на них не падает, проверка вида {if $theme.logo} безопасна.
⚠️ Настройки, не объявленной в theme.json, для магазина не существует.
Написать {$theme.my_setting} и ждать значения бессмысленно: пока поля нет в
схеме, значения у него нет и быть не может. Схема — источник правды.
Тот же подвох с другой стороны: настройку card_variants, которая включает
показ вариантов покупки прямо на карточках товаров в списке, читает сам магазин.
У базовой темы её в схеме нет — поэтому базовая тема варианты на карточках не
показывает, сколько ни правь шаблон. Нужны варианты — объявите поле:
{ "key": "card_variants", "type": "boolean", "label": "Варианты покупки на карточке", "default": true }
⚠️ Имя настройки не должно совпадать с именем группы. Настройки лежат в
$theme и плоско, и по группам, в одном наборе: поле colors внутри группы
catalog затрёт всю группу colors.
Где хранятся значения
Значения настроек лежат у витрины, а не у темы. Отсюда три следствия, о которых нужно знать.
Настройки переживают обновление темы. Файлы заменяются целиком, значения остаются в базе — по совпадающим ключам новая версия увидит всё, что владелец настроил.
Отсюда правило автора темы: не переименовывайте ключи между версиями.
Переименовали primary_color в primary — владелец получит цвет по умолчанию
вместо своего и решит, что обновление сломало магазин. Нужно новое поведение —
заводите новый ключ, а старый оставляйте работать.
Набор значений один на витрину, а не отдельный на каждую тему. Совпадающие
ключи (primary, per_page, container_width) переезжают из темы в тему, а
ключи, которых у новой темы нет, просто лежат дальше. Но сохранение настроек
новой темы перезаписывает весь набор своими полями — то есть переключились на
другую тему, нажали «Сохранить» — значения прежней темы потеряны. Владельцу,
который собирается вернуться, стоит сначала выписать их или скачать архив темы.
При нескольких витринах каждая настраивается отдельно: одна и та же тема может быть синей на одной витрине и зелёной на другой.
Настройка обязана что-то делать
Поле, которое сохраняется и ни на что не влияет, — обман владельца магазина.
Объявили в схеме container_width — читайте его в разметке:
<style>:root { --container: {$theme.container_width}px; }</style>
Хорошая привычка: писать hint там, где название поля не объясняет последствие,
и placeholder в каждом поле ввода.