Skip to content

Режимы

vill edited this page Mar 28, 2018 · 1 revision

ВАЖНО. Только для компонент, структура (дерево) которых была создана с помощью хелпера define_component доступно использование BEMHTML шаблонов.

ВАЖНО. Количество режимов и правила их использования отличаются от bem-xjst.

ВАЖНО. Порядок поиска и применения шаблонов такой же как и в bem-xjst.

Режимы (моды, modes) позволяют производить различные манипуляции (добавлять/изменять/заменять/удалять) над узлами дерева (структуры). При работе с BEMHTML шаблонами доступно 9 основных и 4 вспомогательных режима.

Для всех примеров используется файловая структура:

app/
  ├── assets/
  |     ├── javascripts/
  |     |     └── application.js
  |     └── stylesheets/
  |           └── application.css
  ├── bemer_components/
  |     ├── common/
  |     |     ├── alert/
  |     |     |     ├── index.html.slim
  |     |     |     ├── index.bemhtml.slim
  |     |     |     ├── index.js
  |     |     |     └── index.css
  |     |     └── ...
  |     └── ...
  └── ...  

Подключение технологий JavaScript и CSS компонента alert при использование Sprockets:

// Файл app/assets/javascripts/application.js
//= require common/alert
// Файл app/assets/stylesheets/application.css
//= require common/alert

В качестве структуры компонента alert будет взят компонент alert из библиотеки Twitter Bootstrap:

<!-- Исходная HTML структура компонента alert из библиотеки Twitter Bootstrap -->
<div class="alert alert-info alert-dismissible" role="alert">
  <button type="button" class="close" data-dismiss="alert">
    <span aria-hidden="true">&times;</span>
  </button>
  <strong>Warning!</strong> Better check yourself, you're not looking too good.
</div>

Возможный вариант разметки компонента alert по БЭМ методологии:

/ Содержимое файла index.html.slim компонента alert
= define_component bem_cascade: false do |component|
  = component.block :alert, tag: :div, cls: 'alert alert-dismissible', role: :alert do |alert|
    = alert.elem :close, type: :button, tag: :button, cls: :close, data: { dismiss: :alert }
      span aria-hidden='true' &times;
    = alert.elem :message, tag: false
      strong> Warning!
      | Better check yourself, you're not looking too good.

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

/ Содержимое файла index.bemhtml.slim компонента alert
= define_templates do |template|
  = template.block(:alert).add_cls :alert_info

HTML структура компонента alert после вызова render_component:

/ Шаблонизатор Slim
= render_component 'common/alert'

/ =>
/ <div role="alert" class="alert alert-dismissible alert-info">
/   <button type="button" data-dismiss="alert" class="close">
/     <span aria-hidden="true">×</span>
/   </button>
/   <strong>Warning!</strong> Better check yourself, you're not looking too good.
/ </div>

Основные режимы

Список основных режимов и порядок их применения: replace, content, tag, cls, attrs, bem, mods, mix, js.

Режим replace

ВАЖНО. Режим content работает быстрее режима replace.

ВАЖНО. В тело шаблона вторым параметром передается билдер (builder) компонента.

ВАЖНО. Методы ctx и content доступны ТОЛЬКО в режимах replace и content.

Заменяет/удаляет узел в дереве(структуре) компонента.

Аргументом метода (телом шаблона) может быть String, Proc, lambda или &block.

Найти элемент message и заменить на другой текст:

/ Шаблонизатор Slim
= render_component 'common/alert' do |template|
  = template.elem(:message).replace
    strong> Heads up!
    | This
    =< link_to 'alert needs your attention', '#', class: 'alert-link'
    | , but it's not super important.

/ =>
/ <div role="alert" class="alert alert-dismissible alert-info">
/   <button type="button" data-dismiss="alert" class="close">
/     <span aria-hidden="true">×</span>
/   </button>
/   <strong>Heads up!</strong>
/   This <a class="alert-link" href="#">alert needs your attention</a>,
/   but it's not super important.
/ </div>

Найти элемент close и заменить на пустую строку, т.е. будет выполнено удаление:

/ Шаблонизатор Slim
= render_component 'common/alert' do |template|
  = template.elem(:close).replace

