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

Помічник $shop: списки магазину

Категорії, сторінки, добірки товарів, бренди, мітки, відгуки та кошик — просто з шаблону, без підготовки даних.

На цій сторінці

$shop — помічник, який є в кожному шаблоні. Через нього тема бере те, що їй потрібно, не чекаючи, поки дані передадуть: категорії для меню, добірки товарів на головну, бренди, мітки, відгуки, стан кошика.

Помічник живе один на запит і запам'ятовує результати — повторний виклик з тими самими параметрами до бази не звертається. Кликати {$shop->categories()} у шапці, у меню каталогу і в плитках на головній не накладно.

Зведення

Метод Що віддає
contacts() контакти магазину
locales() мови вітрини з посиланнями на поточну сторінку
categories($parentId, $depth, $media) дерево категорій
pages($parentId) меню сторінок, створених власником
products($code, $preset, $limit, $sort) картки товарів добірки
tags($limit) мітки каталогу
brands($limit) бренди з логотипами
reviews($limit) останні схвалені відгуки
accessories($productId) групи аксесуарів товару
cartCount() число позицій у кошику
cartTotal() сума кошика
cartPath() куди веде значок кошика
isOnepageCheckout() чи увімкнено оформлення в один крок
favoritesCount() число товарів в обраному
compareCount() число товарів у порівнянні
inCart() що вже лежить у кошику
cartItem($productId, $skuId) позиція кошика з цим товаром
inCartQty($productId, $skuId) скільки цього товару в кошику
cardVariantsEnabled() чи показує тема варіанти купівлі на картках

Категорії

{$shop->categories()}                    верхній рівень
{$shop->categories(null, 2)}             два рівні
{$shop->categories(null, 2, true)}       два рівні, з картинками
{$shop->categories($category.id, 1)}     підкатегорії поточної
Параметр За замовчуванням Що задає
parentId порожньо корінь піддерева; порожньо — верхній рівень
depth 1 на скільки рівнів углиб
media ні чи додавати картинки

Поля вузла: id, name, initial (перша літера — для плитки без картинки), slug, url, children. З media додаються logo, icon, cover — або адреса файлу, або порожньо.

{foreach $shop->categories(null, 2, true) as $cat}
    <a href="{$cat.url}">
        {if $cat.icon}<img src="{$cat.icon}" alt="">{/if}
        {$cat.name}
    </a>
    {foreach $cat.children as $sub}
        <a href="{$sub.url}">{$sub.name}</a>
    {/foreach}
{/foreach}

Вимкнені категорії не приходять.

Інформаційні сторінки

{foreach $shop->pages() as $page}
    <a href="{$page.url}">{$page.title}</a>
{/foreach}

Поля: id, slug, title, url. Вимкнені не приходять, порядок — як задано в панелі. Сторінок немає — порожній список.

Добірки товарів

Два способи отримати список товарів на головну.

За кодом добірки, заведеної власником:

{$shop->products('new-arrivals', null, 12)}

Код задається в панелі, у розділі добірок. Добірки з таким кодом немає або вона вимкнена — порожній список. Це основний спосіб: власник сам вирішує, що показувати, не чіпаючи шаблон.

За готовим набором правил:

{$shop->products(null, 'discount', 8)}
Набір Що відбирає
new додані за останні 30 днів
discount лише зі знижкою
low_stock залишок від 1 до 5
random випадкові
bestsellers за продажами
popular за переглядами
top_rated за оцінками

Невідома назва мовчки перетворюється на new.

⚠️ Чесно про три останні: bestsellers, popular і top_rated зараз сортують за новизною. Товари прийдуть правильні, порядок — як у новинок. Сортування за продажами, переглядами і оцінками оголошено, але поки що не зроблено.

Повертаються повні картки товару — той самий набір полів, що й у товарів категорії. Він описаний на сторінці Дані товару.

Мітки і бренди

{foreach $shop->tags(20) as $tag}<a href="{$tag.url}">{$tag.name}</a>{/foreach}

{foreach $shop->brands(30) as $brand}
    <a href="{$brand.url}">
        {if $brand.logo}<img src="{$brand.logo}" alt="{$brand.name}">{else}{$brand.name}{/if}
    </a>
{/foreach}

Мітки: id, slug, name, url, за абеткою. Бренди: те саме плюс logo. Логотип береться зменшеним, за відсутності зменшеної копії — оригінал. За замовчуванням — 50 штук.

Відгуки

