Документация

Грабли, на которые наступают

Ошибки, которые не видны на тестовом магазине и всплывают у покупателя: валюта, пустая корзина, кэш и остатки.

На этой странице

Всё перечисленное уже кусало. Особенность большинства этих ошибок в том, что на тестовом магазине их не видно — они всплывают у покупателя.

Деньги

Сумма без валюты печатается долларами. У тега {money} значение по умолчанию — доллар. Забыли currency — в гривневом магазине цена уедет с долларовым знаком. На тестовом магазине с валютой по умолчанию ошибку не видно вовсе.

{money amount=$product.price currency=$storefront.currency}

Своя формула в шаблоне разъезжается с настоящим итогом. В итог входят скидки, промокод, баллы, надбавка за способ оплаты, доставка, доп-услуги и налог. Повторить это в шаблоне не получится: покупатель увидит в корзине одну сумму, при оформлении другую, а в письме третью. Всё нужное уже посчитано.

Заказ не переоценивается. У него своя валюта и свой курс. Суммы заказа выводят с $order.currency, а не с валютой витрины.

Пустые состояния

Пустая корзина отдаёт неполный набор ключей. Когда корзины ещё нет, в $cart нет items_total и catalog_savings. Блок итогов оборачивают в {if $items}, иначе шаблон полезет за несуществующим ключом.

Отзывы могут прийти одним ключом. Владелец выключил отзывы — в $reviews только признак «выключено». Обращаться к $reviews.items без проверки {if $reviews.enabled} нельзя.

Пустой остаток и нулевой остаток — разные вещи. count и sku_count приходят пустыми, когда остаток у товара не считают вовсе — услуги, товары под заказ. Написать «осталось 0 шт.» в этом случае нельзя, а осталось {$product.count} напечатает пустоту вместо числа.

Товар без фотографии — обычное дело. Ветку с заглушкой пишут сразу, иначе сетка разъедется на первом же магазине, где фотографии ещё не загрузили.

Кэш

«Поправил шаблон — на витрине старое». Страницы витрины кэшируются на сутки. Правка файла темы в редакторе кэш не сбрасывает — файл пишется мимо базы.

Приём: правьте тему, оставаясь вошедшим в панель в соседней вкладке. Сотрудник магазина и пишет мимо кэша, и читает мимо него.

«Поправил CSS — браузер держит старый файл». Файлы темы отдаются с длинным кэшем на месяц. Метку версии получают только те, что подключены тегами {asset_css} и {asset_js}.

⚠️ Файл, подключённый вручную, метки не получает вовсе и залипает у покупателя на месяц:

{* нельзя *}  <link rel="stylesheet" href="{$theme.assets}/css/my.css">
{* нужно *}   {asset_css file="css/my.css"}

Корзину нельзя впечатывать в разметку страницы каталога. Страницы каталога лежат в общем кэше: одна и та же уходит всем покупателям, и следующий увидит чужую корзину. Поэтому количество проставляет магазин уже в браузере, а тема только размечает карточку атрибутом data-in-cart.

Если без разметки на сервере не обойтись, есть {$shop->inCart()} — но он выключает кэш для этой страницы.

Разметка и атрибуты

Забытый мета-тег с ключом защиты ломает всё. Без <meta name="csrf-token"> не работает ни добавление в корзину, ни пересчёт оформления, ни отправка отзыва. Ошибка тихая: покупатель нажимает кнопку, и ничего не происходит.

