Files
2018-lpon-site/_prj_blueprint/DSL.md
T

7.2 KiB
Raw Blame History

Спецификация: LPON Store Hub DSL (Компактный конструктор интерфейсов на кортежах)

драфт

1. Обзор и цели

Мы реализуем гибкий, управленный данными (Data-Driven) конструктор страниц внутри бэкенда Django для LPON.RU. Вместо написания отдельных вьюх (Views) и шаблонов под каждый формат или раздел (например, /catalog/cassettes/, /catalog/vinyl/), мы формируем динамические Страницы-Хабы (Hub Pages) с помощью компактного JSON Tuple DSL, который хранится прямо в базе данных.

Система завязана на модель TbArticle с типом l_article_type = 'HUB'. Конфигурация хранится в JSON-поле метаданных статьи (j_article_metadata['hub']).


2. Синтаксис и структура JSON DSL

Массив hub представляет собой список позиционных кортежей (массивов). Движок определяет тип блока на основе длины массива и типов переданных значений.

Правила синтаксиса:

{
  "hub": [
    ["source-slug", "view_mode"],
    ["source-slug", limit, "sort_rule", "view_mode"],
    ["module-or-article-slug"]
  ]
}

3. Спецификация блоков

Тип A: Блок предложений товаров (по умолчанию Длина = 4)

Выводит подборку товаров (TbOffer), полученную на основе категории, тега формата или слаг-коллекции.

Формат: [ "slug", limit, "sort", "view_mode" ]

Параметры:

  1. slug (str): Уникальный слаг TbMusicStyle, TbArticle (Категория/Тег) или идентификатор формата (например, cassettes-studio, cassettes-used-blank).
  2. limit (int): Количество выводимых товаров (например, 5, 20). Фолбэк при ошибке: 10.
  3. sort (str): Правило сортировки:
  • views → -i_offer_views (самые просматриваемые)
  • favorites → -i_offer_favorites (самые популярные / в избранном)
  • newest → -t_offer_created (новинки)
  • price_asc → f_offer_price (сначала дешевые)
  • price_desc → -f_offer_price (сначала дорогие)
  1. view_mode (str): Компонент рендеринга (шаблон):
  • carousel → Горизонтальная карусель / слайдер.
  • grid → Стандартная сетка карточек.
  • list → Компактный вертикальный список.

Пример: ["cassettes-studio", 5, "views", "carousel"]

Замечания: view_mode -- это название зарегистрированного шаблона в системе. Если передан неизвестный view_mode или он отсутствует, используется дефолтный list.

Тип B: Баннер / Вложенная статья / Вложенный хаб (Длина = 2)

Встраивает существующую статью, рекламный баннер или массив вложенного хаба.

Формат: [ "slug", "view_mode" ]

Параметры:

  1. slug (str): Слаг целевой TbArticle.
  2. view_mode (str): Режим отображения:
  • slider / hero → Главный баннер / промо-слайдер.
  • teaser → Тизер статьи с кнопкой «Читать далее».
  • full → Полный HTML-контент статьи, встроенный inline.

Пример: ["hero-banner-cassettes", "slider"]

Тип C: Динамический модуль / Плагин (Длина = 1)

Запускает кастомный Python-модуль, зарегистрированный в системе (например, расчет скидок, интерактивные виджеты, реклама).

Формат: [ "module-slug" ]

Параметры:

  1. slug (str): Уникальный идентификатор, зарегистрированный в PluginRegistry (например, module-promo-mandarin, module-ad-banner-1).

Пример: ["module-promo-mandarin"]

4. Полный пример конфига (j_article_metadata)

{ "hub": [ ["hero-cassettes-2026", "slider"], ["cassettes-studio", 6, "views", "carousel"], ["cassettes-studio", 20, "newest", "grid"], ["module-mandarin-promo"], ["cassettes-maxell-used-ud2-c90-ver2", 6, "popular", "carousel"], ["cassettes-tdk-ned-cding2-c60", 20, "price_desc", "list"], ["guide-how-to-clean-heads", "teaser"] ] }

5. Защита и логика бэкенда (Требования к Python / Django)

При разработке парсера DSL:

  1. Защита от зацикливания и бесконечной рекурсии:
  • Передавать множество visited_slugs при рендере страницы.
  • Если вложенный блок пытается загрузить slug, который уже есть в visited_slugs, пропускать блок или выводить отладочный HTML-комментарий (<!-- DSL Error: Circular reference detected for slug -->).
  1. Ограничение глубины вложенности:
  • Жестко ограничить максимальную глубину рекурсии: MAX_RECURSION_DEPTH = 2 (устанавливается в settings.py).
  1. Отказоустойчивость (Graceful Degradation):
  • Если limit передан не числом или sort содержит неизвестную строку, парсер должен тихо применить безопасные дефолты (limit=10, sort='newest', view_mode='grid'). Ошибка синтаксиса в JSON никогда не должна приводить к 500 Server Error.
  • Если slug не найден в базе, блок пропускается, а в HTML выводится комментарий: <!-- DSL Error: Slug not found -->.
  1. Изоляция данных:
  • Внутри DSL запрещено использовать сырые имена полей БД (например, k_offer_to_item__s_item). Все выборки данных маппятся строго через slug и внутренние обработчики запросов (Query Handlers).
  • Все ключи из json['hub'] должны быть объявлены заранее.
  1. Валидация slug
  • Нужно добавить в валидатор админки статей (TbArticle) проверку на "не совпадение" slug с существующими роутами сайта из 'urls.py' (чтобы не было конфликта URL-ов).