Giter Club home page Giter Club logo

bemto's Introduction

Bemto — mixins for writing BEM-style code for Pug Build Status NPM version

Table of Contents

  1. Install & Use

  2. Features

  3. Settings

  4. Using for building complex mixins

Install & Use

Cloning

  1. Clone bemto somewhere to your project:

    git clone git://github.com/kizu/bemto.git
  2. Include it in your .pug project:

    include bemto/bemto.pug
  3. Use it:

    +b.block1
      +e.element1 Foo
      +b.block2
        +e.A(href="#bar").element Bar
      +e.element2 Baz

    would render to something like

    <div class="block1">
      <div class="block1__element1">
        Foo
      </div>
      <div class="block2">
        <a class="block2__element" href="#bar">Bar</a>
      </div>
      <div class="block1__element2">
        Baz
      </div>
    </div>

Features

Blocks

“Block” is the main thing there. It creates the block from the first passed class and creates the context for all nested elements.

You can create block calling the b mixin with some class attached to it:

+b.foo bar

That would render as

<div class="foo">bar</div>

While the simple block's syntax, of course, is harder than the simple Pug's tags, the main point is to create the contexts for elements.

Elements

“Element” is a accessory element of the block. You can read on the concept of the elements in the bem methodology, or in the great article by Nicolas Gallagher (see the “Structured class names” part). Elements often are written using the block's name plus element's name with some separator (often __ or -) in-between.

Bemto gives a convenient way to declare the elements: just use the e mixin inside any block context:

+b.foo
  +e.bar baz

This would render like

<div class="foo">
  <div class="foo__bar">baz</div>
</div>

Context of the element

Note that bemto uses the first classname of the block as a context for further elements. If you'd like to use another class without changing the order, you can mark it with __ in the end:

+b.foo.bar__
  +e.baz

This way instead of foo bemto would base the nested elements from the bar:

<div class="foo bar">
  <div class="bar__baz">
  </div>
</div>

Modifiers

“Modifier” is a state of the block or element. It is often written with the addition of it's type and/or value after the single underscore like block_mode_foo or just block_foo. However, at the most cases, the block must contain either the original block/element's class, either the modifier class.

Bemto makes it easy to write such modifiers, 'cause you don't need now to write the same block's name twice:

+b.block_foo bar

Becomes

<div class="block block_foo">bar</div>

See? You write just .block_foo but by fact get the .block.block_foo instead!

But what if you need to have more than one modifier on one block or element? Bemto have a way to do so: add a class to your block or element starting with a modifier token:

+b.block_foo._bar._baz
  +e.element_type_lol._mode_moddy Blah

and that would render as

<div class="block block_foo block_bar block_baz">
  <div class="block__element block__element_type_lol block__element_mode_moddy">
    Blah
  </div>
</div>