/ =>
/ <div role="alert" class="alert alert-dismissible alert-info">
/   <strong>Warning!</strong> Better check yourself, you're not looking too good.
/ </div>

Режим content

ВАЖНО. Режим content работает быстрее режима replace.

ВАЖНО. В тело шаблона вторым параметром передается билдер (builder) компонента.

ВАЖНО. Методы ctx и content доступны ТОЛЬКО в режимах replace и content.

Заменяет/удаляет содержимое узла в дереве(структуре) компонента.

Аргументом метода (телом шаблона) может быть String, Proc, lambda или &block.

Пример из режима replace, будет работать быстрее для режима content:

/ Шаблонизатор Slim
= render_component 'common/alert' do |template|
  = template.elem(:message).content
    strong> Heads up!
    | This
    =< link_to 'alert needs your attention', '#', class: 'alert-link'
    | , but it's not super important.

/ =>
/ <div role="alert" class="alert alert-dismissible alert-info">
/   <button type="button" data-dismiss="alert" class="close">
/     <span aria-hidden="true">×</span>
/   </button>
/   <strong>Heads up!</strong>
/   This <a class="alert-link" href="#">alert needs your attention</a>,
/   but it's not super important.
/ </div>

Режим tag

Изменяет параметр tag, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Режим cls

Изменяет параметр cls, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Режим attrs

Изменяет HTML атрибуты, аргументом (телом шаблона) может быть Hash, Proc, lambda или Array.

Режим bem

Изменяет параметр bem, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Режим mods

Изменяет параметр mods, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Режим mix

Изменяет параметр mix, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Режим js

Изменяет параметр js, кроме допустимых значений аргументом (телом шаблона) может быть Proc и lambda.

Вспомогательные режимы

ВАЖНО. Вспомогательные режимы это всего лишь синтаксический сахар (syntactic sugar) для некоторых основных режимов.

Список вспомогательных режимов: add_attrs, add_cls, add_mix, add_mods.

Режим add_attrs

ВАЖНО. Аргументы такие же как и у режима attrs.

Добавляет HTML атрибуты.

/ Эквивалентные записи
= render_component 'common/alert' do |template|
  = template.block(:alert).add_attrs key: :value

= render_component 'common/alert' do |template|
  = template.block(:alert).attrs ->(node) { node.apply_next.merge!(key: :value) }

= render_component 'common/alert' do |template|
  = template.block(:alert).attrs ->(node) { node.apply(:attrs).merge!(key: :value) }

Режим add_cls

ВАЖНО. Аргументы такие же как и у режима cls.

Добавляет css классы.

/ Эквивалентные записи
= render_component 'common/alert' do |template|
  = template.block(:alert).add_cls :css_class

= render_component 'common/alert' do |template|
  = template.block(:alert).cls ->(node) { node.apply_next << :css_class }

= render_component 'common/alert' do |template|
  = template.block(:alert).cls ->(node) { node.apply(:cls) << :css_class }

Режим add_mix

ВАЖНО. Аргументы такие же как и у режима mix.

Добавляет миксы.

/ Эквивалентные записи
= render_component 'common/alert' do |template|
  = template.block(:alert).add_mix block: :elem

= render_component 'common/alert' do |template|
  = template.block(:alert).mix ->(node) { node.apply_next << { block: :elem } }

= render_component 'common/alert' do |template|
  = template.block(:alert).mix ->(node) { node.apply(:mix) << { block: :elem } }

/ С использованием хелпера bem_mix
= render_component 'common/alert' do |template|
  = template.block(:alert).mix ->(node) { node.apply(:mix) << bem_mix(block: :elem) }

Режим add_mods

ВАЖНО. Аргументы такие же как и у режима mods.

Добавляет модификаторы.

/ Эквивалентные записи
= render_component 'common/alert' do |template|
  = template.block(:alert).add_mods :enabled

= render_component 'common/alert' do |template|
  = template.block(:alert).mods ->(node) { node.apply_next.merge!(enabled: true) }

= render_component 'common/alert' do |template|
  = template.block(:alert).mods ->(node) { node.apply(:mods).merge!(enabled: true) }