Войти с помощью github

Заманчиво выглядит сгенерить на BEM MapReduce и загрузить в CouchDB. Можно было бы и json отдавать, и html для блоков на разных уровнях. Навскидку проблема с модулями: reduce не поддерживает, а в остальных результаты не кешируются. Может BEM собираться без модулей (все инлайнить)?

подскажите пожалуйста в чем ошибка

код:

    var bemtreeTemplate = fs.readFileSync(path.join('.',pathToBundle, 'index.bemtree.js'), 'utf-8');
    var context = vm.createContext({
        console: console,
        require: require,
        Vow: vow
    });
    vm.runInContext(bemtreeTemplate, context);

ошибка:

node ./desktop.bundles/index/index.node.js
evalmachine.<anonymous>:85
       if('onreadystatechange' in doc.createElement('script')) { // ie6-ie8
                                      ^

TypeError: Cannot read property 'createElement' of undefined
    at evalmachine.<anonymous>:85:39
    at evalmachine.<anonymous>:104:7
    at Object.__vow_init (evalmachine.<anonymous>:1331:3)
    at buildBemXjst (evalmachine.<anonymous>:1335:12)
    at evalmachine.<anonymous>:1603:25
    at evalmachine.<anonymous>:1605:3
    at Object.exports.runInContext (vm.js:44:17)
    at /home/rustam/work/newkent/desktop.blocks/server/server.node.js:18:5
    at pendingRequires.push.cb (/home/rustam/work/newkent/desktop.bundles/index/index.node.js:88:32)
    at onDeclResolved (/home/rustam/work/newkent/desktop.bundles/index/index.node.js:175:29)

Добрый день! Извините за дилетантский вопрос. Подскажите, пожалуйста (или подскажите, где посмотреть), как вывести повторяющиеся элементы блока (см. код).

Необходимо в блоке вывести один раз title и три раза пару элементов year и university.

На странице должно быть так:

ОБРАЗОВАНИЕ 2000 - институт 1999 - институт 1998 - институт

Если добавить элементы, например, так:

sections: [
    {
        title: 'ОБРАЗОВАНИЕ',
        year: '2000 — ',
        university: 'институт',
        year: '1999 — ',
        university: 'институт',
        year: '1998 — ',
        university: 'институт'  
    }
]

выводится только последняя пара year и university.

index.bemjson.js:

//...
content: [
        { block : 'name',
          content : 'имя'
           },

        {
            block: 'sections',
            sections: [
                {
                    title: 'ОБРАЗОВАНИЕ',
                    year: '2000 — ',
                    university: 'институт'
                }
            ]
        }
        ]
//...

sections.bemhtml:

block('sections')(

    tag()('div'),

    content()(function() {
        return this.ctx.sections.map(function(item){
            return [
                {
                    elem: 'item',
                    content: [
                        {
                            elem: 'title',
                            content: item.title
                        },
                        {
                            elem: 'year',
                            content: item.year
                        },
                        {
                            elem: 'university',
                            content: item.university
                        }
                    ]
                },
                ' '
            ];

        });

    }),


    elem('item')(
        tag()('div')
    ),

    elem('title')(
        tag()('h3')
    ),

    elem('year')(
        tag()('span')
    ),

    elem('university')(
        tag()('span')
    )
);

Если используется централизованное получение данных с бекенда, в чем преимущества использования bemtree по сравнению с прямым формированием полного дерева bemjson бекендом?

В приложении типа чат есть два списка: список общих комнат и список приватных бесед. Реализовал их блоком list с соответствующим модификатором type.

Задача: реализовать выбор одного элемента из списка. Проблема: каждый инстанс блока list запоминает свой активный элемент списка.

// При клике на элемент списка ставлю соответствующий модификатор
_onItemClick : function (e) {
    var item = $(e.currentTarget);
    var type = this.getMod(item, 'type');

    this.setMod(item, 'current', true);
}

// При выставлении модификатора новому элементу, удаляю модификатор у предыдущего
onElemSetMod : {
    'item' : {
        'current' : {
            'true' : function (elem) {
                this.delMod(this._current, 'current');
                this._current = elem;
            }
        }
    }
}

Как грамотнее всего реализовать, чтобы при выборе одного элемента удалялся модификатор не только в текущем инстансе блока, а во всех списках?

Так же интересует насколько правильной является реализация "оборачивания" всех элементов списка в контейнер с помощью создания нового элемента container

// BEMJSON
{
    block: 'list',
    mods: { 'type' : 'channels' },
    content: [
        { elem: 'title', content: 'Каналы' },
        { elem: 'container' }
    ]
}

// BEMHTML
block('list').elem('container').tag()('ul');

// JS-реализация загрузки данных в список
_getListData : function (type) {
    var container = this.elem('container');

    API.get('channels.list', { type: type }).then(function (data) {
        var channels = data.channels;

        channels.forEach(function (channel) {
            BEMDOM.append(container,
                BEMHTML.apply({
                    block : 'list',
                    elem : 'item',
                    mods : { type : type },
                    content : channel.name,
                    js : {
                        id : channel.id,
                        name : channel.name
                    }
                })
            );
        });
    });
}

Спасибо!

С удовольствием посмотрел запись выступления Владимира :). Для себя услышал одну очень простую, казалось бы, фразу, но упрощающую очень сильно понимание bemhtml.