You can also use shorter modifier syntax like class="block -modifier" (but only when this syntax won't be used for delimiting full modifiers or elements).

+b.-foo.-bar.-baz

this would render to

<div class="block -foo -bar -baz">
</div>

Changing the tag name

By default the blocks and elements render as divs. You can change it by passing the desired tag name as the first class in uppercase:

+b.SPAN.foo bar

Or by passing an options object with a tag param:

+b({tag: 'span'})foo bar

Either way would render as

<span class="foo">bar</span>

Attributes

Like any Pug tag or mixin, blocks and elements can take attributes that would go to the desired tags:

+b.foo(title="Oh, it's a title")
  +e.A.bar(href='#baz') baz

would render like

<div class="foo" title="Oh, it's a title">
  <a class="foo__bar" href="#baz">baz</a>
</div>

Automatic attributes

There are some tags like img that must have at least one attribute set. Bemto would create attributes with some predefined values for such tags. So, for images this code — +b.image(src="foo.png") would render <img alt="" class="image" src="foo.png"/> — you can see that in that case there is the added empty alt.

Also, in some cases there is a need to adjust some attributes according to other ones. For img if the alt is set, but the title is not we'd need to set it to empty, 'cause there'd be a inconsistency between browsers (IE would show the title bubble for alt). And from the other side, if there is only title set in an image, we'd need to clone it to alt. Bemto do all those things.

Context

Look at the previous example: you have there some excess code that you can throw away. It's the ('a') part — as long as you set the href attribute, the block would automagically become the link. Also, there are other tags that you can omit: li in ul or ol context, or span in any already inline context.

So, here is a bigger example:

+b.UL.list
  +b.list-item
    +e.link(href="foo")
      +e.text foo
  +b.list-item
    +e.link(href="bar")
      +e.text bar

Would render to

<ul class="list">
  <li class="list-item">
    <a class="list-item__link" href="foo">
      <span class="list-item__text">foo</span>
    </a>
  </li>
  <li class="list-item">
    <a class="list-item__link" href="bar">
      <span class="list-item__text">bar</span>
    </a>
  </li>
</ul>

For now that's all, but there would be other contexts in the future of bemto.

Redefining tag's metadata

In a case you'd like some tag to set a different context, i.e. to override it's content_type, you can use a metadata option for the block/element. For example, if you'd like a link to have block context, you can redefine it in this way:

+b({ metadata: { content_type: 'block' } }).A.foo
  +e.bar

would render as

<a class="foo">
<div class="foo__bar">baz
</div></a>

Settings

There are some settings you can set for different syntaxes of BEM.

For doing so, you must set them after including the bemto like this:

-
  set_bemto_settings({
    prefix: '',
    element: '__',
    modifier: '_'
  })

Here you can see all available settings with their default values.

Adding Prefix

If you'd like to prefix all your bemto-generated blocks, you can set the prefix setting to a String or an Object.

Strings for prefix setting

If you'd set a string, it would be just prepended to the names of all blocks:

- set_bemto_settings({ prefix: 'b-' })

+b.block
  +e.element foo

and that would then render as

<div class="b-block">
  <div class="b-block__element">
    foo
  </div>
</div>

Note that if you had already used this prefix in a classname, it won't be added, so you won't have occasional duplicated prefixes.

Objects for prefix setting

If you'd want to have more control over prefixes, you can use a special object instead of a string:

-
  set_bemto_settings({
    prefix: {
      '': 'b-',
      'js-': true,
      'is-': 'is-',
      'global-': '',
      'nope-': false,
      'sc-': 'shortcut-'
    }
  })

Look at the above example, it have all the variations the prefix object accepts:

  • The empty string for key works the same as a string setting: you'd get the value for this key prepended for all classnames without detected prefixes.

  • If a value for any key is true, this prefix would be always treated as such and won't be prepended by other prefixes.

  • If a value for a key is false or an empty string, the classnames with this prefix would be rendered without it.

  • In other cases, where the key and the value are both strings, all the key prefixes in the source code would be replaced with the value ones, and also all of those prefixes would be treated as registered ones, so you wouldn't add other prefixes for them.

Setting for Element syntax

If you don't like the default elements syntax with the __ delimiter, you can set using the element setting:

- set_bemto_settings({ element: '-' })

+b.block
  +e.element foo

this would render to

<div class="block">
  <div class="block-element">
    foo
  </div>
</div>

Setting for Modifier syntax

If you'd like to use different modifier syntax, like the one Nicolas Gallagher mentioned in his article, you can use the modifier setting:

- set_bemto_settings({ modifier: '--' })

+b.block--modifier-name.--other-modifier foo

and that would expand to

<div class="block block--modifier-name block--other-modifier">
  foo
</div>

Setting for allowing nested elements

There can be cases when you could want to make elements of elements, i.e. when using element names instead of block names:

+b.block-element
  +e.element2

renders by default to

<div class="foo__bar">
  <div class="foo__baz">
  </div>
</div>

If you'd like to have foo__bar__baz in the output instead, you can set the flat_elements to false:

- set_bemto_settings({ flat_elements: false })

+b.foo__bar
  +e.baz

This would render with the nested element:

<div class="foo__bar">
  <div class="foo__bar__baz">
  </div>
</div>

Scope for the settings

If you'll need to have some settings just in a certain scope, you can wrap your code in bemto_scope mixin, passing your desired settings right into it:

+b.foo_bar
  +bemto_scope({
      prefix: 'b-',
      element: '-',
      modifier: '--'
    })
    +b.nnnn
      +e.mmmm--kkkk
  +e.baz

Would render as

<div class="foo foo_bar">
  <div class="b-nnnn">
    <div class="b-nnnn-mmmm b-nnnn-mmmm--kkkk">
    </div>
  </div>
  <div class="foo__baz">
  </div>
</div>

Setting for the output syntax of the elements/modifiers

If you'd like to use different syntax of the element/modifier delimiter in Pug source and the html output, you can use the ouput_element and output_modifier settings, otherwise the same delimiter as in the element and modifier settings would be used.

-
  set_bemto_settings({
    element: '-',
    modifier: '--',
    output_element: '__',
    output_modifier: '_'
  })

+b.block.block2-
  +e.element--modifier foo

would output

<div class="block block2">
  <div class="block2__element block2__element_modifier">foo
  </div>
</div>

You can see how the source uses the - for element and -- for modifier, but the result gets __ and _ instead.

Setting for delimiters between classnames

If you'd like to have extra delimieters between the rendered classnames for clarity, you can use a class_delimiter setting:

- set_bemto_settings({ class_delimiter: '|' })

+b.foo.bar_baz

Would be rendered as

<div class="foo | bar | bar_baz">
</div>

Note that there would be always added spaces around the given delimiter, so you don't need to include them in the setting's value.

Using for building complex mixins

This is somewhat obvious, but I must mention that the bemto blocks would be great for using as the bricks for building more complex blocks. The Pug mixins work in the way where you can translate any attributes through to the any inner blocks. So you can do this:

mixin link(url)
  +b.SPAN.link(href=url)&attributes(attributes)
    block

And then use it in this way:

+link('#Foo') Foo

+link('https://github.com')._external Github

+link('http://kizu.ru').url(rel="me") Here I am

+link Ah, I'm not a link

+link('https://github.com')
  +e.icon(src="http://favicon.yandex.net/favicon/github.com")
  +e.text Github

And that would render to

<a class="link" href="#Foo">Foo</a>

<a class="link link_external" href="https://github.com">Github</a>

<a class="link url" href="http://kizu.ru" rel="me">Here I am</a>

<span class="link">Ah, I'm not a link</span>

<a class="link" href="https://github.com">
  <img alt="" role="presentation" class="link__icon" src="http://favicon.yandex.net/favicon/github.com"/>
  <span class="link__text">Github</span>
</a>

There you can see almost all of the bemto features that can be used for any mixin with attributes variable attached to any inner bemto block inside of it.


To be continued!

If you'd like to follow on the bemto progress, follow me on twitter.


Copyright (c) 2012 Roman Komarov [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

bemto's People

Contributors

bivihoba avatar igoradamenko avatar jonscottclark avatar kandrianov avatar kinday avatar kizu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bemto's Issues

Move all the taggy stuff to something like `tag.jade`

A lot of things that are there used for bem stuff could be made so they would be useful for Jade overall, and bemto then could just reuse it.

All the current helpers with defaults and inline/block lists could be moved there, there could be also helpers for tables etc.

I'm not sure if this should be a stand-alone project, or it could be just a part of bemto.

Creating wrapper tags for some contexts

If you have an ul and then some a(href) right in it, it would be nice to create the li wrapping the a.

The same thing can go to the all the table-tr-td… stufff.

Code style settings

We need at least those settings for bemto:

  1. done Prefix setting, empty by default (need this to make b- prefixes)
  2. done Element syntax (__ by default, can be - etc.)
  3. done Modifier syntax (_ by default, can be -- etc.)
  4. Strict full modifier syntax (false by default, make _hidden_hidden from _hidden if true)
  5. ???

Modifier expanding

+b.block_mode

must be equal to

+b.block.block_mode

, and

+b.block_mode._other_mode

must be equal to

+b.block.block_mode.block_other_mode

Proper order of classes, part 2

In #9 there was a rather straightforward way of doing the task, we should try to use the order from the source when possible although.

Unwanted whitespace

Seems there is always a new line before the end tag. Can we remove it?

+b.foo bar
+b.foo
    +e.bar
        | baz
p
    +b('span').foo bar

converts to:

<div class="foo">bar|
</div>
<div class="foo">
    <div class="foo__bar">baz|
    </div>
</div>
<p><span class="foo">bar</span>|
</p>

Jade works a bit different without bemto (expected result)

<div class="foo">bar|</div>
<div class="foo">
    <div class="bar">baz|</div>
</div>
<p><span class="foo">bar</span>|</p>

Allow mixing of multiple blocks/elements on one tag

Proposed syntax:

+b.mediaList
  +b(['entity', '__item', 'media__'])

Note that the leading element delimiter marks the element and the ending one is marking the context for the nested entities. If there is no context marked, the first block would get it.

Add some smart mixing

Right now it's not that easy to mix blocks. It would be nice to have a way to somehow declare mixings of blocks or elements in a way where all the bemto features would work for everyone.

Bug with `extends`

extends layout-site

include bemto/bemto

block content
  .content
    .user-projects
    +b.block_foo bar
TypeError: /Users/antonshuvalov/Desktop/markup-UP/views/index.jade:141


Object block_foo has no method 'split'
    at Object.b_mixin (eval at <anonymous> (/Users/antonshuvalov/Desktop/markup-UP/node_modules/jade/lib/jade.js:152:8), <anonymous>:36:38)

Multiple modifiers not added properly when certain separators defined

Hey @kizu,

First, thanks for your mixin. It's really made the transition to BEM syntax a lot easier.

I am using these settings:

- bemto_settings_prefix = ''
- bemto_settings_element = '-'
- bemto_settings_modifier = '--'

I try your example, changing the syntax to match my settings:

+b.block--foo.--bar.--baz
  +e.element--type_lol.--mode_moddy

But it renders like this:

<div class="block block--bar block--baz block--foo">
  <div class="block--mode_moddy block-element block-element--type_lol">
</div>

As you can see, the "mode_moddy" modifier class is being added as a modifier of the parent block, I think because the mixin sees the first "-" character, and then uses the rest of the string ("-mode_moddy") as an element name, placing it first in the class list.

If I change my element separator to two underscores, like so: - bemto_settings_element = '__', and then run the test again, it returns as expected:

<div class="block block--bar block--baz block--foo">
  <div class="block__element block__element--mode_moddy block__element--type_lol">
</div>

I guess the problem is that I am only using hyphens in my separator settings. While this isn't the official BEM syntax, a few people suggest using a syntax with just hyphens, like I'm trying to do:

I'm not able to diagnose where in the mixin I should look to get this working.. likely in some regex somewhere.. but I figured I should bring it to your attention in case there is an easy fix to allow some more flexibility with the separator options.

Auto names for elements based on blocks

Sometimes we could add names for different elements based on parent block names. It would be especially helpful for lists, so (with addition of #23):

+b.list
  +e foo
  +e bar

would be rendered as

+b('ul').list
  +e('li').item foo
  +e('li').item bar

(basically — if the element is a list item and is unnamed — name it as item etc.)

Setting for allowing nested elements

Moved from #4

Right now the elements don't create the block scope, however there are a lot of people who use it this way, so we could add an ability to do so.

Also, there'd be a need to “jump” higher to blocks etc. by adding more element delimiters at the start.

Attributes context checks - problematic when using "type" attribute with <button>

Hey kizu,

I'm creating an element with +e('button') but I need it to be type='reset'. Unfortunately, at the top of bemto there's an "Attributes context checks" area which forces the element to be an <input> if there's a type attribute. <button>s can also have type='button' or type='submit', both of which are also valid attribute values for <input> elements, so maybe these checks (or just the one for the type attribute) should be removed (because they seem very prescriptive). I'll leave it to you, wanted to let you know the situation I ran into :)

Cannot use template inheritance when using bemto

Tag 'block' causes exception with stack from bemto mixin calls.

  throw err;
        ^
ReferenceError: blocks/b-site-menu/b-site-menu.jade:5
    3|         small {{ stats.bookmarks_count }}
    4|         block menu_bookmarks
  > 5|             a(href='{% url bookmarks_latest %}') {% trans 'Bookmarks' %}
    6|     li.users
    7|         small {{ stats.people_count }}
    8|         block menu_people

block is not defined
    at b_mixin.call.block.e_mixin.call.block.e_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at b_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at bemto_tag_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at Object.bemto_tag_mixin (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at Object.b_mixin (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at Object.e_mixin (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at b_mixin.call.block.e_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at b_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at bemto_tag_mixin.call.block (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))
    at Object.bemto_tag_mixin (eval at  (/home/serzhit/bobrmongo/bem/node_modules/jade/lib/jade.js:176:8))

Add snippets to the `tag` argument

Right now the bemto block can accept only one argument — the tag name.

What if it could contain not just the tag name, but something like simple zen html snippet? So we could do, for example, +b('input:text').input and get the <input type="text"/> etc.

Add setting for strict full modifier syntax

Moved from #4 — we can have it false by default, but when it would be true, then we would make _hidden_hidden from _hidden.

However, do we need it to be _hidden_hidden, _hidden_true, or anything else? Nice place for another setting here.

Elements?

That would be hard.

The point is to use either

+b.block
  +e.element

or

+b.block
  +b.__element

However, right now I can't see how to do this in raw Jade. Maybe there'd be a need in some context variable. Maybe we'd need to patch the Jade a bit for this.

Tag name / attributes conflict

There is a question: should the attribute tweaking get priority over the tag name?

So if there is this: +b('span').foo(href="bar"), then should it be <span class="foo" href="bar"> or <a class="foo" href="bar">.

Should there be a setting to set this or some other syntax, so we could control it?

Button with type=button doesn't compile correctly

Code:

include bemto/bemto

+b.block
  +e('button').element(
    type='button'
  ) test

Expected result:

<div class="block">
  <button type="button" class="block__element">test</button>
</div>

Actual result:

<div class="block">
  <input type="button" class="block__element"/>
</div>

Other output methods?

There could be other output methods — like bemjson etc, Jade could be nice not only for outputting html, but also as a layer between data in nice indented format and any desired output. So, need to experiment on this.

Link the inputs with wrapping labels

While all modern browsers support the inputs in labels, IE still can't understand them.

So there is often a need in using the for/id pairs, and that's the place where bemto can help: you could write the id only in for and the first nested input would get the corresponding ID if possible.

Templating based on block/element names?

Is it possible to add a way to declare templates based on block/elements' names and modifiers?

Jade already have a way to call mixins using an interpolation:

+#{'b'}.block
  +#{'e'}.element

Would this be enough to allow defining custom templates, so things like this:

mixin bemto_block()
  +b.block-wrapper
    +b.block
      +b.element
        block

+b.block
  = "Whatever"

would be treated as:

+b.block-wrapper
  +b.block
    +b.element
      = "Whatever"

One of the problems is how to stop it being recursive, when the +b.block can be used inside bemto_block mixin?

<button type="submit"> becomes an <input>

There is code in tool:

  if attributes.type
    - newTag = 'input';

There are situation, when button must have type=submit attribute. But i getting <input>, which breaks me view.

Uncorrect element classname when custom tag used (milestone:1.0.0)

Classname for element generated incorrectly if we set custom tag for block or element.
Example:

+b.section
  +e('figure').ill

Expected Results:

<div class="b-section">
  <figure class="b-section__ill">
  </figure>
</div>

Actual Results:

<div class="b-section">
  <figure class="b-ill">
  </figure>
</div>

Add tests

There are already a lot of functions in bemto, and a lot of them can be somewhat conflicting. Adding more functions or changes to the existing ones can be harsh now: I need to be sure that nothing is broken.

So. We need tests. As Jade uses Mocha, it would be nice to use it there too.

Base for mixins

Something like

mixin b
  div(attributes)
    block

+b.block some block

etc., with prefixing, handling of classes etc. Btw, is there the tag interpolation in jade?

Buggy indentation

Tried to include foot.jade inside index.jade, got a strange Bemto indentation.

index.jade:

body
    .header
        | etc

    include includes/foot

foot.jade:

.footer.clear
    .element Text

+b.footer.clear
    +e.element Text

Result:

<body>
    <div class="header">etc</div>
    <div class="footer clear">
        <div class="element">Text</div>
    </div>
    |   |   <div class="footer clear">
                |   |   |   <div class="footer__element">Text
                            </div>
            </div>
</body>

There is recursive unwanted indentation for +b.footer.wide, which is inside foot.jade.
Two overhead tabs added for itself, 4 for the child (3+1) and so on.

Hope it may be fixed.

Jade blocks inside bem block mixin

При использовании блоков джэйда внутри подобной конструкции исполнение прекращается с ошибкой "block is not defined"

+b('header').header
  +e.layout
    +e('h1').logo
      block logo
        a(href="/")

Вне этой конструкции block logo работает правильно

Похоже недоглядел и создал дублирующее сообщение. #25

Bemto lost js context when using extends

Create a layout file:

block header
  di-panel-header(
  close-callback="details.closeDetails()"
  title="{{ details.selectedEvent.st + details.selectedEvent.loc_tzs | timeUTC:{format: 'ddd, DD MMM, HH:mm'} }}"
  )

block body
  +b.event-details.scroll-area
    .scroll-area__helper.scroll-area__helper--venue-details

Create a view wich extends a layout:

extends ./layout.jade

append body
  di-point-header(point="selectedEvent.getPointInfo()")

  +b.point-details(ng-if="selectedEvent.description")
    +e.row.--column.--contacts
      +e('h4').caption Описание встречи

      +e.misc-info.--location
        span(ng-bind="selectedEvent.description")

  di-place-info(point="selectedEvent.getPointInfo()")

And get the error:

    168|
    169|     if !isElement
  > 170|       - bemto_chain[bemto_chain.length] = bemto_block
    171|       - bemto_classes[0] = bemto_classes[0]
    172|     else
    173|       - bemto_classes[0] = bemto_chain[bemto_chain.length-1] + bemto_settings_element + bemto_classes[0]

Cannot read property 'length' of undefined

I tried to debug a little bit, and recognize that global variables bemto_chain and bemto_chain_contexts is undefined when error occurs.

Zero image gifs?

Do we need the way to insert the 1x1 transparent gif instead of an image? This can be useful in some cases, like using the sprites over the img elements with having the alt text fallback etc.

We could do it so if there is image with no src specified, then the src would get this image's src. However, I think that we surely would need to have a setting to determine this image's src, 'cause who knows where it would be?

Auto headings

We could ad ability to make automagically numbered headings, so we could look at the current sectioning structure (if it's made with the bemto blocks) and then create the appropriate heading tags h1-h6.

Edge cases with calling blocks/elements

There are some:

  • +b._lol — block starting with a modifier/element syntax.
  • +b — block without the class entirely.
  • +b._ — the block without actual modifier/element.

The same issues are there for element too.

Also, what should we do in all those cases?

Закрывающий слеш у input, img и т.п.

Можно ли как-то отключить вставку закрывающего тега для input, img и т.п. при использовании bemto?

Пример:

+b.form-item
    +e('input')
    input(type="text")

разворачивается в:

<div class="form-item">
    <input type="text"/>
    <input type="text">
</div>

New syntax suggestion

How about the new syntax.

Instead of:

+b.login-form
  +e('form').form(action="#")
    +e.line.header
      +e('h4').title Log in

Write:

.login-form(block)
  form.form(action="#")
    .line.header
      h4.title Log in

The point is that (block) attribute affects the elements below, so that all of them get BEM prefixes login-form (or modifiers according to bemto rules), just like if there's +e everywhere below.

The benefit: no need to prepend elements with +b/+e any more. Just normal jade with a small, but very tasty spoon of BEM-sugar.

The possible problem is that with such proposal every subelement will have the prefix by default.
So you can't insert just bare a. This could be worked around, if needed.

P.S. I can't find the exact rules of bemto transformations.
There is a "tutorial", but no list of strict rules in the docs.
I could reverse-engineer them from the source, but it could be so much better to just see them, to avoid any misunderstanding.

P.P.S. Before I get to the implementation, we should sort out possible non-trivial cases here, to come up with the new fresh cool flexible and yet no-pitfalls syntax.

P.P.P.S. Details of implementation: I will inherit a new parser from jade.Parser and modify AST. No ugly limited mixins. A CJS-module instead of bemto.jade.

Issues with prefixes

There can be a lot of issues with prefixes: we mustn't add prefix if it's already there, must allow use of other prefixes (how?) etc.

пробелы в textarea

Странным образом в textarea изначально присутствуют пробелы.

Something works wrong

    +b.test
        +b.account
            +e.field
                +b('label')(for="login") Email
            +e.field

is translating into:

<div class="test">
    <div class="account">
        <div class="account__field"><label for="login">Email</label></div>
        <div class="test__field"></div>
    </div>
</div>

As you can see second field element became test__field instead of expected account__field.

Function for setting default tag in scope

There are a few situations where some default tag can be used, like <p> or <section> and so on.

So, we could add either custom attribute to the tag to set (like (bemto-default-tag="p")), or a function/variable with this name.

Auto tags based on names

We could set tag names (if they're not defined) based on the block/element names.

For example, if we do +b.menu we treat it as +b('ul').menu by default.

If we have +b.header — make it +b('header').header.

The thing to think on — if there are names in modifiers, for example — what would have more priority? The modifier seems more appropriate for me — so +b.section_footer would give us +b('footer').section_footer

Can't use button tag with type attribute

The issue is that the input is an empty tag, and when we want to use some content inside button
we should to use a button tag,
but it is not possible to use button tag with a type attribute in bemto.
The reason to use type attribute is in case when we have many button in a form, and to
set button that is do submit we have to use type attribute (type=button and type=submit)

Clone `alt` for images if the `title` is not specified

If there is only alt defined with an image, we could clone it's content to the title attribute.

However, it's a thing to consider: it's not always needed and may be not needed in some cases, so — we should compare different cases first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.