{foreach $shop->reviews(6) as $r}
    <blockquote>
        <p>{$r.text}</p>
        <cite>{$r.name}, <a href="{$r.product_url}">{$r.product}</a>, {$r.date}</cite>
    </blockquote>
{/foreach}

Останні схвалені відгуки про товари — для блока на головній. Поля: name, initial, product, product_url (веде на #, якщо товар видалено), rating, text, date у форматі дд.мм.

Аксесуари

{foreach $shop->accessories($product.id) as $group}
    <h3>{$group.title}</h3>
    {foreach $group.items as $item}
        <label>
            <input type="checkbox" value="{$item.sku_id}">
            <img src="{$item.image}" alt="">
            {$item.name}
            {money amount=$item.final_price currency=$storefront.currency}
        </label>
    {/foreach}
{/foreach}

Група: id, title, multiple (можна вибрати кілька), items. Аксесуар: product_id, sku_id, name, url, image, in_stock, is_available, discount (відсоток групи), price, final_price (зі знижкою групи), compare_price, default_quantity, unit, qty_step, qty_min, is_default.

Аксесуари вимкнені в налаштуваннях — порожній список. Група, у якій не залишилося жодного доступного товару, не приходить зовсім.

На сторінці товару те саме вже лежить у $product.accessories — окремо кликати не потрібно. І пам'ятайте: живий перерахунок комплекту робить сам магазин, тема тільки розмічає блок — див. Атрибути data-*.

Мови

{foreach $shop->locales() as $l}
    <a href="{$l.url}"{if $l.active} class="is-active"{/if}>{$l.short}</a>
{/foreach}

Поля: code (ru), prefix (uk або ua — задається в довіднику мов), name (назва рідною мовою), short (префікс великими літерами), active, url.

urlшлях поточної сторінки цією мовою, а не повна адреса: перемикач зобов'язаний залишитися на тому домені, за яким покупець зайшов.

Кошик

<a href="{$shop->cartPath()}">
    Кошик
    <span data-badge="cart">{$shop->cartCount()}</span>
    <span data-cart-total-header>{money amount=$shop->cartTotal() currency=$storefront.currency precision=0}</span>
</a>

cartPath() віддає /checkout, якщо у вітрини увімкнено оформлення в один крок, інакше /cart — значок кошика має вести туди, куди власник налаштував.

cartTotal() бере готовий підсумок кошика, а не складає позиції: своя формула в шапці розійдеться зі сторінкою кошика і з оформленням. Кошика ще немає — нуль.

favoritesCount() і compareCount() — те саме для обраного і порівняння.

Усі чотири дешеві, кличте звідки завгодно.

Що вже в кошику

inCart(), cartItem(), inCartQty() відповідають, чи лежить товар у кошику. Позиція: item_id, product_id, sku_id, qty, qty_text, unit, packs, lines. Товар лежить кількома варіантами — кількості складаються, а item_id, sku_id і packs приходять порожніми: позиція вже не одна.

⚠️ Звичайний шлях інший. Ці методи позначають сторінку як особисту і вимикають для неї загальний кеш вітрини: сторінка перестає віддаватися з кешу і збирається заново кожному покупцеві.

Штатний спосіб показати «вже в кошику» — атрибут на картці:

<article class="card" data-in-cart="{$product.id}">
    …
    <span class="card__in-cart">
        У кошику <b data-in-cart-qty></b> <span data-in-cart-unit></span>
    </span>
</article>

Кількість проставить магазин уже в браузері, і сторінка залишиться кешованою. Подробиці — на сторінці Атрибути data-*.

Варіанти купівлі на картках

cardVariantsEnabled() читає налаштування теми card_variants — чи показувати вибір кольору і розміру просто в списку товарів.

⚠️ Налаштування зобов'язане бути оголошене в theme.json. У базової теми його немає, тому базова тема варіанти на картках не показує. Поки поля немає в схемі, магазин не витрачає запити на підготовку варіантів — і правка шаблону нічого не змінить. Як оголосити поле, написано на сторінці Файл theme.json.

Чого у $shop немає

Помічник віддає списки і стан, а не все підряд. Замовлень покупця, довільної вибірки товарів за своїми умовами, чужих сутностей магазину в ньому немає — і обійти це, звернувшись із шаблону до бази, не можна: шаблон працює в пісочниці.

Якщо темі потрібні дані, яких у $shop немає, — це завдання доповнення. Воно рахує своє і виводить через точку вбудовування або власний тег.

Оновлено 19 серпня 2026