До этого я пытался с ним работать, но выбор пал на сторону bh.

А вот вчера вечером, смотря запись услышал: "Это то же самое, что CSS". @tadatuta показал как они похожи и по какой логике работает bemhtml. После этого у меня прояснилось в голове и появилось желание использовать именно данный шаблонизатор.

Спасибо за удачное сравнение :) Мне его не хватало.

А я могу, каким-то образом получить bemjson, который соотвествует финальной верстке BEMHTML ?

т.е. например из

{
  block: 'widgets',
  content: [
    {
      elem: 'weather',
      content: 4
    }
  ]
}

вот это

{
  block: 'widgets',
  tag:"div",
  attrs: {
     class: "widgets i-bem",
     "data-bem": '{ "weather": { "id": 4321 } }'
  },
  content: [
    {
      elem: 'weather',  
      tag:"span",
      attrs: {
        class:"widgets__weather"
      },
      content: 4
    }
  ]
}
block('kg-appbar')(
    js()(true),
    tag()('header'),
    elem('title').tag()('h1'),
    elem('panel')(
        tag()('nav'),
        def()(function(){
            return applyCtx({
                elem: 'placeholder',
                content: this.ctx
            });
        })
    )
);

с 2.6.0 работало. после обновления:

RangeError: Maximum call stack size exceeded
    at applyc (bundle.js:443)
    at __$b37 (bundle.js:3822)
    at __$g0 (bundle.js:4875)
    at applyc (bundle.js:460)
    at __$b89 (bundle.js:4225)
    at applyc (bundle.js:573)
    at __$b19 (bundle.js:3333)
    at __$g0 (bundle.js:4688)
    at applyc (bundle.js:460)
    at __$b89 (bundle.js:4225)

I: Подскажите пожалуйста, указанный здесь https://ru.bem.info/technology/bemhtml/v2/rationale/#Примеры-3 код шаблона (шаблона ли?), в каком файле он должен содержаться? Вроде как это относится к файлам *.bemhtml, но при сборке выдаётся Unexpected identifier. Да и до этого, в других примерах ( https://ru.bem.info/technology/bemhtml/v2/intro/#template ) синтаксис шаблона другой. Воспроизвести этот пример с указанным кодом так и не удалось. II: Из того, на что наткнулся, пока разбирался с вашей методологией: 1) Если какой-либо из ИМЯБЛОКА.js файлов написан с ошибкой ( с ошибкой синтаксиса, пробовал, например вставить туда приведённый выше код примера), то для всех блоков перестаёт работать инициализация, т.е. блоку не добавляется класс ИМЯБЛОКА_js_inited. Это нормальная логика? При этом, запущенный командой npm start, сервер никакой ошибки не выдаёт. 2) https://ru.bem.info/tutorials/start-with-project-stub/#bemhtml-шаблоны код примера блока BEMHTML шаблона для блока goods прямо очень сильно расходится с тем, что написано в разделе.

после установки проекта через generator-bem-stub возникают проблемы с добавлением технологии bemhtml при создании блока

как добавить meta теги в шаблон page?

Доброго времени!

Для создания проекта использовал «yo bem-stub». Выбранные основные технологии: bemtree, bemjson, bh. Выбранные уровни переопределения: desktop, touch-pad, touch-phone. Сборщик — ENB.

Как при описании блока «page», например, в «desktop.bundles/index/index.bemjson.js» не указывать параметр favicon, а использовать значение и ресурсы самого блока, переопределенного на уровне «common»?

Заранее спасибо за помощь!

Вот в этой ветке https://ru.bem.info/forum/-439/ @tadatuta сказал:

Кроме того, BEMTREE асинхронный, что позволяет во время выполнения шаблона сходить за данными

1) Сходить куда? Например в базу данных или к HTTP API? 2) Можно ли где-нибудь почитать код, примеры как это лучше применять на практике?

Привет всем!

Начинаю изучать БЭМ. Есть тестовый проект с одним блоком и одним элементом в нем. Пытаюсь собрать. Безуспешно, категорически не могу получить html. Хотя сборка вроде бы проходит без ошибок.

Структура проекта до сборки:

├── common.block
│.....└── b-head
│.............├── b-head.bemhtml
│.............├── b-head.css
│.............└── __title
│....................├── b-head__title.bemhtml
│....................└── b-head__title.css
└── pages.bundles
 ......└── index
 ..............└── index.bemjson.js

"Проект" принципиально сделан с нуля, без использования bem-components - чтобы понять как создаются блоки, как из bemhtml получается просто html, как собирается весь проект.

Контент файлов: ---------------- b-head.bemhtml -----------

block('b-head')(
   tag()('h1'),
   content()(
      {elem : 'title', content : 'Yo!'}
   ) 
)

-------------- b-head__title.bemhtml --------------

block('b-head').elem('title').tag()('i')

-------------- index.bemjson.js ----------------------

({
    block: 'b-head',
    content: [
        { elem: 'title', content: 'H' },
    ]
})

