Я сломал весь мозг пытаясь понять можно ли сгенерировать контент для блока menu
за один проход.
Проблема заключается в том, что блок menu
не приемлет в поле content контекста ничего кроме элемента menu__group
или блока menu-item
. Таким образом, даже если положить в контент блока menu
БЭМ сущность, которая могла бы развернуться в menu__group
или menu-item
, будет выброшено исключение.
Проблему мне удавалось решить только используя 2 прохода. Сначала выполняем преобразование блоков в поле content вне блока menu
, а на второй проход уже развёрнутое содержимое размещаем в блоке menu
.
В BH
это получилось сделать более-менее удачно, с помощью метода bh.processBemjson()
.
В xjst
трансформацию контента пришлось делать в bemtree
, а в блок menu
вставлять уже в bemhtml
. Приручить applyCtx
, чтобы получилось как в BH
не вышло.
Хотелось бы понять, возможно ли сгенерировать таким образом содержимое блока menu
средствами bemhtml,
не прибегая к bemtree
:
view ориентированный bemjson на входе
{ block: 'my-menu', content: [ { elem : 'group', content : [ { elem : 'item', title : '1st level item with sub-item' content : [ elem : 'group', content : { elem : 'item', content : '2nd level item' } ] } ] }, { block: 'my-menu', elem : 'group', content : [ { elem : 'item', title : '1st level item but in separate section' } ] } ] }
На выходе ожидается разметка блока my-menu
один из элементов которого будет блок menu
(mix my-menu__menu
) внутри которого будут menu__group
(mix my-menu__group
) и menu-item
(mix my-menu__item
).
Бонусный вопрос: зачем такие ограничения накладываются в шаблонах библиотеки? Мне кажется, что логику из-за которой возникли подобные ограничения можно было возложить на js реализацию блока.
https://github.com/bem/bem-components/issues/1513
У нас имено так работает блок
select
(см. select__menu.bemhtml). Не скажу, что это хорошо или плохо — другого способа, мы пока не придумали.Ты можешь раскрыть мысль? Как сохранить ленивость блока, правильную отрисовку в HTML до загрузки JS (нам важно, чтобы лейаут максимально «не скакал» в процессе загрузки страницы — это очень «анноит» пользователей) и при это унести часть логики в JS?
Вот такой подход мне как раз совсем не подходит. Во-первых, у меня довольно не простые
menu-item
. Во-вторых они бывают разные в зависимости от модификатора. Хочется воспользоваться всей мощьюbemhtml
и описать их как элемент блока.Да я уже понял именно эту проблему был призван решать код шаблонов блока
menu
.https://github.com/bem/bem-components/issues/1520 решит мои проблемы, т.к. мне требуется базовый блок
menu
безmenu_mode_*
расширений.Пообщались с @veged @dfilatov @aristov, проблему можно решить через кастомные моды (по сути создать аналог
processBemjson
из bh). Это будет куда проще, чем текущая реализация в pr.А что такого сложного в текущем pr? Код ровно тот же. Совместимость соблюдена. Гибкость повышена
Не знаю что вы решите по этому issue, но всеми руками за аналог processBemjson в bemhtml.
Аналог processBemjson это хорошо и хотелось что бы кто-то более подробно осветил эту тему. Тем не менее хочется услышать аргументированный ответ, что именно не позволяет принять https://github.com/bem/bem-components/issues/1520 ?
1) PR не решает проблему в общем случае, а просто перекладывает ее из одной папки в другую. Если тебе, для того же самого
kg-menu
, нужен будет модификатор_mode
, ты сможешь сделать, как хочешь? 2) Добавлять флаги вthis
вне модыdefault
, не очень круто — они точно так же могут понадобиться в модахmix/js/attrs
(сейчас не нужны, но с точки зрения общего стиля кода в библиотеке, это аргумент). 3) Говорить «в BEMJSON блокаmenu
можно класть все что угодно, но работать будет только с блокамиmenu-item
», исключительно по опыту поддержки библиотек, не прокатывает. Как задокументировать такое BEMJSON API в библиотеке?Это основные причины, почему сходу я не готов принять PR в текущем виде.
Можешь показать пример того, что в каком виде ты хочешь задавать твой блок и во что он должен разворачиваться? Код из
gist
выше, некоректен — там вообще блокаmenu
в финальном BEMJSON нет.Спасибо, так гораздо понятнее.
def
.В документации есть следующее предложение:
Что уже противоречит декларации:
Оказывается в массиве у нас могут быть группы с массивами пунктов в меню. И, внезапно, в документации не сказано, что пункт меню должен быть реализован блоком
menu-item
.Таким образом, вопрос: "Как задокументировать такое BEMJSON API в библиотеке?" - актуален, в том числе, и для текущей версии. У меня есть некоторые мысли на этот счёт, но они пока не сформировались в нечто целостное.
Итого, предлагаю:
def
menu
@zxqfox в bemhtml в текущем виде не может быть аналога
processBemjson
т.к. там нет выделенной стадии формирования bemjson — дефолтная мода заполняет буфер строками с htmlно это не проблема для реального использования (в частности для изначальной задачи @Guria) — можно сделать свою кастомную моду и использовать её
@veged Очевидно, стоит портировать xjst на пхп, чтобы понять как оно там работает... ;-)
Вы не думали там дом ноды генерировать из bh/bemhtml? Строки даже не модно уже.
@veged Можно пример подобной кастомной моды? Будет ли такой подход приемлем для библиотеки?
можно даже без кастомной моды!
как я вижу задачу: есть
my-menu
и внутри естьmy-menu__my-elem
({ block : 'kg-menu', content : [{ elem : 'my-elem' }, { elem : 'my-elem' }] }
), которые должны превратиться в какое-тоmemu
сmenu-item
-амидостаточно таких шаблонов:
это же магия!
@veged Спасибо за пример. Попробую данный подход и посмотрю на сколько он будет удобен.
Однако яро прошу принять хотя бы проверку на наличие поля content перед попыткой итерирования по нему.
мы готовы принять все полезные исправления, но только, пожалуйста, в виде раздельных пуллреквестов
@veged подход отличный, беру на заметку. Однозначно его надо сохранить в рецепты BEMHTML. Но меня всё таки волнует тот факт, что пользователю блока
my-menu
или разработчику делающего новый элемент придётся знать, что шаблоны не имеют права ничего генерировать и лишь добавлять что-либо в некое поле контекста. Таким образом считаю, что подход имеет право жить на уровне проекта, но не в библиотеке. Вы сами учите критически относиться к тому, как должна выглядеть библиотека. Библиотека вынуждающая такой подход использовать, тоже не желательный вариант@veged @tadatuta @narqo вынос логики в menu_mode с сохранением работы в рамках моды def считаем полезным исправлением?