Имена полей оформления менять нельзя. Пересчёт запускается по именам — shipping, payment, coupon, bonus и всё, что начинается с address[. Переименовали coupon в promo — промокод перестал пересчитывать заказ.

data-recalc и data-required магазин не читает — он проставляет их сам в той разметке, которую рисует. Ставить их в шаблоне бессмысленно.

Свой счётчик количества над блоком упаковок дерётся с магазинным. В режиме упаковок счётчик считает пачки, а не метры, и два счётчика начнут спорить.

Не сообщили о своём изменении корзины — счётчик замер. Любой участок, меняющий корзину, обязан отправить событие cartix:cart-updated.

Без JavaScript оформление заказа не работает. И пересчёт, и создание заказа отвечают данными, а не страницей. Заглушки в базовой теме нет.

Шаблоны

nofilter там, где выводится готовая разметка. Экранирование включено всегда. Описание товара, содержимое информационной страницы и карта вариантов без nofilter выведутся текстом с &lt;.

Опечатка в парном теге роняет страницу. Одиночный неизвестный тег безопасен — он выводит пусто, поэтому тег выключенного дополнения не ломает витрину. А неизвестный парный ({foo}…{/foo}) даёт ошибку сборки шаблона.

Незнакомый обработчик значения безопасен, но тих. Значение проходит насквозь, имя уходит в журнал. Перед выкладкой в журнал стоит заглянуть.

Ключи и имена — только латиницей. {$theme.чего_нет} — это ошибка разбора и белый экран, а не пустая строка.

Отсутствующий шаблон — единственная ошибка, из-за которой покупатель видит ошибку вместо страницы. То же при {extends} и {include} на несуществующий файл. После переименования шаблона пройдитесь по витрине глазами.

Пагинатор Laravel в шаблон не отдаётся. Пользуйтесь готовым pagination.

Настройки темы

Настройки, не объявленной в theme.json, не существует. Пока поля нет в схеме, значения у него нет и быть не может — правка шаблона ничего не изменит. Так и с card_variants: у базовой темы её в схеме нет, поэтому базовая тема не показывает варианты покупки на карточках.

Имя настройки не должно совпадать с именем группы. Настройки лежат в $theme и плоско, и по группам: поле colors внутри группы catalog затрёт всю группу colors.

Переключились на другую тему, нажали «Сохранить» — настройки прежней потеряны. Значения лежат одним набором на витрину, а не отдельно на каждую тему, и форма перезаписывает весь набор своими полями.

Из того же следует, что новая тема может показать чужие значения: совпадающие ключи (primary, per_page, container_width) переезжают из темы в тему.

Переименованный между версиями ключ настройки выглядит как сломанное обновление. Владелец получит значение по умолчанию вместо своего.

Языки

Ключ, которого нет ни в теме, ни в магазине, выводится сам. Страница не падает, но в вёрстке висит storefront.cart. Перед выкладкой каждый язык нужно пройти глазами.

Надписи, уезжающие в браузер, передаёт тема. Не передали data-text-* живому поиску или data-l-* оформлению — на месте сообщения будет пустота.

Длина надписи — часть вёрстки. Кнопка фиксированной ширины, собранная на русском тексте, на украинском порвётся.

Склонение проверяют числами, а не на глаз. 21 товар и 22 товара — самая частая ошибка.

Файлы и пакет

Три файла магазин просит на каждой странице: assets/css/theme.css, assets/js/theme.js, assets/vendor/fontawesome/all.min.css. Их нет — три ошибки 404 в консоли.

Нет 404.html — покупатель увидит стандартную страницу без вашей шапки и подвала.

Пустая папка в пакет не попадает — складывается список файлов.

Файлы за пределами assets/ браузеру не отдаются — это защита, а не недоработка.

В базовой теме

Две вещи, о которые спотыкаются, читая её как образец.

Файлы checkout/delivery.html, checkout/payment.html и checkout/confirm.html — мёртвые заготовки. Оформление одностраничное, всё рисует checkout/layout.html, а эти три файла никто не подключает. В своей теме их можно удалить.

README.md базовой темы устарел. Он упоминает тег {getList}, шаблон list.html и точки встраивания header.end, home.after.lists, product.after.buy, checkout.fields — ничего этого не существует. Написанный в шаблоне {getList} молча выведет пустоту. Ориентируйтесь на этот справочник, а не на тот файл.

Обновлено 24 августа 2026