# Каталог ← [К разделу «Как собирается сайт»](README.md) Каталог — универсальная иерархия над документами и полями. Он подходит не только товарам, но и новостям, базе знаний, услугам, специалистам и другим типам контента. ## Создание каталога При создании выбираются рубрика, название, alias поля и назначение. Система создаёт или использует поле типа `catalog`, через которое документы связываются с разделами дерева. - **Обычный каталог** доступен в core и не предполагает цены или корзину. - **Товарный каталог** появляется только с установленным товарным модулем и включает его проекцию, остатки, варианты и связанные инструменты. Если товарный модуль не установлен, интерфейс не должен предлагать товарные сущности или пустой список «товарных каталогов». ## Обзор товарного каталога Страница **Каталог → Характеристики → Обзор** — начальная точка товарного контура. Она не создаёт ещё один каталог и не переключает публичный сайт, а собирает существующие редакторы в понятную последовательность: 1. **Характеристики** задают общие свойства товаров. 2. **Наборы разделов** определяют, какие свойства нужны в каждой ветке. 3. **Цвета и комплектации** связывают отдельные документы-варианты. 4. **Доставка** хранит одно или несколько грузовых мест товара. 5. **Карточки** и **Фильтры** управляют Twig-разметкой и CSS. Блок состояния показывает, сколько разделов получили активный набор и какие режимы сейчас включены. Разделы без рабочей схемы перечислены отдельно и открываются сразу в нужном редакторе. Товарные и вариантные характеристики разделены намеренно. Характеристику с областью **Вариант товара** нельзя добавить в набор раздела или сопоставить со старым полем рубрики. После начала использования область также нельзя поменять. Так цвет или комплектация не смогут случайно стать свойством каждого товара раздела. ## Сохранённые фильтры товаров В списке товаров и в центре качества можно сохранить текущий набор фильтров. Это удобно для постоянных очередей: «без фото», «не заполнена упаковка», «выключенные товары» или «товары ТСР». Настройте фильтры, нажмите кнопку с закладкой и плюсом рядом с заголовком блока, задайте название. Готовый набор появится в выпадающем списке и в дальнейшем применится одним выбором. Повторное сохранение под тем же названием обновляет набор, кнопка корзины удаляет его. Наборы принадлежат текущему сотруднику и не меняют каталог, документы или публичный сайт. Список товаров и центр качества хранят свои представления раздельно. ## Конструктор быстрого заполнения Страница **Товары → Быстрое заполнение** больше не привязана к одному фиксированному набору колонок. Нажмите **Настроить таблицу**, чтобы собрать рабочую таблицу под конкретную задачу: обновление цен, проверку наличия, заполнение характеристик или подготовку публикации. Конструктор разделён на три части: 1. **Доступные данные** — основные сведения о товаре, поля товарных рубрик и нативные характеристики. Уже выбранная колонка из этого списка исчезает. 2. **Колонки таблицы** — текущий состав и порядок. Колонки можно перетаскивать, а ненужные возвращать в список доступных данных. 3. **Параметры колонки** — собственное название, ширина и разрешение редактирования прямо в таблице. В одном наборе может быть не больше 24 колонок. Поля сложных типов, изображения и составные значения показываются только для чтения: их безопаснее менять в полном редакторе товара. Однострочные поля, числа, переключатели и списки сохраняются по одной ячейке без перезагрузки страницы. Если выбранного поля нет в рубрике или наборе характеристик конкретного товара, таблица показывает прочерк и не пытается создать чужое значение. Сохранённый набор может быть: - **личным** — его видит только создавший сотрудник; - **общим** — его могут выбрать другие сотрудники; - **набором по умолчанию** — он автоматически открывается у текущего сотрудника. Общий набор другого сотрудника нельзя случайно перезаписать: при изменении создаётся личная копия. Переключение фильтров, разделов и страниц не меняет состав выбранного набора. ## Разделы дерева Раздел хранит название, родителя, позицию, активность и связанные документы. Порядок и уровень меняются перетаскиванием. Активность можно переключать прямо в листинге. Связанный документ выбирается живым поиском. Используйте его, когда разделу нужна собственная страница, SEO и содержимое. Выключенный раздел остаётся в админке, но не должен участвовать в обычном публичном дереве. ## Поля раздела Для каждого раздела можно включить поля документов, которые редактор должен заполнять в этом контексте. Поля показываются по группам рубрики; выбранные строки подсвечиваются. При создании нового раздела применяются поля по умолчанию из настроек каталога. Наличие поля в рубрике и его включение в разделе — разные уровни: - рубрика определяет, что документ в принципе может хранить; - раздел определяет, что важно для документов этой части каталога. Общее поле товарной рубрики не нужно включать во все разделы. Узкое свойство, например «Тип насоса», назначайте только тем разделам, где редактор действительно должен его заполнять. Мастер характеристик использует эти назначения и не распространяет поле на остальные категории. Подготовка нового контура не удаляет исходные поля и значения документов. Для первичной проверки откройте **Товары → Характеристики → Наведение порядка**. Экран покажет поля, которые назначены слишком широко, не заполнены ни у одного товара раздела или создают фильтр без полезного выбора. Это подсказки: система ничего не снимает автоматически, пока администратор не проверит смысл поля. ## Фильтры Фильтр строится по реальному полю рубрики или зарегистрированной характеристике. Он имеет активность, порядок, способ сравнения и условия применения. Не создавайте дубли `weight_1`, `weight_2` только ради независимых фильтров. Используйте единое семантическое поле и привязывайте его к нужным разделам и фильтрам. Это упрощает импорт, API и перенос проекта. Условия фильтров должны учитывать тип данных. Число сравнивается как число, список — по ключу значения, связь — по ID связанной сущности. После изменения условий пересоберите индекс, если экран предлагает эту операцию. ### Проверка перед Native В **Каталог → Характеристики → Режимы разделов** сначала назначьте набор и оставьте оба режима в состоянии **Legacy**. Кнопка обновления строит теневой индекс, а кнопка отчёта сравнивает старый и новый контуры без изменения сайта. Отчёт проверяет не только общее количество товаров. Для каждого значения он сопоставляет старую подпись с постоянным ключом справочника, сравнивает число товаров и, для числовых характеристик, минимальную и максимальную границы. Строки с расхождениями показаны отдельно. Переключатель **Native** станет доступен только после полной сверки выбранного раздела. Вернуть прежний вывод можно в любой момент переключением этого раздела обратно в **Legacy**. ## Значения в документе Поле `catalog` хранит выбранные пункты в нормализованном JSON-формате. При открытии документа значения должны быть восстановлены в переключателях. Старые строковые значения преобразуются слоем совместимости, но новый код должен работать с JSON. ## Публичный вывод Публичный каталог использует дерево разделов, запрос документов и активные фильтры. Сама карточка содержимого настраивается отдельно от системных блоков, потому что разные сайты могут иметь разные карточки и условия. Для новостного каталога не подключайте товарный индекс. Для товарного проекта документ остаётся источником данных, а товарная таблица является быстрой проекцией для цен, остатков, вариантов и фильтрации. Лимит изображений в настройках карточки относится только к компактным листингам. Детальная страница получает полную галерею из медиаполя документа, поэтому дополнительные фотографии не требуют повторного сохранения товара или переиндексации каталога. ### Подборки товаров В **Товары → Подборки** создаются управляемые товарные ленты для главной, разделов и контентных блоков. Шаблон хранит только короткий тег, например: ```text [mod_product_list:new] [mod_product_list:sale] [mod_product_list:popular] ``` Название, подпись, ссылка «Показать все», количество карточек, раздел каталога, диапазон цены и наличие меняются в настройках подборки. Править шаблон сайта после этого не нужно. Есть два способа наполнения: - **Только выбранные вручную** — выводятся только назначенные товары; - **Автоматический источник** — вручную назначенные товары идут первыми, а свободные места заполняются новинками, акциями, популярными или всеми подходящими товарами. Товар добавляется живым поиском по названию, артикулу или ID. Порядок меняется перетаскиванием. Один товар нельзя добавить дважды. Выключенный, удалённый или неподходящий фильтрам подборки товар на сайт не возвращается. Старый расширенный синтаксис оставлен для совместимости: ```text [mod_product_list:sale:8:125,42,310] ``` Он временно переопределяет количество и ручной приоритет прямо в теге. Для новых страниц используйте короткий тег и экран подборок: так состав может менять редактор без доступа к HTML. Акционным считается товар, у которого цена показывается, текущая цена больше нуля, а старая цена действительно выше текущей. Старое служебное поле скидки само по себе больше не делает товар акционным. Если старая цена не заполнена, обычная товарная карточка показывает расчётную сравнительную цену на 25% выше текущей. Это только витринное представление: расчётное значение не записывается в документ или индекс и не добавляет товар в раздел акций. Акционный бейдж по-прежнему управляется отдельным признаком скидки. Поведение включается и выключается в настройках товарного каталога: **Каталог → нужный каталог → Карточка товара → Расчётная старая цена +25%**. Товарная проекция обновляется автоматически после общего события сохранения документа. Поэтому одинаково работают редактор, JSON API, импорт документов и CommerceML: интеграции не должны писать прямо в таблицу товарного индекса. Окончательное удаление документа также удаляет его упаковки, платёжные признаки, характеристики и связь с группой вариантов; оставшаяся группа автоматически получает нового основного варианта. Перемещение в корзину эти данные не удаляет, чтобы товар можно было восстановить. ### Центр качества товаров Вкладка **Товары → Качество** собирает рабочие очереди по уже построенному товарному индексу. Она помогает найти товары: - без цены, раздела, фотографии или артикула; - без краткого анонса и SEO-описания; - с неполной упаковкой при включённом расчёте доставки; - с нулевым остатком; - с устаревшей товарной проекцией. Нажмите нужную карточку очереди — таблица сразу отфильтруется по этой проблеме. Поиск, состояние товара, число строк и пагинация работают без перезагрузки страницы. Кнопка редактирования открывает исходный документ товара. Показатель **Готовность** учитывает только данные, без которых товар нельзя нормально продавать или обрабатывать: цену, раздел, фотографию, артикул, заполненную упаковку и актуальный индекс. Анонс и SEO показаны как рекомендации, потому что на существующих проектах их роль может выполнять отдельное поле рубрики. Нулевой остаток также является состоянием, а не ошибкой. Центр качества ничего не исправляет автоматически. После сохранения документа его товарная проекция обновится обычным системным событием. Если менялась сама схема полей или выполнялся внешний перенос, используйте точечное обновление индекса либо общую перестройку на вкладке товаров. ### Внешний вид фильтров В товарном модуле откройте **Каталог → Фильтры**, чтобы изменить Twig-разметку и CSS фильтров. Черновик можно проверить на реальном разделе, не затрагивая сайт. После публикации выберите представление в настройках нужного каталога. Режим **Текущий публичный вывод** сохраняет прежнюю разметку. Режим **Предпросмотр** также ничего не меняет в паблике. Только режим **Опубликованный Twig** включает новый шаблон, причем при ошибке система возвращается к прежнему выводу. Количество товаров передается шаблону в `option.count`. Стандартный класс счетчика — `.filter_checkbox-quantity`; его внешний вид можно менять в CSS представления. Там же выбирается поведение вариантов с нулевым результатом: показывать, отключать или скрывать. Технический контракт Twig описан в `docs/development/catalog-filter-templates.md`. ### Карточки в разных разделах сайта В **Каталог → Карточки** блок «Контексты использования» управляет карточками в избранном, просмотренных товарах, результатах поиска и похожих материалах. Сначала назначьте опубликованное представление и оставьте режим **Подготовка без публикации**. После проверки переключите только нужный контекст на **Центральная карточка**. Остальные места продолжат использовать прежнюю разметку. В Twig доступно `context.code`: `catalog`, `favorites`, `viewed`, `search` или `related`. Через него можно показывать разные команды без копирования всего шаблона. Полный контракт описан в `docs/development/catalog-card-templates.md`. ### Цвета и варианты товара Модуль сразу добавляет две характеристики с областью **Вариант товара**: `variant_color` («Цвет») и `variant_configuration` («Комплектация»). Они ничего не добавляют существующим товарам автоматически. Затем откройте **Товары → Группы вариантов**, соберите товары одной модели в группу и назначьте каждому нужные значения. Цвет используйте только в группах тех разделов, где товары реально различаются цветом; сама характеристика не становится обязательной для всего каталога. При необходимости в **Каталог → Характеристики** можно создать другие оси, например размер или материал. У типа «Один вариант» или «Несколько вариантов» заранее добавьте общий список: подпись, стабильный ключ и, при необходимости, HEX-цвет. Тогда во всех группах выбирается одна и та же запись, а переименование не приходится повторять у каждого товара. Если список значений пуст, редактор оставляет ручной ввод подписи и цвета. Это режим совместимости для существующих групп, а не рекомендуемый способ настройки новых цветов и размеров. Тот же список используется у обычной характеристики товара. В карточке товара выбирается подпись, но сохраняется постоянный ключ. Переименование подписи или цвета не требует обходить все товары. Старые карточки, где была записана сама подпись, продолжают открываться; известная подпись автоматически связывается со справочником, а неизвестная помечается как прежнее значение. Ключ блокируется после первого сохранения. Это сделано намеренно: его могут хранить товары, фильтры и внешние интеграции. Подпись и HEX-цвет при этом можно исправлять в любое время. Удаление уже используемого значения также блокируется. Каждый вариант остаётся отдельным документом со своим URL, артикулом, ценой, остатком и изображениями. В общем листинге группа показывается одной карточкой, а на странице товара штатный переключатель использует нативные значения. Старые группы с привязкой к полям рубрики продолжают работать; этот способ спрятан в блоке совместимости. Внешний вид переключателя задаётся в **Товары → Группы вариантов**: - **Карточки** — прежний вид, где каждый вариант идёт одним пунктом; - **По характеристикам** — отдельные ряды для цвета, размера, материала или комплектации. Там же можно включить показ цены, наличия и артикула. По умолчанию стоит режим **Карточки**, поэтому обновление модуля не меняет вид сайта без действия администратора. Каждый пункт остаётся обычной ссылкой на отдельный товар. Поэтому URL, корзина, цена и артикул всегда относятся к реально выбранному варианту. Если характеристики группы ещё не заполнены, движок покажет прежние карточки вместо пустого блока. В матрице оси зависимы. Сначала выбирается цвет, после чего комплектации проверяются именно для выбранного цвета. Если, например, существует синий товар в стандартной комплектации, но нет синего товара с педалью, «С педалью» останется видимой, но недоступной. Движок не подменяет её случайным товаром другого цвета. Публичная модель `VariantRepository::forProduct()` отдаёт `items`, `attributes` и подготовленную `matrix`. Шаблоны находятся в `modules/products/app/view/variants.twig` и `modules/products/app/view/variant-matrix.twig`. Назначение характеристик само по себе не включает новый шаблон карточек каталога. ### Как быстро заполнить варианты Откройте **Товары → Группы вариантов** и выберите группу. В таблице **Матрица вариантов** каждая строка соответствует отдельному товару: 1. Заполните цвет, комплектацию или другие отличия. 2. Проверьте артикул, цену, старую цену и наличие. 3. Нажмите состояние упаковки, чтобы добавить коробки, вес и габариты. 4. Для изменения названия, URL или всей галереи откройте товар кнопкой с карандашом. Изменения в ячейках сохраняются автоматически. Отдельную кнопку сохранения всей таблицы нажимать не нужно. Если значение не сохранилось, ячейка вернётся к предыдущему состоянию и покажет причину. Для повторяющихся цветов и комплектаций сначала создайте общий список значений в **Каталог → Характеристики**. Тогда в матрице будет понятный выбор, а не ручной текст. Ручной режим оставлен для старых групп и постепенного перехода. Матрица не создаёт копию товара: обычный редактор, импорт и API работают с теми же ценами, остатками и артикулами. Публичный вид также не меняется от появления этой таблицы в панели управления. После осознанного переключения фильтров раздела в режим **Native** их варианты также берутся из справочника. Пользовательский Twig-шаблон фильтра получает `option.value`, `option.label`, `option.count`, `option.selected` и `option.swatch`. Пустой `swatch` означает обычное текстовое значение. До переключения публичный каталог и его старые фильтры не меняются. ### Грузовые места Вес и размеры упаковки задаются в редакторе товара отдельным профилем доставки. Можно добавить несколько коробок и количество одинаковых мест. Эти данные не нужно дублировать характеристиками `weight`, `length`, `width`, `height`. Сервис `App\Content\ProductShipping::profile($productId)` возвращает `packages`, сводку `summary` и признак `complete`. Для расчёта заказа используется `packagesForQuantity($productId, $quantity)`: количество мест умножается на количество товара. Публичный дизайн не выводит упаковку автоматически; сайт показывает её только там, где шаблон или модуль явно использует этот сервис. ### Связи и комплекты В **Товары → Связи и комплекты** можно связать два товара как совместимые, обязательные, аксессуары, аналоги или сопутствующие покупки. Если связь работает в обе стороны, включите соответствующий переключатель: вторую запись создавать не нужно. Комплект объединяет минимум два товара и хранит количество каждой позиции. Название, цена, остаток и изображения всегда читаются из самих товаров, поэтому после изменения товара комплект не нужно пересохранять. Публичный сайт после создания связей не меняется. Вывод нужно явно вставить в шаблон страницы товара: ```text [mod_product_relations] [mod_product_relations:compatible] [mod_product_relations:required] [mod_product_relations:accessory] [mod_product_relations:alternative] [mod_product_relations:together] [mod_product_bundles] ``` Тег без уточнения сначала выводит связи, которые администратор задал вручную. Если у товара ещё нет ручных связей, модуль автоматически подбирает товары из тех же разделов каталога. Поэтому блок «Похожие товары» можно сразу добавить в общий шаблон товарной рубрики, а важные связи постепенно уточнять в панели. Теги с конкретным типом выводят только ручные связи выбранного типа и не подменяют их автоматической подборкой. Связанные товары используют те же центральные карточки, что каталог. Кнопка комплекта добавляет каждую позицию в обычную корзину с текущей ценой. Если товар выключен, удалён или у него не настроено поле цены, недоступный комплект не выводится. Техническое описание и JSON API находятся в `docs/development/product-relations.md`. ### Сравнение товаров Откройте **Товары → Сравнение**, включите функцию и выберите: - адрес публичной страницы; - общий шаблон сайта для этой страницы; - сколько товаров можно сравнивать одновременно; - нужно ли сначала скрывать одинаковые значения; - сколько дней работает отправленная покупателю ссылка. Включение функции само по себе не добавляет кнопки в карточки. Это намеренно: у разных сайтов разные дизайн и место команды. В Twig-шаблоне карточки доступны `item.comparison.enabled`, `item.comparison.selected`, `item.comparison.url` и `item.comparison.max`. Пример кнопки: ```twig {% if item.comparison.enabled %} {% endif %} ``` Движок сам добавляет и убирает товар по AJAX. Ссылку на страницу со счётчиком можно разместить в общем шаблоне тегом `[mod_product_compare]`. В таблицу попадают артикул, цена, наличие и нативные характеристики товара. Характеристики сопоставляются по системному коду: одинаковые поля разных товаров окажутся в одной строке, даже если позже была исправлена подпись. Выключенный или удалённый товар автоматически исчезает из сравнения. Кнопка **Скопировать ссылку** сохраняет набор товаров, но не копирует их цены и описания. Поэтому открывший ссылку увидит актуальные данные. Срок ссылки задаёт администратор. Разметку страницы можно переопределить в теме файлами `views/products_public/comparison.twig` и `views/products_public/comparison-mini.twig`. Полный API и контракт шаблона описаны в `docs/development/product-comparison.md`. ### Поступление, предзаказ и запрос цены Откройте **Товары → Обращения**. В одном разделе находятся: - очередь обращений покупателей; - отправка уведомлений о поступлении; - переключатели доступных сценариев; - текст согласия; - шаблон письма о поступлении; - подключение к публичной странице и личному кабинету. Функция выключена по умолчанию. После включения она также ничего не вставляет в карточку автоматически. Добавьте в шаблон товарной рубрики: ```text [mod_product_demand] ``` Форма сама определит текущий товар. Если покупатель вошёл, имя, email и телефон будут взяты из профиля. Гость указывает email или телефон вручную. Повторное обращение того же человека по тому же товару обновляет запись, поэтому очередь не заполняется дублями. Для собственного Twig-шаблона карточки доступны: - `item.demand.restock` — товар отсутствует и можно подписаться; - `item.demand.preorder` — разрешён предзаказ; - `item.demand.price` — разрешён запрос цены; - `item.demand.api_url` — адрес JSON API. При появлении положительного остатка подписки переходят в состояние **Товар поступил**. Уведомления можно отправить одной кнопкой всей готовой очереди или отдельно выбранному покупателю. Записи без email остаются в очереди для ручного звонка. Вошедший покупатель видит страницу `/personal/requests` и может отменить незавершённое обращение. Полный API и описание состояний находятся в `docs/development/product-demands.md`. ## Безопасное изменение 1. Сначала меняйте структуру и поля в тестовом разделе. 2. Проверьте сохранение документа и повторное открытие редактора. 3. Пересоберите индекс и сравните товары, отдельные значения и диапазоны. 4. Проверьте выбор, сброс и повторный выбор каждого фильтра. 5. Проверьте страницу без результатов и пагинацию. 6. Только после этого переносите настройки на остальные разделы.