Family cards on a category page
/docs/guide-family-cardscurrentМашинный перевод с английского· проверено 2026-10-25
Статус: current · проверенный: 2026-10-25, source обзор по компонентам и API контракты; нейтральный стиль обучения, а не live принятие владелец: гладиатр API документация · Служить: GET /docs/guide-family-cards связанный: /docs/authentication, /docs/components, /docs/own-markup, /docs/catalogue, /docs/chrome, /docs/troubleshooting
1. Результат и предпосылки
Вы замените один category's сетка запаса с двумя вставками одного многоразового использования Компонент: семья cards и а combo полоска. size Цветной чип переключает целое SKU панелями, включая картинку, запас, price и exact combo Цитата: Это link Также работает без JavaScript. Выберите это path когда card design должен быть твой; keep запас listing когда существует design достаточно.
Используйте key и руководство по разрешению before любой API работа. Вам нужен существующий category, product groups с size/colour Топоры, опубликованные members, и опубликованный combo sets. конфигурировать Доступ к списку покупателей для обоих selected attributes и group топоры first: Каталог § 8.3. Это каноническое section Также объясняет, effect фильтры; изменение доступа Просто для получения чипов может выставить filter, Поэтому проверьте result. Проверяйте каждый field Используется ниже /docs/vz-keys.json → scope before издатель.
Пример использует TOPLOFT коды bed_size и bed_color; Замените свой own Коды. document и product ids Ниже приведен пример, а не платформа. Решите и проверьте свои own ids. Нет. production Писать - это required то Прочитайте или адаптируйте этот учебник.
Найди его. ids с тем же самым key и contour:
GET /product-groups→result[].id,membersиaxes[].attribute_id.GET /attributes→ атрибутidиcode. The shop исходит из key;company_idне является поддерживаемым селектором для этой конечной точки;.GET /products?filter.category_id=<combo-category-id>&page.number=1&page.limit=48→ проверятьkind:"combo"и select тот set product ids.filter.kindне поддерживается; при необходимости, пагинат.
The standard сетка block иметь payload.kind:"productListing". Замена его удаляет его встроенные фильтры, сортировка, пагинация UI и ItemList JSON-LD; смотреть Компоненты §4.7. Ан own-вставки разметки ограничиваются 48 selected ids / items или groups; использовать own разметка §2 для feed контракт.
2.Подготовить два компонента files
создавать index.html и component.json в той же папке компонентов. Опубликовать как бы level-1 компонент через Компоненты §4.1. Полное HTML следовать. CSS Он является локальным, локальным для fc- классы, и держит нейтральные цвета. tl-section class принадлежит к TOPLOFT theme; адаптировать Как описано в §4, нет custom script или клиент-side price расчет.
index.html:
<style>
.fc-catalog,.fc-combos{color:inherit;font:inherit}
.fc-catalog *,.fc-combos *{box-sizing:border-box}
.fc-catalog a,.fc-combos a{color:inherit;text-decoration:none}
.fc-catalog a:focus-visible,.fc-combos a:focus-visible{outline:2px solid currentColor;outline-offset:3px}
.fc-grid,.fc-combo-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
.fc-card,.fc-combo-card{min-width:0;border:1px solid #ddd;border-radius:12px;overflow:hidden}
.fc-media{position:relative;background:#f5f5f5}
.fc-image,.fc-combo-picture{display:block}
.fc-image img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
.fc-photo-title,.fc-body,.fc-combo-body{padding:16px}
.fc-photo-title h3,.fc-combo-name{margin:0 0 8px}
.fc-detail{margin:0}
.fc-promo,.fc-stock{display:inline-block;margin:0 0 12px 16px;padding:4px 8px;background:#eee;border-radius:4px}
.fc-combo-tag{display:block;margin:0 16px 12px;padding:10px;border:1px solid currentColor;border-radius:4px}
.fc-combo-heading{display:block}
.fc-combo-regular,.fc-old{margin-left:8px;color:#666}
.fc-controls,.fc-axis{margin-bottom:12px}
.fc-sizes,.fc-colors,.fc-prices{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.fc-size,.fc-color{display:inline-flex;align-items:center;justify-content:center;gap:4px;border:1px solid #bbb;border-radius:4px}
.fc-size{min-height:38px;padding:6px 10px}
.fc-color{width:42px;height:42px}
.fc-color img{display:block;width:38px;height:38px;object-fit:cover;border-radius:3px}
.fc-size[aria-current="true"],.fc-color[aria-current="true"]{outline:2px solid currentColor;outline-offset:1px}
.fc-size[aria-disabled="true"],.fc-color[aria-disabled="true"]{opacity:.4}
.fc-combo-dot{width:6px;height:6px;background:currentColor;border-radius:50%}
.fc-price,.fc-combo-total b{font-size:1.2em}
.fc-combo-price{text-decoration:underline!important}
.fc-combos{margin-top:32px}
.fc-combos-heading{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:16px}
.fc-combo-picture img{display:block;width:100%;height:auto;aspect-ratio:1;object-fit:cover}
.fc-combo-eyebrow{font-size:.8em}
.fc-combo-total{margin:12px 0}
.fc-combo-items{display:grid;gap:10px}
.fc-combo-item{display:flex;align-items:center;gap:10px}
.fc-combo-item img{width:44px;height:44px;object-fit:cover;flex:none}
.fc-combo-item-copy,.fc-combo-item-name{display:block;min-width:0}
.fc-combo-item-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fc-combo-cta{display:inline-block;margin-top:16px;text-decoration:underline!important}
@media(max-width:767px){.fc-grid,.fc-combo-grid{grid-template-columns:1fr}.fc-combo-item img{width:32px;height:32px}}
</style>
{{#show_catalog}}
<section class="tl-section fc-catalog" aria-label="{{ catalog_label }}">
<div class="fc-grid">
<article class="fc-card" vz-for="p in products" vz-panes>
<div vz-for="m in p.members" vz-pane="{{ m.id }}" vz-hidden="!m.selected">
<div class="fc-media">
<a class="fc-image" vz-href="m.url" aria-label="{{ m.name }}">
<img vz-src="m.preview" srcset="{{ m.preview_srcset }}" sizes="(max-width: 767px) calc(100vw - 32px), calc(50vw - 62px)" alt="{{ m.name }}" width="1024" height="768" decoding="async" loading="lazy">
</a>
<div class="fc-photo-title">
<h3><a vz-href="m.url" title="{{ m.name }}"><span vz-if="p.group">{{ p.group.name }}</span><span vz-if="!p.group">{{ m.name }}</span></a></h3>
<p class="fc-detail"><span vz-if="m.attrs.bed_size">{{ m.attrs.bed_size.value }}</span><span vz-if="m.attrs.bed_color"> · {{ m.attrs.bed_color.value }}</span></p>
</div>
<span class="fc-promo" vz-if="m.combo" aria-hidden="true">%</span>
<a class="fc-combo-tag" vz-if="m.combo" vz-href="m.combo.url" aria-label="{{ m.combo.name }}">
<span class="fc-combo-heading">В комбо выгоднее</span>
<span class="fc-combo-tag-price"><b class="fc-combo-item-price">{{ m.combo.item_price_text }}</b><s class="fc-combo-regular">{{ m.combo.item_regular_price_text }}</s></span>
</a>
<span class="fc-stock" vz-if="m.in_stock">В наличии</span>
<span class="fc-stock fc-stock-off" vz-if="!m.in_stock">Под заказ</span>
</div>
<div class="fc-body">
<div class="fc-controls">
<div class="fc-axis" vz-for="ax in m.variants">
<div vz-if="ax.options.1">
<div class="fc-sizes" vz-if="!ax.options.0.image_url" role="group" aria-label="{{ ax.name }}">
<span vz-for="o in ax.options" class="fc-opt">
<a class="fc-size" vz-if="o.available" vz-href="o.url" vz-pick="{{ o.member_id }}" aria-current="{{ o.current }}"><span>{{ o.label }}</span><span class="fc-combo-dot" vz-if="o.has_combo" aria-hidden="true"></span></a>
<span class="fc-size" vz-if="!o.available" aria-disabled="true">{{ o.label }}</span>
</span>
</div>
<div class="fc-colors" vz-if="ax.options.0.image_url" role="group" aria-label="{{ ax.name }}">
<span vz-for="o in ax.options" class="fc-opt">
<a class="fc-color" vz-if="o.available" vz-href="o.url" vz-pick="{{ o.member_id }}" aria-current="{{ o.current }}" title="{{ o.label }}" aria-label="{{ o.label }}"><img vz-src="o.image_thumb" srcset="{{ o.image_srcset }}" sizes="38px" alt="" width="38" height="38" loading="lazy"></a>
<span class="fc-color" vz-if="!o.available" aria-disabled="true" title="{{ o.label }}"><img vz-src="o.image_thumb" srcset="{{ o.image_srcset }}" sizes="38px" alt="" width="38" height="38" loading="lazy"></span>
</span>
</div>
</div>
</div>
</div>
<div class="fc-prices">
<b class="fc-price">{{ m.price_text }}</b>
<a class="fc-combo-price" vz-if="m.combo" vz-href="m.combo.url" title="Цена этой модели в комбо-наборе"><span class="fc-price-fire" aria-hidden="true">🔥</span><span>{{ m.combo.item_price_text }}</span></a>
<s class="fc-old" vz-if="m.old_price_text">{{ m.old_price_text }}</s>
</div>
</div>
</div>
</article>
</div>
</section>
{{/show_catalog}}
{{#show_combos}}
<section class="fc-combos" aria-label="{{ combo_heading }}">
<div class="tl-section fc-combos-inner">
<div class="fc-combos-heading"><h2>{{ combo_heading }}</h2><a href="{{ combo_all_url }}">Все наборы ↗</a></div>
<div class="fc-combo-grid">
<article class="fc-combo-card" vz-for="c in products">
<a class="fc-combo-picture" vz-href="c.url" aria-label="{{ c.name }}"><img vz-src="c.preview" srcset="{{ c.preview_srcset }}" sizes="(max-width: 767px) calc(100vw - 32px), calc(50vw - 62px)" alt="{{ c.name }}" width="640" height="640" loading="lazy"></a>
<div class="fc-combo-body">
<span class="fc-combo-eyebrow">КОМБО-НАБОР</span>
<h3 class="fc-combo-name" title="{{ c.name }}">{{ c.name }}</h3>
<div class="fc-combo-total"><b>{{ c.price_text }}</b><s vz-if="c.old_price_text">{{ c.old_price_text }}</s></div>
<div class="fc-combo-items">
<a class="fc-combo-item" vz-for="it in c.combo_items" vz-href="it.url">
<img vz-src="it.preview_url" srcset="{{ it.preview_srcset }}" sizes="(max-width: 767px) 32px, 44px" alt="" width="44" height="44" loading="lazy">
<span class="fc-combo-item-copy"><span class="fc-combo-item-name" title="{{ it.name }}">{{ it.name }}</span><small>{{ it.price_text }} <s vz-if="it.regular_price_text">{{ it.regular_price_text }}</s></small></span>
</a>
</div>
<a class="fc-combo-cta" vz-href="c.url">Показать комбо ↗</a>
</div>
</article>
</div>
</div>
</section>
{{/show_combos}}component.json:
{
"name": "Family cards and combo sets",
"params": [
{"key": "show_catalog", "type": "bool", "label": "Показывать модели", "default": true},
{"key": "show_combos", "type": "bool", "label": "Показывать комбо", "default": false},
{"key": "catalog_label", "type": "text", "label": "Название области каталога", "default": "Товары", "max": 100},
{"key": "combo_heading", "type": "text", "label": "Заголовок комбо", "default": "Комбо-наборы", "max": 100},
{"key": "combo_all_url", "type": "link", "label": "Все наборы", "default": "/catalog/combo"}
]
}3. Настройка двух вставок
Следуй за мной. Канонический рабочий процесс замены компонентов §4.8 для API последовательность вызовов, snapshot, usage проверка, validation, активация и Откат.Два JSON кузова, расположенные ниже, снабжают вставку content для этого рабочий процесс; не связывайте их before Пропускной пункт. component.ref с Ваш опубликованный document id. Один и тот же компонент повторно используется для обеих вставок..
Семейная вставка, с явным order представитель products. productsIds содержит Один член семьи: Этот член является default selected SKU, и id order Это семья order (Каталог 4.1.).
{
"item": {
"name": "Category families",
"sections": [{"type": "text", "payload": {
"v": 2, "kind": "component",
"props": {
"blockWidth": "full",
"paddingSides": {"top": 0, "right": 0, "bottom": 0, "left": 0},
"component": {
"ref": 189,
"params": {"show_catalog": true, "show_combos": false, "catalog_label": "Кровати"},
"productsMode": "collapse",
"productsAttributes": ["bed_size", "bed_color"],
"productsIds": [2503, 2509, 2498]
}
}
}}]
}
}Комбо вставка, выбор set ids и явно отключать каталог:
{
"item": {
"name": "Category combo sets",
"sections": [{"type": "text", "payload": {
"v": 2, "kind": "component",
"props": {
"blockWidth": "full",
"paddingSides": {"top": 0, "right": 0, "bottom": 0, "left": 0},
"component": {
"ref": 189,
"params": {
"show_catalog": false, "show_combos": true,
"combo_heading": "Комбо-наборы", "combo_all_url": "/catalog/combo"
},
"productsIds": [2806, 2807]
}
}
}}]
}
}Омить productsIds и использовать productsCategoryId Когда вы хотите, чтобы category feed Вместо выбора. Feed границы, упорядоченный отбор, группирование и limits Канонический в own разметка §2. productsAttributes При этом каждый из них имеет свой: другой. category может повторно использовать этот компонент с own Список атрибутов. template Если нужны разные коды. Недавно опубликованный член существующего selected Семья подхватывается без редактировать HTML; недавно selected семья или set требует изменения его вставки выбор.
4. Соединяйтесь с theme
Следуйте за мной. chrome §3.7 Чтобы обнаружить active theme и его content-container class. Читать GET /themes/{id}/site → active_release_id и files[].path, затем GET /themes/{id}/site/releases/{rid}/file?path=<css-path> → text. Используйте path Возвращаясь к этому освобождению, URL-закодированный в query; Если нет, то нет active Освобождение, нет theme-папка CSS повторно использовать. TOPLOFT это class это tl-section, Используется в обоих content В корнях выше. theme, Заменить его на найденный class. Держите вставку wrapper settings из §3 и уходить contentWidth Отключи, давай. theme own container width и водостоки Один раз, не добавляйте второй корень max-width горизонтальный padding компенсировать. перепроверять image sizes против полученного columns и фактические width (image правила). местный CSS cannot Изменить размер платформы's внешний wrapper.
5.Проверить before принятие
Используйте активацию и проверку считывания из компонентов §4.8, а затем проверьте page как Устранение неполадок §2 описание:
- Без JavaScript, Начальный элемент виден, другие панели видны. hidden, Ссылки открываются правильным членом page.
- меняться size Сохраняет цвет, когда существует комбинация. комбинация отключена; реальный неучтенный член остается выбираемым.
- Изображение, атрибут text, price, акции, ссылки и combo Изменение цитаты вместе. The small Точка описывает
o.has_combo, когда лента и цитата используют selected член'sm.combo; Их контракт заключается own разметка §2. - Текстовые чипы и image Чипы идентифицируют current Измененный клик последующий link; член без рендеринга все еще открывает свою page.
- The combo Вставка показывает только sets, цены на сервер и состав. Запросы на миниатюру совпадают display size и DPR; Не сломанный image source появляется.
- Оба sections line Вместе с существующим banner на рабочем столе и mobile ширина. Иной category Оставаться неизменным, выглядеть неизменным.
- Публикация другого члена selected Семья обновляет свои доступные choices без HTML Редактирование. Повторение обновлений рабочего процесса существующих вставок Вместо того, чтобы дублировать сетку.
Этот пример скрывает топоры с менее чем двумя options и выбирает image-чип отсчет от указанного first вариант's image_url. Если ваша ось использует смешанные image
- покрытие, адаптируйте эту презентацию к вашему data Вместо того, чтобы принимать все
опция имеет текстуру. Не добавляйте клиент-side SKU Математика замещения или котировки.
6. Откатиться назад и поставить диагноз
Восстановить спасенное group Если же он изменяется, то сохраняется откат Шаг компонентов §4.8. Перечитывать и проверять page. Выпуск компонентов Откат отката отдельная: восстановление group Ссылки не восстанавливают общий компонент's Сохрани старое. blocks и снимки во время приема.
Если plain Появляются плитки, first проверка вставки mode и доступ покупателя к топорам; Если цитата отсутствует, проверьте члена's Фактический прибыль combo Вместо того, чтобы принуждение badge. Использовать устранение неполадок и канонический field ссылка /docs/vz-keys.json для дальнейшей диагностики.
Ссылки на документы используют heading Фрагменты на сайте: например, /docs/components#4-8-replace-a-category-s-stock-grid-through-a-pat-with-rollback. Для сырых API section использовать GET /docs/components?section=4-8-replace-a-category-s-stock-grid-through-a-pat-with-rollback. Точка внутри 4.8 становится дефисом (4-8, не 48). Фрагмент перемещается по выполненный page; не является select а section в HTTP запросить у API.
7.Безмолвно ignored
Неизвестные или невидимые коды атрибутов не создают атрибутов. values; охрана optional data с vz-if. Подробный feed и ignored-Правила, устанавливающие правила, должны то own разметка §§2,8, и правил параметра компонентов для компоненты. Успешное письмо само по себе не доказывает, что предназначенный feed или замена является active: выполнять read-back и браузер Проверки выше.
Исходник: https://api.vizen.shop/docs/guide-family-cards?full=1