3. Объектная модель
Тема видит данные как объекты с полями. Это единый контракт: те же поля отдаёт API (см. 04-api) — тема и API не расходятся.
Соглашения:
- Имена полей —
camelCase(как в API). - Деньги — число в валюте магазина (
shop.currency), уже посчитанное платформой. Тема не считает суммы, только показывает. - Идентификаторы — GUID-строки.
⚠️ сейчас:— поле/объект целевые; в текущем коде отличаются или отдаются через виджет.
shop — магазин (доступен на всех страницах)
| Поле | Тип | Описание |
|---|---|---|
id |
guid | идентификатор бизнеса |
slug |
string | ярлык для URL |
name |
string | название |
shortDescription |
string | короткое описание |
description |
string | полное описание |
logoUrl |
string? | логотип |
accentColor |
string | акцентный цвет (hex) |
currency |
string | символ валюты (₽) |
city,address,phone,email,website |
string? | контакты |
workingHours |
object | часы работы по дням |
gallery |
string[] | галерея изображений |
social |
object | соцсети {telegram,whatsapp,vk,…} |
flags |
object | {hasProducts,hasServices,hasOrders,hasAppointments,hasDelivery} — что включено |
delivery |
object | способы доставки/самовывоза (для checkout) |
payment |
object | {cash,online,onlineProvider} — доступные способы оплаты |
images |
object | ⚠️ брендинг витрины: {logo,hero,favicon,og} (сейчас частично в settings) |
flags — как тема понимает тип бизнеса: магазин (hasOrders), услуги (hasServices/hasAppointments), гибрид.
category — категория каталога
| Поле | Тип | Описание |
|---|---|---|
id |
guid | |
name |
string | |
parentId |
guid? | родитель (для дерева) |
product — товар или услуга
Один объект для товара и услуги; type различает. В списке приходят «карточные» поля, на странице — полные.
| Поле | Тип | Карточка / Страница | Описание |
|---|---|---|---|
id |
guid | обе | |
slug |
string? | обе | URL: /p/{slug} (иначе /p/{id}) |
type |
product|service |
обе | |
name |
string | обе | |
price |
number | обе | базовая цена |
effectivePrice |
number | обе | цена со скидкой (показывать её) |
oldPrice |
number? | обе | зачёркнутая, если есть скидка |
discountPercent |
number | обе | размер скидки |
imageUrl |
string? | карточка | обложка |
images |
string[] | страница | галерея |
inStock |
bool | обе | в наличии (услуга — всегда) |
categoryId |
guid? | обе | |
hasVariants |
bool | карточка | есть ли варианты |
description |
string | страница | |
sku |
string? | страница | артикул |
durationMinutes |
number? | страница | длительность (услуга) |
variants |
variant[] | страница | варианты (цвет/размер) |
options |
option[] | страница | оси выбора: {key,values[]} (напр. Цвет→[Красный,Синий]) |
modifiers |
modifier[] | страница | ⚠️ модификаторы (еда: размер, добавки) |
components |
component[] | страница | состав (композитная услуга/букет) |
variant
{id, name, effectivePrice, oldPrice, inStock, imageUrl, attributes{key:value}} — конкретная комбинация. Тема рисует селектор из options, выбор резолвит variant.
service, staff, availability (флоу Записи)
service — это product с type=service (+ durationMinutes).
| Объект | Поля | Описание |
|---|---|---|
staff |
{id, name, avatarUrl, role} |
мастер/специалист |
availability |
{date, slots[]} |
доступность на дату |
slot |
{start, end, staffId?} |
свободный слот времени |
⚠️ сейчас: доступность считает AvailabilityService, но отдаётся через виджет (bp-widget.js / PublicBookingController). Цель — те же объекты в нативном флоу витрины.
cart — корзина (флоу Заказа)
Состояние и итоги считает платформа; тема показывает.
| Поле | Тип | Описание |
|---|---|---|
lines |
cartLine[] | позиции |
itemCount |
number | всего единиц |
subtotal |
number | сумма позиций |
discountTotal |
number | скидки |
deliveryCost |
number | стоимость доставки (после выбора) |
total |
number | итого к оплате |
cartLine
{itemId, name, variantLabel, imageUrl, unitPrice, quantity, lineTotal}.
Мутации (add/remove/qty) — через JS-API рантайма, не в Liquid (см. 05-build-a-theme).
order / appointment — результат
order |
Тип | appointment |
Тип | |
|---|---|---|---|---|
orderNumber |
string | id |
guid | |
publicToken |
string | service |
product | |
status |
string | staff |
staff? | |
lines |
orderLine[] | start,end |
datetime | |
subtotal,deliveryCost,total |
number | status |
string | |
customer |
customer | customer |
customer | |
delivery |
object | place |
at_business|at_customer |
status (заказ): new → confirmed → packed → shipped → delivered (набор зависит от способа получения). status (запись): booked → confirmed → done / cancelled.
customer — покупатель
{name, phone, email, address?}. Узнаётся по сессии/аккаунту; тема предзаполняет, но не хранит.
Контекст страницы — что доступно где
| Страница | Объекты в контексте |
|---|---|
| Главная | shop, categories, collections, featuredProducts |
| Категория | shop, category, products (пагинация), categories |
| Товар/услуга | shop, product (полный), relatedProducts |
| Корзина | shop, cart |
| Запись | shop, service, staff[], availability |
| Checkout | shop, cart|appointment — платформенный, тема даёт токены+блоки |
| Статус | shop, order|appointment |
shop — глобально на всех страницах. Списки (products) приходят порциями с пагинацией.
Что дальше
- Как эти объекты получить по HTTP и как выполнять действия (add-to-cart, book) — 04. API-контракт.
- Как из них собрать тему — 05. Как сделать тему.