Skip to content

Instantly share code, notes, and snippets.

@tadatuta
Last active December 25, 2015 17:49
Show Gist options
  • Save tadatuta/7016335 to your computer and use it in GitHub Desktop.
Save tadatuta/7016335 to your computer and use it in GitHub Desktop.
BEM-XJST синтаксис

BEM-XJST

Это БЭМ-ориентированные хелперы над стандартным XJST-синтаксисом. Сюда входит:

  • синтаксический сахар для подпредикатов про БЭМ предметную область
  • возможность писать вложенные шаблоны
  • синтаксический сахар для apply по какой-то mode (apply(this._mode = 'bla'))
  • ключевое слово applyCtx (синтаксический сахар для applyNext(this.ctx = { some: 'new' }))
Подпредикаты про БЭМ

В старом синтаксисе шаблон состоит из перечисления подпредикатов через запятую и тела после двоеточия:

block link, tag, this.ctx.url: 'a'

Есть такие типы подпредикатов: кастомные, про матчинг на входной BEMJSON и про моду (генерация результата).

Прийдётся ввести ключевое слово для кастомных подпредикатов -- match -- оно ведёт себя так же (почти, об этом ниже) как и template в XJST:

match(this.block === 'link', this._mode === 'tag', this.ctx.url)('a')

А ещё можно написать так (цепочкой вызовов):

match(this.block === 'link').match(this._mode === 'tag').match(this.ctx.url)('a')

Теперь для кастомных подпредикатов про БЭМ абсолютно логично пишется:

block('link').tag().match(this.ctx.url)('a')
block('link').mod('pseudo', 'yes').tag().match(this.ctx.url)('a')
Вложенные шаблоны

В старом синтаксисе можно писать шаблоны так:

block link {
    tag: 'a'
    attrs: { href: this.ctx.url }
}

и это просто способ не повторять два раза под предикат на блок, в конечном счёте это два шаблона:

block link, tag: 'a'
block link, attrs: { href: this.ctx.url }

Так можно группировать любые подпредикаты, в том числе кастомные:

this.block === 'link' {
    this._mode === 'tag': 'a'
    this._mode === 'attrs': { href: this.ctx.url }
}

Предлагается иметь такой синтаксис:

block('link')(
    tag()('a'),
    attrs()({ href: this.ctx.url })
)

Попутно мы получаем более красивую возможность вкладывать на один уровень тело и подшаблоны. То что раньше записывалось через подпредикат true:

this.ctx.url {
    true: 'a'
    mods not-link yes: 'span'
}

можно написать:

match(this.ctx.url)(
    'a',
    mods('not-link', 'yes')('span')
)

Вложенность естественным образом может быть любой глубины:

block('link')(
    tag()('span'),
    match(this.ctx.url)(
        tag()('a'),
        attrs()({ href: this.ctx.url })
    )
)
apply по моде

Сейчас вместо apply(this._mode = 'bla') можно написать просто apply('bla').

Благодаря возможности apply в XJST иметь произвольное количество аргументов для модификации контекста, мы можем иметь такой синтаксис: apply(this)('bla').

applyCtx

Вместо applyNext(this.ctx = { some: 'new' }) можно написать просто applyCtx({ some: 'new' }).

По аналогии с предыдущим пунктом, можно иметь: applyCtx(this)({ some: 'new' }).

Тут есть небольшой нюанс, т.к. в applyCtx можно также использовать модификацию контекста: applyCtx({ some: 'new' }, this.bla = 1).

Поскольку в новом синтаксисе для выражения модификации контекста используются объекты, прийдётся договориться, что первый параметр это всегда новый this.ctx: applyCtx(this)({ some: 'new' }, { bla: 1 }).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment