bem / bem-core

BEM Core Library
https://ru.bem.info/technologies/classic/i-bem/
Other
276 stars 95 forks source link

Please explain how to use BEMHTML JS API directly (without bem-tools) #328

Closed dypsilon closed 10 years ago

dypsilon commented 10 years ago

I suppose it is possible to use BEMHTML dynamically, without using "bem make" or "bem server". There are a lot of BEMup talks on how to use BEMHTML dynamically with two factor view rendering and so on, but zero docs about how to set it up. Every bit of documentation starts with "clone the project stub". Which leaves me with lot's of configuration files I don't understand and probably don't want to. (what does this file do? no idea...)

Please describe how to use the JavaScript API for BEMHTML. All I want to do is provide the BEMHTML engine with BEMJSON and a template and get an HTML output. Probably with a compiled XJST template inbetween or whatever the workflow is.

What I do not want is learning how to setup bem-tools with all it's adjacent configs, declarations and commands. As far as I'm concerned I don't want to touch bem-tools at all, but instead run everything through an express server or something like that. According to several talks some Yandex teams are doing it.

I tried to reverse engineer bem-tools to find out how BEMHTML gets called in the make process, but bem-tools is huge, complicated and in flux. That said, all the other BEMHTML docs are excellent and @veged does a great job explaining how it works.

SevInf commented 10 years ago

bem-xjst package can be used to compile bemhtml templates without bem-tools. Readme has a usage example. Also, you can pre-compile your templates using bem-xjst cli and require compiled templates as usual node module.

In command line:

bem-xjst -i template.bemhtml -o output.bemhtml.js

In your code:

var tpl = require('./output.bemhtml.js');
tpl.apply({block: 'my-block'});

BTW, bem-tools has no code using bemhtml . All such code is here, in own tech module.

dypsilon commented 10 years ago

Thank you for a fast response. Is it possible to use BEMHTML syntax directly with XJST?

SevInf commented 10 years ago

bem-xjst is the compiler for new, js syntax of bemhtml. While the doc on it is in progress, you can find a basic info on it here and see some examples here. If you still want to use old syntax, you can use bemhtml-compat to translate old syntax to the new.

dypsilon commented 10 years ago

Nice, the new syntax looks much better because it's native JS. I will look into it, thank you.

It's hard to adopt the full BEM stack right now because so many things are in flux.

dypsilon commented 10 years ago

I'm trying to render a template using your example above, but have no luck.

template.bemhtml

block('hello').tag()('span');

index.js

var tpl = require('./output.bemhtml.js');
var out = tpl.apply({block: 'hello', content: 'BEMHTML'});

console.log(out);

first I run bem-xjst binary on the console:

./node_modules/.bin/bem-xjst -i template.bemhtml -o output.bemhtml.js

The content of output.bemhtml.js is

var __$ref={};function apply(ctx){try{return applyc(ctx||this,__$ref)}catch(e){(ctx||this).xjstContext=e;throw e}}exports.apply=apply;function applyc(__$ctx,__$ref){if(__$ctx._mode==="tag"&&__$ctx.block==="hello"&&!__$ctx.elem){__$ctx.__$a=0;return"span"}__$ctx.__$a=0}[].forEach(function(fn){fn(exports,this)},{recordExtensions:function(ctx){}});

now the index.js

node .

The output is "undefined".

blond commented 10 years ago

Use base templates besides your own templates to obtain correct result.

For example, you can use base templates from bem-core. Insert code from i-bem.bemhtml to template.bemhtml and you see <span class="hello"></span> instead of undefined.

dypsilon commented 10 years ago

What does all this code do? Do I have to put it in each template? Is there no other way to use just the template engine? I don't need bem-core.

tadatuta commented 10 years ago

Well, you can think of that code as if it is engine itself (it's not quite so but still you need it to be included just once to get proper result).

It gives possibility not to write templetes by yourself at all: if you call BEMHTML.apply({ block: 'b1', content: { elem: 'e1' } }) you'll get <div class="b1"><div class="e1"></div></div> becouse basic templates "knows" how to render bemjson by default. And then you can add some more templates to redefine default behavior.

Offtopic: don't be afraid to use http://github.com/bem/project-stub with http://github.com/bem/bem-core/ inside — you won't get any extra code. bem-tools collect just declared in bemjson or deps.js entities (blocks, elements and modifiers) so nothing else will be built.

But if you are confident on not to involve build process into development you can try https://github.com/tadatuta/bem-precompiled which is prebuilt stub. Still you should understand that templates there are in dev mode.