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

Форми вітрини

Захист форми, перевірка «я не робот», виведення помилок поруч із полем та адреси всіх дій покупця.

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

На вітрині два види форм. Одні надсилаються звичайним POST і повертають сторінку — вхід, реєстрація, профіль. Інші надсилаються з браузера і отримують дані — кошик, оформлення, відгуки. Правила в них різні.

Захист форми

Будь-яка форма зобов'язана нести ключ захисту, інакше магазин її не прийме.

<form method="post" action="/account/login">
    {csrf_field}
    …
</form>

Для запитів із браузера ключ приходить у налаштуваннях вітрини — CartiX.csrf:

headers: { 'X-CSRF-TOKEN': CartiX.csrf }

Ставити його в розмітку не потрібно: мета-тег csrf-token магазин друкує сам.

Перевірка «я не робот»

{captcha form="reviews"}

Тег сам запитує, чи ввімкнена перевірка для цієї форми, і малює потрібний віджет. Перевірка вимкнена — тег не виводить нічого, гілку {if} навколо нього писати не треба.

Готові імена форм: login, register, forgot, reviews, questions. Доповнення можуть завести свої.

Власник вибирає спосіб перевірки один на весь магазин: вимкнено, вбудований захист (приховане поле-пастка) або Google reCAPTCHA. Тема про це не знає і знати не повинна — вигляд віджета приходить готовим.

⚠️ reCAPTCHA підключає скрипт із сайту Google. Це єдине місце, де вітрина звертається назовні без участі власника. Якщо ви робите тему, для якої це неприйнятно, скажіть про це в описі — вибір способу перевірки залишається за власником магазину.

Помилки і введені значення

Форма, надіслана звичайним POST і не пройшла перевірку, повертає покупця назад. Разом з ним приходять три змінні:

{if $status}<p class="ok">{$status}</p>{/if}

<label>
    Пошта
    <input type="email" name="email" value="{$old.email|default:''}"
           class="{if $errors.email}is-invalid{/if}">
    {if $errors.email}<span class="err">{$errors.email}</span>{/if}
</label>
Змінна Що всередині
$errors помилки за іменами полів; помилок немає — порожній список
$old введені значення, щоб покупцеві не набирати все заново
$status повідомлення про успіх

Підставляти $old обов'язково. Форма, яка після помилки очищає все, що людина набрала, — найчастіша причина покинутої реєстрації.

Форми, які обслуговує магазин

Їхня розмітка описана атрибутами, а не адресами: кошик, оформлення замовлення, обране, порівняння, відгуки і запитання. Що і як розмічати — на сторінці Атрибути data-*.

Коротко: адреси дій друкує магазин — об’єктом window.CartiX, темі їх знати не потрібно.

fetch(CartiX.urls.reviewSubmit, { … });

Вхід і реєстрація

{* account/login.html *}
<form method="post" action="{url path='/account/login'}">
    {csrf_field}

    <input type="text" name="identifier" value="{$old.identifier|default:''}"
           placeholder="Пошта або телефон">
    {if $errors.identifier}<span class="err">{$errors.identifier}</span>{/if}

    <input type="password" name="password" placeholder="Пароль">
    {if $errors.password}<span class="err">{$errors.password}</span>{/if}

    {captcha form="login"}
    <button type="submit">Увійти</button>
</form>

{if $auth.social}
    {include file="partials/social-login.html"}
{/if}

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

У реєстрації понад це приходить $reg_types — види покупця (приватна особа, компанія) і поля, які власник зробив обов'язковими.

Профіль

account/profile.html отримує $profile: вид покупця, контакти, прив'язані соцмережі. Набір полів задає власник, тому малюйте їх списком за даними, а не перелічуйте руками: у чужому магазині список інший.

Поля, яких може не бути

Склад полів оформлення, реєстрації і профілю власник налаштовує сам. Тема, написана під один магазин, в іншому покаже порожнечу або втратить обов'язкове поле.

Правильний підхід — обходити те, що прийшло:

{foreach $checkout.recipient_fields as $field}
    <label>
        {$field.label}{if $field.required} *{/if}
        <input type="{$field.type}" name="{$field.name}"
               placeholder="{$field.placeholder}"
               {if $field.required}required{/if}>
    </label>
{/foreach}

Відгуки і запитання

Розмітку зручно винести в partials/reviews.html і partials/questions.html — вони потрібні і на сторінці товару, і в інших місцях.

<form data-review-form>
    {csrf_field}
    <input type="hidden" name="product_id" value="{$product.id}">
    <div class="rating-input">…</div>
    <textarea name="text" placeholder="Розкажіть про товар"></textarea>
    {captcha form="reviews"}
    <button type="submit">Надіслати</button>
</form>

Надсилання обробляє тема — за адресою CartiX.urls.reviewSubmit. Відповіді на відгуки і оцінки «корисно / некорисно» влаштовані так само: CartiX.urls.reviewReply, CartiX.urls.reviewVote.

⚠️ Відгуки власник може вимкнути — тоді в $reviews приходить лише ознака «вимкнено». Звертатися до $reviews.items без перевірки не можна:

{if $reviews.enabled}
    {include file="partials/reviews.html"}
{/if}

Плейсхолдер у кожному полі

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

Тексти плейсхолдерів, як і всі інші написи теми, беруть з її файлів перекладів — див. Тексти теми і мови.

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