CSS пока не важно, больше ничего не трогал. (код выложен на https://bitbucket.org/shbma/codepr-6_bem3)

Сборку выполняю по инструкции https://ru.bem.info/tools/bem/bem-tools/commands/

команда: bem create -l pages.bundles -b index -T bemdecl.js результат: успешно cоздается файл декларации pages.bundles/index/index.bemdecl.js

команда: bem create -l common.block -b b-head -T bemdecl.js результат: успешно создался файл декларации common.block/b-head/b-head.bemdecl.js

команда: bem build -l common.block -l pages.bandles -d pages.bundles/index/index.bemdecl.js -t deps.js -o pages.bundles/index -n index результат: успешно создался файл зависимостей pages.bundles/index/index.deps.js

команда: bem build -l common.block -l pages.bandles -d pages.bundles/index/index.deps.js -t css -o pages.bundles/index -n index результат: создался файл импорта стилей pages.bundles/index/index.css

команда: bem make результат:

22:56:32.837 - info: bem 0.9.0
22:56:33.082 - info: Graph:
== root
 all
   build
     pages.bundles*

22:56:33.090 - info: [i] Going to build 'all' [1]
22:56:33.108 - info: [t] isValid() time for "build" [1]: 1ms
22:56:33.108 - info: [*] make 'build' [1]
22:56:33.108 - info: [t] Build time for "build" [1]: 1ms
22:56:33.109 - info: [t] isValid() time for "all" [1]: 0ms
22:56:33.109 - info: [*] make 'all' [1]
22:56:33.110 - info: [t] Build time for "all" [1]: 1ms
22:56:33.111 - info: [t] Build total: 270ms

ничего не произошло - html файлов не появилось

Пробуем по-другому:

команда: bem server результат:

23:00:52.405 - info: bem 0.9.0
23:00:52.412 - info: Project root is '/home/michael/code-production/les6_bem/bem-tools-test'
23:00:52.658 - info: Graph:
== root
 all
   build
     pages.bundles*

23:00:52.668 - info: Server is listening on port 8080. Point your browser to http://localhost:8080/

На запрос http://localhost:8080/index.html отдает 404 ошибку, в консоли пишет

warn: *** HTTP error: 404, /home/michael/code-production/les6_bem/bem-tools-test/index.html

И опять-таки никаких html-файлов внутри папок проекта не образуется

Есть какие-то варианты решения проблемы?

P.S. Извиняюсь, если этот пост покажется очевидной банальностью тому, кто в теме. В БЭМ я чайник, шерстю сайт, есть отличные вебинары по сборке css и js, теория по синтаксису bemhtml (правда не нашел ничего по сборке таких вот нано-проектов), но в моей голове мозаика материалов пока не складывается. Я уперся лбом в стену и не понимаю куда копать, потому и задаю сюда вопросы.

Собственно как выполнить в блоке несколько шаблонов? т.е по одним и тем же входным данным генерятся 2 разных блока.

Проблема следующая есть блоки

{
    block: 'form-input',
    name: 'user',
}

Как все понимают элемент формы input, и есть блок

{
    block: 'form-input',
    name: 'tel',
    js: true,
    mods: {type: 'tel'},
    maxlength: '13'
}

Блок с модификатором, проблема с шаблоном, сейчас у него изменился шаблон относительно других inputов, я заюзал новый шаблон, но проблема в том что при сборке этот блок собирается сначала без модификатора потом с модификатором, получается вложенность. Как избежать подобной проблемы?

block('form-input')(
    //code
);

block('form-input').mod('type', 'tel')(
  //code
);

Например у меня есть блок Thing

block("thing")(
  attrs()({
    "itemscope": "",
    "itemtype": "http://schema.org/Thing"
  })
);

И я хочу чтоб блок Product наследовался от Thing

block("product")(
  attrs()({
    "itemtype": "http://schema.org/Product"
  })
);

и на выходе получал: <div class="product thing" itemscope itemtype="http://schema.org/Product"></div> Возможно ли такое?

Безопасно ли собирать bem-core и bem-components технологиями deps и bemhtml вместо deps-old и bemhtml-old соответственно?

Мне нужно изменить базовый блок page следующим образом при навешивании модификатора sticky-push контент оборачивался оберткой добавлялся блок под контентом и подключался блок футера после данного контейнера

block('page').mod('sticky-push', true)(
    def()(function(){
        return applyCtx([
            {
                block: 'page-sticky-footer',
                content: [
                    {
                        tag: '',
                        content: this.ctx.content
                    },
                    {
                        block: 'sticky-push'
                    }
                ]
            },
            {
                block: 'footer'
            }
        ])
    })
);

Я написал следующий код, он не верен так как я юзаю this.ctx.content У меня естественно пропадают теги body и т/д

Существует ли способ обернуть элемент блока другим элементом внутри BEMHTML Имеем такой bem json

{
    elem: 'cancel',
    content: 'Отмена'
}

на выходе такой html div.form__cancel-wrapper>a.form__cancel Я вижу решение подключения elem: 'cancel-wrapper' и внутри его шаблона подключить другой элемент и тогда все ок. Но хотелось бы не знать о существовании такой обертки, когда пишется элемент, чтобы его шаблон оборачивал. Есть ли решение этой проблемы?

Добрый день интересует возможность сделать escapeHtml на уровне шаблонизатора bemhtml, Проблема в том что когда шаблонизатор получает в качестве контента другой блок, он принимает объект а не результат исполнения шаблона входного блока. Задача имея такой bemjson

{
 block: 'prism',
 language : 'markup',
 content: {
   block: 'content',
   elem: 'title',
   сontent:'Заголовок content__title размер ssбез модификаторов'
 }
}

Получить за escape html Вот мой bemhtml

block('prism')(
    tag()('pre'),
    content()(function(){
            var text = this.ctx.content + '';

            return {
                tag: 'code',
                attr: {'data-language': this.ctx.language},
                cls: 'language-' + this.ctx.language,
                content: this.attrEscape(this.ctx.content)
            }
        }
    )
)

Как правильно можно получить результат исполнения шаблона блока внутри другого блока. В документации нашел applyCtx но опять же получаю объект. Извиняюсь за стиль кода, не нашел как его оформить в вашем редакторе.

Добрый день. Разбираюсь с БЭМом. Предположим, я реализовал блок label, использую его в технологии BEMJSON, по нему формируется HTML через BEMHTML, привязывается js, все хорошо. Встала задача динамически создавать блок label на уже отображенной странице по действиям пользователя.

Насколько я понимаю, мне необходимо сформировать HTML этого блока и проинициализировать его. что- то типа createLabel(parentBlock,params)

Как правильно реализовать эту возможность?

modules.define(
    'i-bem__dom',
    ['BEMTREE', 'BEMHTML', 'vow'],
    function(provide, BEMTREE, BEMHTML, Vow, BEMDOM) {
        provide(BEMDOM.decl(this.name, {}, {
            applyBemjson : function(bemjson, ctx, useBemtree) {
                var promise;
                if (useBemtree) {
                    promise = BEMTREE.apply(bemjson)
                } else {
                    var deferred = Vow.defer();
                    deferred.resolve(bemjson);
                    promise = deferred.promise();
                }

                return promise
                    .then(function(bemjson){
                        BEMDOM.update(ctx, BEMHTML.apply(bemjson));
                    })
            }
        }))
    });

Ок или что-то не так?

Собрал на bem статичную страницу, теперь нужно добавить динамику используя БД. Что читать? и хотел начать с простого - с блока select, нужно его заполнить данными из БД. Есть ли у блока backend часть?

Начал изучать expressjs хочу выкинуть jade и запихнуть bemtree + bh. Можете подсказать как это сделать? Смотрел видео и статью по sssr там более менее понятно, но мне хотелось бы не менять всю структуру серверной части под БЭМ, (иначе я в туториалах по express запутаюсь) а просто использовать его в качестве шаблонизатора.

<div class="people">
    <div class="people_container">
        <div class="people__avatar">No found</div>
        <div class="people__name">Chel Bez</div>
    </div>
</div>
{
  block: 'people',
  content: [
    { elem: 'avatar', content: 'No found'},
    { elem: 'name', content: 'Chel Bez'}
  ]
}

Возможно ли средствами BEMHTML сделать обертку div.people_container

Рома @sbmaxx запилил песочницу BEMHTML.

https://ru.bem.info/technology/bemhtml/v2/rationale/#data-bind

не до конца понял, почему knockout так выделили.. и что значит тогда data-bind? если live-data-bind описан как "отличается тем, что в шаблоне можно декларировать связь не со статическими, а изменяющимися данными", тогда наверно и angular стоит выделить также

В BH@4.0.0 добавили метод processBemJson возвращает стандартный BEMJSON.

Правильно хотеть делать специальные шаблоны *.bemtree.bh для блока, если блоку надо уметь делать денормализацию данных (формирование BEMJSON из сырых данных)?

Хочется разобраться теме bemtree/priv.js, понять каким образом применять и как правильно подойти к выбору реализации?

Ниже материалы и обсуждения по теме.

Материалы

@apsavin bemtree генерирует входные данные для bemhtml. данные от вашего сервера попадают в bemtree, на выходе получается bemjson bemjson попадает в bemhtml, на выходе получается html Есть альтернативные технологии, например, sbmaxx/bem-priv Переходите или на bemhtml + bemtree, или на bh + priv.js Реализация priv.js может быть очень разной, если не хотите пилить сами - выше ссылка на готовую. Сложнее переиспользовать блоки, если формат данных, который ним приходит, зашит прямо в шаблоны.

Похожие топики

Возможно ли допилить BEMHTML так, чтобы он вместо функции по генерации html строки, выдал функцию по генерации виртуального DOM дерева? Если это возможно, то в какую сторону нужно копать?