1
Gender
s.zotov edited this page 2026-04-12 20:46:36 +00:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Гендерная сегментация

Концепция

Одно письмо может содержать блоки для женской и мужской аудитории. При рендере выбирается header/footer по гендеру, а блоки могут переставляться местами.

Сегменты блоков

Каждый блок имеет свойство segment:

  • 'common' (по умолчанию) — общий блок, показывается в обеих версиях
  • 'female' — только для женской версии
  • 'male' — только для мужской версии

Кнопки О / Ж / М в шапке каждого блока устанавливают сегмент (setBlockSegment).

Кнопки Жен / Муж

Переключают currentGenderVersion ('female' / 'male') и перерендеривают превью.

Функция assembleGenderVersion(target):

  • Меняет currentGenderVersion = target
  • Не переставляет блоки в конструкторе
  • При рендере backend подставит нужный header/footer

Кнопка ⇅ (Flip)

Переставляет блоки местами и переключает гендер.

Функция flipSegmentOrder():

  1. Вызывает buildVersion(assembledBlocks, target)
  2. Физически перестраивает массив assembledBlocks[]
  3. Переключает segmentFlipped (boolean toggle)
  4. Синхронно меняет currentGenderVersion

Алгоритм buildVersion

buildVersion(list, target):
  1. Ищет блок с swapCenter = true (divider-ось)
  
  ЕСЛИ ось найдена:
    - Блоки ДО оси  группа A
    - Блоки ПОСЛЕ оси  группа B
    - target === 'male'  [B, ось, A]
    - target === 'female'  [A, ось, B]
  
  ЕСЛИ оси нет:
    - commonsPrefix = общие блоки до первого сегментированного
    - segmentA = блоки с segment === target
    - commonsMid = общие блоки между сегментами
    - segmentB = блоки с противоположным segment
    - commonsSuffix = общие блоки после последнего сегментированного
    - Результат: [commonsPrefix, segmentA, commonsMid, segmentB, commonsSuffix]

Разделитель (swapCenter)

Блок типа "dividerVA" (разделитель) может иметь флаг swapCenter = true:

  • Устанавливается кнопкой в шапке блока-разделителя
  • Только один блок может быть осью одновременно
  • Служит центральной точкой для buildVersion() — блоки до и после оси меняются местами

Gender Paths

Настройки в settings.genderPaths:

{
  "headerFemale": "./parts/header/header-woman",
  "headerMale": "./parts/header/header-man",
  "footerFemale": "./parts/footer/footer-woman",
  "footerMale": "./parts/footer/footer-man"
}

В UI — dropdown-пикеры, список файлов из /api/parts-files (сканирует email-gen/emails/vipavenue/parts/).

Цепочка передачи gender при рендере

  1. App.svelteapiRenderEmail(..., { gender: currentGenderVersion })
  2. vite.config.js → читает genderPaths из settings.json, форвардит в email-gen-api с { gender, genderPaths }
  3. email-gen-api/server.jsrewriteHtmlPug() — записывает html.pug с нужными путями:
    block header
        include ./parts/header/header-woman    // или header-man
    block footer
        include ./parts/footer/footer-woman    // или footer-man
    

Кэш рендера и gender

Хэш кэша: MD5(slug + pug + gender + JSON(genderPaths))

Female и male версии кэшируются отдельно.

ID Pool

Пул ID товаров для быстрого заполнения блоков:

  1. Ввод — textarea, по одному ID на строку или через запятую
  2. Из Yonote — кнопка refreshIdsFromYonote():
    • Берёт ID из assemblyInfo.extra (свойство "ID товаров")
    • Женские ID первыми (filter по /жен|female|ж\b/i)
    • Затем неразмеченные, затем мужские
  3. РаспределениеdistributeIds():
    • Проходит по блокам с полем mixin-ids
    • Вставляет 3 или 4 ID в зависимости от имени миксина (products3 → 3, products4 → 4)
    • Последовательно из очереди idPoolQueue[]