bem / bh

BH template engine
http://bem.github.io/bh/
MIT License
68 stars 31 forks source link

BH is incompatible with BEMHTML #90

Closed isqua closed 9 years ago

isqua commented 10 years ago

I need to get some BEMJSON from BH layer and then compile it to HTML with BEMHTML. But BH process this structure:

{
    "block": "input",
    "mods": {
        "type": "textarea"
    },
    "content": [
        { "elem": "control" }
    ]
}

into this:

{
    "block": "input",
    "mods": {
        "type": "textarea"
    },
    "content": [
        {
            "elem": "control",
            "block": "input",
            "blockMods": {
                "type": "textarea"
            }
        }
    ],
    "blockMods": {
        "type": "textarea"
    }
}

And the fragment

{
    "elem": "control",
    "block": "input",
    "blockMods": {
        "type": "textarea"
    }
}

is parsed wrong with BEMHTML. If it was mods instead of blockMods, BEMHTML would work as I expected.

May be it is possible to add an option for this parameter? How could I solve the problem now?

mishanga commented 10 years ago

I'll do something about it on this week.

isqua commented 9 years ago

I’ve written small hack in my project: my script recursively traverses the tree and replace mods with elemMods on each elem node and blockMods with mods on each node. But there is a problem in some cases.

When mods property is defined on elem node, BEMHTML use these mods to build class name of the elem.

Source JSON:

{
    "block": "myblock",
    "mods": {
        "theme": "dark"
    },
    "content": [
      { "elem": "myelem" }
    ]
}

JSON after bh.processBemJson:

{
    "block": "myblock",
    "mods": {
        "theme": "dark"
    },
    "content": [
        {
            "elem": "myelem",
            "block": "myblock",
            "blockMods": {
                "theme": "dark"
            }
        }
    ],
    "blockMods": {
        "theme": "dark"
    }
}

JSON after the hack:

{
    "block": "myblock",
    "mods": {
        "dark": "dark"
    },
    "content": [
        {
            "elem": "myelem",
            "block": "myblock",
            "mods": {
                "theme": "dark"
            }
        }
    ]
}

So the result class of the elem is myblock__myelem myblock__myelem_theme_dark, but I expected only myblock__myelem. If I remove mods property from elem, BEMHTML templates for

block myblock, mod theme dark, elem myelem

don’t work. But if I remove mods and block properties, BEMHTML consider this condition. But it will cause problems with constructions like this:

{
    "block": "block1",
    "content": {
        "block": "block2",
        "content": {
            "block": "block1",
            "elem": "myelem"
        }
    }
}
an9eldust commented 9 years ago

Assuming the facts that:

  1. there might be much of inner fuzzy logic considering properties block and blockMods (source code around these is not pretty clear for me, my bad), and
  2. our use case is not about the way BH is meant to be used actually;

I would suggest just adding an additional flag (__addedBlock / __deleteBlock, don't really care) to the elem nodes which are populated with the block property. So, using the hack described above, we would tell, if the elem node had the block property originally, or the prop was added during processBemJson transformation.