Форми вітрини
Захист форми, перевірка «я не робот», виведення помилок поруч із полем та адреси всіх дій покупця.
На цій сторінці
На вітрині два види форм. Одні надсилаються звичайним 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}
Плейсхолдер у кожному полі
Порожнє поле без підказки всередині — це запитання без відповіді: покупець не знає, що туди писати і в якому вигляді. Плейсхолдер потрібен усюди: у тексті, у числі, у багаторядковому полі, у випадному списку без вибраного значення.
Тексти плейсхолдерів, як і всі інші написи теми, беруть з її файлів перекладів — див. Тексти теми і мови.