bemer 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/{LICENSE-RU → LICENSE-RU.txt} +0 -0
  3. data/{LICENSE → LICENSE.txt} +5 -5
  4. data/README.md +47 -16
  5. data/docs/BEMHTML.md +5 -0
  6. data/docs//320/232/320/276/320/275/321/202/320/265/320/272/321/201/321/202-/321/203/320/267/320/273/320/260.md +275 -0
  7. data/docs//320/232/320/276/320/275/321/204/320/270/320/263/321/203/321/200/320/260/321/206/320/270/321/217.md +158 -0
  8. data/docs//320/237/321/200/320/265/320/264/320/270/320/272/320/260/321/202/321/213.md +205 -0
  9. data/docs//320/240/320/265/320/266/320/270/320/274/321/213.md +274 -0
  10. data/docs//320/241/320/276/320/267/320/264/320/260/320/275/320/270/320/265-/320/270-/320/270/321/201/320/277/320/276/320/273/321/214/320/267/320/276/320/262/320/260/320/275/320/270/320/265-UI-/320/272/320/276/320/274/320/277/320/276/320/275/320/265/320/275/321/202.md +173 -0
  11. data/docs//320/244/320/260/320/270/314/206/320/273/320/276/320/262/320/260/321/217-/321/201/321/202/321/200/321/203/320/272/321/202/321/203/321/200/320/260.md +167 -0
  12. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mix.md +62 -0
  13. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mods.md +63 -0
  14. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-block_tag.md +215 -0
  15. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_asset_path.md +71 -0
  16. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_pack.md +101 -0
  17. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_partial_path.md +28 -0
  18. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_component.md +154 -0
  19. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_templates.md +96 -0
  20. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-elem_tag.md +38 -0
  21. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-refine_component.md +114 -0
  22. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-render_component.md +108 -0
  23. data/docs//320/250/320/260/320/261/320/273/320/276/320/275/321/213.md +44 -0
  24. data/lib/bemer.rb +3 -1
  25. data/lib/bemer/builders.rb +8 -0
  26. data/lib/bemer/builders/tree.rb +0 -8
  27. data/lib/bemer/configuration.rb +3 -1
  28. data/lib/bemer/context_extentions/structure.rb +2 -3
  29. data/lib/bemer/entity.rb +2 -2
  30. data/lib/bemer/entity_builder.rb +5 -9
  31. data/lib/bemer/helpers.rb +10 -0
  32. data/lib/bemer/mixin_list.rb +1 -1
  33. data/lib/bemer/modifier_list.rb +2 -2
  34. data/lib/bemer/path_resolver.rb +23 -0
  35. data/lib/bemer/pipeline/handler.rb +4 -6
  36. data/lib/bemer/railtie.rb +22 -9
  37. data/lib/bemer/renderer.rb +1 -1
  38. data/lib/bemer/template_list.rb +2 -4
  39. data/lib/bemer/tree.rb +3 -3
  40. data/lib/bemer/tree/node.rb +5 -7
  41. data/lib/bemer/version.rb +1 -1
  42. data/spec/bemer/railtie_spec.rb +95 -0
  43. data/spec/dummy/config/application.rb +30 -12
  44. data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -5
  45. data/spec/dummy/config/initializers/bemer.rb +1 -3
  46. data/spec/rails_helper.rb +5 -9
  47. metadata +87 -129
  48. data/.gitignore +0 -17
  49. data/.overcommit.yml +0 -59
  50. data/.rspec +0 -4
  51. data/.rubocop.yml +0 -21
  52. data/.rubocop_todo.yml +0 -11
  53. data/Gemfile +0 -12
  54. data/Rakefile +0 -12
  55. data/bemer.gemspec +0 -43
  56. data/spec/dummy/Rakefile +0 -8
  57. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  58. data/spec/dummy/app/helpers/application_helper.rb +0 -4
  59. data/spec/dummy/app/jobs/application_job.rb +0 -4
  60. data/spec/dummy/app/mailers/application_mailer.rb +0 -6
  61. data/spec/dummy/app/models/application_record.rb +0 -5
  62. data/spec/dummy/app/models/concerns/.keep +0 -0
  63. data/spec/dummy/app/views/layouts/mailer.html.erb +0 -13
  64. data/spec/dummy/app/views/layouts/mailer.text.erb +0 -1
  65. data/spec/dummy/bin/bundle +0 -5
  66. data/spec/dummy/bin/rails +0 -6
  67. data/spec/dummy/bin/rake +0 -6
  68. data/spec/dummy/bin/setup +0 -39
  69. data/spec/dummy/bin/update +0 -31
  70. data/spec/dummy/bin/yarn +0 -13
  71. data/spec/dummy/config/cable.yml +0 -10
  72. data/spec/dummy/config/database.yml +0 -25
  73. data/spec/dummy/config/environments/development.rb +0 -51
  74. data/spec/dummy/config/environments/production.rb +0 -84
  75. data/spec/dummy/config/environments/test.rb +0 -44
  76. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -7
  77. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -7
  78. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -6
  79. data/spec/dummy/config/initializers/inflections.rb +0 -17
  80. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  81. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  82. data/spec/dummy/config/locales/en.yml +0 -33
  83. data/spec/dummy/config/puma.rb +0 -58
  84. data/spec/dummy/config/routes.rb +0 -5
  85. data/spec/dummy/config/secrets.yml +0 -32
  86. data/spec/dummy/config/spring.rb +0 -8
  87. data/spec/dummy/lib/assets/.keep +0 -0
  88. data/spec/dummy/log/.keep +0 -0
  89. data/spec/dummy/package.json +0 -5
  90. data/spec/dummy/public/404.html +0 -67
  91. data/spec/dummy/public/422.html +0 -67
  92. data/spec/dummy/public/500.html +0 -66
  93. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  94. data/spec/dummy/public/apple-touch-icon.png +0 -0
  95. data/spec/dummy/public/favicon.ico +0 -0
@@ -0,0 +1,215 @@
1
+ # Хелпер block_tag
2
+
3
+ **ВАЖНО**. *Только для компонент, [структура (дерево) которых была создана](Создание-и-использование-UI-компонент.md) с помощью [хелпера `define_component`](Хелпер-define_component.md) доступно использование [BEMHTML шаблонов](Шаблоны.md).*
4
+
5
+ **ВАЖНО**. *Для сущностей у которых не указано название, не будут созданы css классы и js атрибуты из методологии БЭМ*:
6
+ ```ruby
7
+ block_tag js: true, bem: true # => <div></div>
8
+ ```
9
+
10
+ **ВАЖНО**. *[Параметр `bem` из конфигурации](Конфигурация.md#%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80-bem) никак не влияет на работу `block_tag`.*
11
+
12
+ **ВАЖНО**. *Использование строковых (`String`) ключей при передаче параметров не допустимо, ключами могут быть только сиволы (`Symbol`).*
13
+
14
+ Позволяет создавать блок по методологии БЭМ.
15
+
16
+ ## Название сущности
17
+
18
+ При вызове `block_tag` первым аргументом передается название блока (указывать не обязательно) допустимые типы:
19
+ 1. `Symbol` ВСЕ символы нижнего подчеркивания будут преобразованы в тире, при формирование css классов по методологии БЭМ
20
+ 1. `String` возвращается без изменений
21
+
22
+ ```ruby
23
+ # Вызов без каких-либо параметров
24
+ block_tag # => <div></div>
25
+ ```
26
+ ```ruby
27
+ block_tag :block_name # => <div class="block-name"></div>
28
+ ```
29
+
30
+ **ВАЖНО**. *Будьте ВНИМАТЕЛЬНЫ при использовании названий с типом `String`, если в них содержатся знаки нижнего подчеркивания `_`, это может привести к неправильному результату согласно методологии БЭМ*:
31
+ ```ruby
32
+ block_tag 'block_name' # => <div class="block_name"></div>
33
+ ```
34
+
35
+ ## Допустимые параметры
36
+
37
+ `bem`, `bem_cascade`, `cls` (синоним `class`), `content`, `js`, `mix`, `mods` и `tag`, все остальные переданные параметры с названиями не из этого списка будут считаться атрибутами.
38
+
39
+ ### Параметр `bem`
40
+
41
+ Разрешает или запрещает использовать методологию БЭМ при создании текущего блока.
42
+
43
+ ```ruby
44
+ block_tag :block, bem: true # => <div class="block"></div>
45
+ block_tag :block, bem: false # => <div></div>
46
+ block_tag :block, bem: nil # => <div class="block"></div>
47
+ ```
48
+
49
+ ### Параметр `bem_cascade`
50
+
51
+ Разрешает или запрещает использовать методологию БЭМ для текущего блока и ТОЛЬКО всех его элементов (в [хелпере `define_component` используется для ВСЕХ ДОЧЕРНИХ ЭЛЕМЕНТОВ см. описание параметра `content`](#%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80-content))
52
+
53
+ ```ruby
54
+ block_tag :block, bem_cascade: true # => <div class="block"></div>
55
+ block_tag :block, bem_cascade: false # => <div></div>
56
+ ```
57
+
58
+ Имеет меньший приоритет чем параметр `bem`:
59
+
60
+ ```ruby
61
+ block_tag :block, bem_cascade: true, bem: false # => <div></div>
62
+ block_tag :block, bem_cascade: false, bem: true # => <div class="block"></div>
63
+ ```
64
+
65
+ ### Параметр `cls` синоним `class`
66
+
67
+ Добавляет css классы.
68
+
69
+ ```ruby
70
+ block_tag :block, cls: 'class-1', bem: false # => <div class="class-1"></div>
71
+ block_tag :block, class: 'class-1', bem: true # => <div class="block class-1"></div>
72
+ ```
73
+ ВСЕ символы нижнего подчеркивания будут преобразованы в тире, если класс передан как `Symbol`:
74
+
75
+ ```ruby
76
+ block_tag :block, cls: ['cls_1', :cls_2], bem: false # => <div class="cls_1 cls-2"></div>
77
+ ```
78
+
79
+ ### Параметр `content`
80
+
81
+ Добавляет содержимое для блока.
82
+
83
+ ```ruby
84
+ block_tag :block, content: 'Block content' # => <div>Block content</div>
85
+ ```
86
+ Если передан `Ruby &block`, тогда параметр `content` игнорируется:
87
+
88
+ ```slim
89
+ / Шаблонизатор Slim
90
+ = block_tag :block, content: 'Block content', bem: false do
91
+ h1 Content from Ruby &block
92
+
93
+ / => <div><h1>Content from Ruby &block</h1></div>
94
+ ```
95
+ Для блоков доступно альтернативное создание элементов:
96
+
97
+ ```slim
98
+ / Шаблонизатор Slim
99
+ = block_tag :block, bem_cascade: true do |block|
100
+ = block.elem :elem_1 do
101
+ = block.elem :elem_2 do
102
+ span Elem 2 content
103
+
104
+ / =>
105
+ /<div class="block">
106
+ / <div class="block__elem-1">
107
+ / <div class="block__elem-2">
108
+ / <span>Elem 2 content</span>
109
+ / </div>
110
+ / </div>
111
+ / </div>
112
+
113
+ = block_tag :block, bem_cascade: false, bem: true do |block|
114
+ = block.elem :elem_1 do
115
+ = block.elem :elem_2 do
116
+ span Elem 2 content
117
+
118
+ / =>
119
+ / <div class="block">
120
+ / <div>
121
+ / <div>
122
+ / <span>Elem 2 content</span>
123
+ / </div>
124
+ / </div>
125
+ / </div>
126
+
127
+ = block_tag :block, bem_cascade: false, bem: true do |block|
128
+ = block.elem :elem_1, bem: true do
129
+ = block.elem :elem_2 do
130
+ span Elem 2 content
131
+ / =>
132
+ / <div class="block">
133
+ / <div class="block__elem-1">
134
+ / <div>
135
+ / <span>Elem 2 content</span>
136
+ / </div>
137
+ / </div>
138
+ / </div>
139
+ ```
140
+
141
+
142
+ ### Параметр `js`
143
+
144
+ Создает атрибут `data-bem` и css класс `i-bem`.
145
+
146
+ ```ruby
147
+ block_tag :block, js: true, bem: true
148
+ # => <div class="block i-bem" data-bem="{"block":{}}"></div>
149
+
150
+ block_tag :block, js: [1, 2], bem: true
151
+ # => <div class="block i-bem" data-bem="{"block":[1,2]}"></div>
152
+
153
+ block_tag :block, js: { key: :val }, bem: true
154
+ # => <div class="block i-bem" data-bem="{"block":{"key":"val"}}"></div>
155
+
156
+ block_tag :block, js: true, bem: false # => <div></div>
157
+ ```
158
+ Для блока без имени js атрибуты не создаются:
159
+ ```ruby
160
+ block_tag js: true, bem: true # => <div></div>
161
+ ```
162
+ ### Параметр `mix`
163
+
164
+ Добавляет миксы подробнее см. [хелпер `bem_mix`](Хелпер-bem_mix.md).
165
+
166
+ ```ruby
167
+ block_tag :block, mix: [:mix_1, block_1: :elem], bem: true
168
+ # => <div class="block mix-1 block-1__elem"></div>
169
+
170
+ block_tag :block, mix: { block_1: :elem }, bem: true
171
+ # => <div class="block block-1__elem"></div>
172
+ ```
173
+
174
+ ### Параметр `mods`
175
+
176
+ Добавляет модификаторы подробнее см. [хелпер `bem_mods`](Хелпер-bem_mods.md).
177
+
178
+ ```ruby
179
+ block_tag :block, mods: :enabled, bem: true
180
+ # => <div class="block block_enabled"></div>
181
+
182
+ block_tag :block, mods: [:enabled, size: :small], bem: true
183
+ # => <div class="block block_enabled block_size_small"></div>
184
+
185
+ block_tag :block, mods: { size: :small }, bem: true
186
+ # => <div class="block block_size_small"></div>
187
+ ```
188
+
189
+ ### Параметр `tag`
190
+
191
+ Добавляет или удаляет html тег, допустимые значения: `Symbol`, `String`, `false` и `nil`.
192
+
193
+ ```ruby
194
+ block_tag :block, tag: :span, content: 'Block content'
195
+ # => <span>Block content</span>
196
+
197
+ block_tag :block, tag: '', content: 'Block content'
198
+ # => 'Block content'
199
+
200
+ block_tag :block, tag: false, content: 'Block content'
201
+ # => 'Block content'
202
+
203
+ # Будет использован default_block_tag из конфига
204
+ block_tag :block, tag: nil, content: 'Block content'
205
+ # => <div>Block content</div>
206
+ ```
207
+
208
+ ### Атрибуты
209
+
210
+ Любой параметр с названием не из [списка допустимых параметров](#%D0%94%D0%BE%D0%BF%D1%83%D1%81%D1%82%D0%B8%D0%BC%D1%8B%D0%B5-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B) считается атрибутом:
211
+
212
+ ```ruby
213
+ block_tag :block, data: { key: :val } # => <div data-key="val"></div>
214
+ block_tag :block, key: :val # => <div key="val"></div>
215
+ ```
@@ -0,0 +1,71 @@
1
+ # Хелпер component_asset_path
2
+
3
+ **ВАЖНО**. *Необходимо делать прекомпиляцию ресурсов, с помощью `sprockets` или `webpacker`.*
4
+
5
+ Хелпер `component_asset_path` возвращает путь до ресурса (asset) компонента: изображения, файла и т.д. При вызове, хелперу необходимо передать название ресурса (asset).
6
+
7
+ Для примеров используется следующая файловая структура:
8
+
9
+ ```
10
+ app/
11
+ ├── bemer_components/
12
+ | ├── image_gallery/
13
+ | | ├── images/
14
+ | | | ├── placeholder.jpg
15
+ | | | └── ...
16
+ | | ├── _image.html.slim
17
+ | | ├── index.html.slim
18
+ | | ├── index.js
19
+ | | ├── index.scss
20
+ | | └── ...
21
+ | ├── user_profile/
22
+ | | ├── images/
23
+ | | | ├── placeholder.jpg
24
+ | | | └── ...
25
+ | | ├── index.html.slim
26
+ | | ├── index.js
27
+ | | ├── index.scss
28
+ | | └── ...
29
+ | └── ...
30
+ ├── views/
31
+ | ├── users/
32
+ | | ├── show.html.slim
33
+ | | └── ...
34
+ | ├── images/
35
+ | | ├── index.html.slim
36
+ | | └── ...
37
+ | └── ...
38
+ └── ...
39
+ ```
40
+
41
+ ## Использование
42
+
43
+ ```slim
44
+ / app/bemer_components/user_profile/index.html.slim
45
+
46
+ = component_asset_path('images/placeholder.jpg') / => 'user_profile/images/placeholder.jpg'
47
+ = component_asset_path('image_gallery/images/placeholder.jpg') / => 'image_gallery/images/placeholder.jpg'
48
+
49
+ ```
50
+
51
+ ```slim
52
+ / app/bemer_components/image_gallery/_image.html.slim
53
+
54
+ = component_asset_path('images/placeholder.jpg') / => 'image_gallery/images/placeholder.jpg'
55
+ = component_asset_path('user_profile/images/placeholder.jpg') / => 'user_profile/images/placeholder.jpg'
56
+
57
+ ```
58
+
59
+ ```slim
60
+ / app/views/users/show.html.slim
61
+
62
+ = component_asset_path('user_profile/images/placeholder.jpg') / => 'user_profile/images/placeholder.jpg'
63
+
64
+ ```
65
+
66
+ ```slim
67
+ / app/views/images/index.html.slim
68
+
69
+ = component_asset_path('image_gallery/images/placeholder.jpg') / => 'image_gallery/images/placeholder.jpg'
70
+
71
+ ```
@@ -0,0 +1,101 @@
1
+ # Хелпер component_pack
2
+
3
+ **ВАЖНО**. *`component_pack` и параметр `cached: true` позволяют лишь в некоторых случаях пропускать перекомпиляцию одних и тех же шаблонов для технологии BEMHTML, дополнительно к этому обязательно используйте кэширование которое [доступно в Rails](http://rusrails.ru/caching-with-rails-an-overview)*.
4
+
5
+ Использование `component_pack` и `cached: true` может пригодиться только в том случае, когда один и тот же компонент(ы) нужно вывести в одном месте несколько раз (используя цикл), при этом шаблоны этого компонента или используемые внутри его вызовы других компонент не зависят от итераций, для всех итераций шаблоны у них будут одни и те же (нет динамических данных в шаблонах BEMHTML).
6
+
7
+ Для всех примеров используется файловая структура:
8
+ ```
9
+ app/
10
+ ├── assets/
11
+ | ├── javascripts/
12
+ | | └── application.js
13
+ | └── stylesheets/
14
+ | └── application.css
15
+ ├── bemer_components/
16
+ | ├── common/
17
+ | | ├── alert/
18
+ | | | ├── index.html.slim
19
+ | | | ├── index.js
20
+ | | | └── index.css
21
+ | | └── ...
22
+ | └── ...
23
+ └── ...
24
+ ```
25
+ Подключение технологий JavaScript и CSS компонента `alert` при использование Sprockets:
26
+
27
+ ```js
28
+ // Файл app/assets/javascripts/application.js
29
+ //= require common/alert
30
+ ```
31
+
32
+ ```scss
33
+ // Файл app/assets/stylesheets/application.css
34
+ //= require common/alert
35
+ ```
36
+
37
+ В качестве структуры компонента `alert` будет взят [компонент `alert` из библиотеки Twitter Bootstrap](https://getbootstrap.com/docs/3.3/components/#alerts):
38
+
39
+ ```html
40
+ <!-- Исходная HTML структура компонента alert из библиотеки Twitter Bootstrap -->
41
+ <div class="alert alert-info alert-dismissible" role="alert">
42
+ <button type="button" class="close" data-dismiss="alert">
43
+ <span aria-hidden="true">&times;</span>
44
+ </button>
45
+ <strong>Warning!</strong> Better check yourself, you're not looking too good.
46
+ </div>
47
+ ```
48
+ Возможный вариант разметки компонента `alert` по БЭМ методологии:
49
+ ```slim
50
+ / Содержимое файла index.html.slim компонента alert
51
+ = define_component bem_cascade: false do |component|
52
+ = component.block :alert, tag: :div, cls: 'alert alert-dismissible', role: :alert do |alert|
53
+ = alert.elem :close, type: :button, tag: :button, cls: :close, data: { dismiss: :alert }
54
+ span aria-hidden='true' &times;
55
+ = alert.elem :message, tag: false
56
+ strong> Warning!
57
+ | Better check yourself, you're not looking too good.
58
+ ```
59
+ ## Примеры
60
+
61
+ ### Без использования `component_pack` с параметром `cached: true`
62
+
63
+ После каждой итерации, скомпилированные шаблоны компонента `alert` и шаблоны других компонент (в примере их нет), которые были созданы при вызове `render_component :alert` будут удалены, поэтому `cached: true` при вызове компонента `alert` не влияет на результат:
64
+ ```slim
65
+ - %i[success info warning danger].each do |alert_type|
66
+ = render_component :alert, cached: true do |template|
67
+ = template.block(:alert).add_cls "alert-#{alert_type}"
68
+ = template.elem(:message).content
69
+ strong = "Alert type: #{alert_type}"
70
+ ```
71
+ ![alert-cached-false](images/alert-cached-false.jpg)
72
+
73
+ ### С использованием `component_pack` без параметра `cached` (`cached: false`)
74
+
75
+ Если у компонента есть в шаблонах вызов других компонент с параметром `cached: true` или присутствуют [шаблоны по умолчанию (у `define_templates` по умолчанию параметр `cached` равен `true`)](Хелпер-define_templates.md) тогда для каждой итерации будут использоваться шаблоны из кэша (скомпилированные при первой итерации).
76
+
77
+ Шаблоны для компонента `alert` не кэшируются потому что не был передан параметр `cached: true`
78
+
79
+ ```slim
80
+ = component_pack do
81
+ - %i[success info warning danger].each do |alert_type|
82
+ = render_component :alert do |template|
83
+ = template.block(:alert).add_cls "alert-#{alert_type}"
84
+ = template.elem(:message).content
85
+ strong = "Alert type: #{alert_type}"
86
+ ```
87
+ ![alert-cached-false](images/alert-cached-false.jpg)
88
+
89
+ ### С использованием `component_pack` и параметром `cached: true`
90
+
91
+ Для всех итераций используются шаблоны которые были получены при первой итерации:
92
+ ```slim
93
+ = component_pack do
94
+ - %i[success info warning danger].each do |alert_type|
95
+ = render_component :alert, cached: true do |template|
96
+ = template.block(:alert).add_cls "alert-#{alert_type}"
97
+ = template.elem(:message).content
98
+ strong = "Alert type: #{alert_type}"
99
+ ```
100
+
101
+ ![alert-cached-true](images/alert-cached-true.jpg)
@@ -0,0 +1,28 @@
1
+ # Хелпер component_partial_path
2
+
3
+ Хелпер `component_partial_path` возвращает путь до партиала (partial) в каталоге компонента. При вызове хелпера необходимо передать название партиала (partial).
4
+
5
+ Для примеров используется следующая файловая структура:
6
+
7
+ ```
8
+ app/
9
+ ├── bemer_components/
10
+ | ├── image_gallery/
11
+ | | ├── _image.html.slim
12
+ | | ├── index.html.slim
13
+ | | ├── index.js
14
+ | | ├── index.scss
15
+ | | └── ...
16
+ └── ...
17
+ ```
18
+
19
+ ## Использование
20
+
21
+ ```slim
22
+ / app/bemer_components/image_gallery/index.html.slim
23
+
24
+ = component_partial_path(:image) / => 'image_gallery/image'
25
+
26
+ = render component_partial_path(:image)
27
+
28
+ ```
@@ -0,0 +1,154 @@
1
+ # Хелпер define_component
2
+
3
+ **ВАЖНО**. *Необходимо только описывать структуру (дерево) компонента в терминах (блок и элемент) методологии БЭМ*, **создание `css` классов и `js` атрибутов из методологии БЭМ НЕ ОБЯЗАТЕЛЬНО**.
4
+
5
+ **ВАЖНО**. *В отличие от хелперов `block_tag` и `elem_tag`, генерация данных из методологии БЭМ зависит от параметра [`bem` в конфигурации](Конфигурация.md#%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80-bem).*
6
+
7
+ **ВАЖНО**. *Доступно использование [BEMHTML шаблонов](Шаблоны.md).*
8
+
9
+ **ВАЖНО**. *Для сущностей у которых не указано название, не будут созданы css классы и js атрибуты из методологии БЭМ*.
10
+
11
+ Хелпер `define_component` позволяет описывать структуру (дерево) компонента с помощью сущностей (блок и элемент) методологии БЭМ, благодаря этому, используя BEMHTML шаблоны можно более продвинутыми способами взаимодействовать с такими типами компонент.
12
+
13
+ При вызове `define_component` обязательно нужно использовать `&block` в который будет передан билдер (builder) для построения структуры (дерева) компонента.
14
+
15
+ ## Метод `block`
16
+
17
+ Принимает такие же параметры как и [хелпер `block_tag`](Хелпер-block_tag.md).
18
+
19
+ **ВАЖНО**. *В отличие от `block_tag` и `elem_tag`, переданный в текущий узел параметр `bem_cascade` распространяется на сам узел и все его дочерние узлы (блоки и элементы), даже если текущий узел является элементом.*
20
+
21
+ Позволяет создавать блок из методологии БЭМ:
22
+ ```slim
23
+ = define_component do |component|
24
+ = component.block content: 'Plain text'
25
+
26
+ = define_component do |component|
27
+ = component.block :block_name, content: 'Plain text'
28
+
29
+ = define_component do |component|
30
+ = component.block
31
+ span Content
32
+
33
+ / bem_cascade: false применится к узлу и ко всем его дочерним узлам
34
+ = define_component do |component|
35
+ = component.block bem_cascade: false do |block|
36
+ = component.block :block2 do |block2|
37
+ = block2.elem :elem
38
+ = block.elem content: 'Plain text'
39
+ ```
40
+
41
+ ## Метод `elem`
42
+
43
+ Принимает такие же параметры как и [хелпер `elem_tag`](Хелпер-elem_tag.md).
44
+
45
+ **ВАЖНО**. *В отличие от `block_tag` и `elem_tag`, переданный в текущий узел параметр `bem_cascade` распространяется на сам узел и все его дочерние узлы (блоки и элементы), даже если текущий узел является элементом.*
46
+
47
+ Позволяет создавать элемент из методологии БЭМ:
48
+ ```slim
49
+ = define_component do |component|
50
+ = component.elem content: 'Plain text'
51
+
52
+ = define_component do |component|
53
+ = component.elem :block_name, :elem_name, content: 'Plain text'
54
+
55
+ = define_component do |component|
56
+ = component.elem
57
+ span Content
58
+
59
+ / bem_cascade: true применится к узлу и ко всем его дочерним узлам
60
+ = define_component do |component|
61
+ = component.elem bem_cascade: true
62
+ = component.block do |block|
63
+ = block.elem content: 'Plain text'
64
+ ```
65
+
66
+ ## Метод `text`
67
+
68
+ **ВАЖНО**. *Переданные параметры через методы `apply`, `apply_next`, `content` и `ctx` не будут использоваться в узлах внутри метода `text`*.
69
+
70
+ Создает текстовый узел(`TextNode`) в структуре(дереве) компонента, к узлам такого типа **не применяются шаблоны BEMHTML** и значение параметра `tag` указано как `false`, не принимает никаких дополнительных параметров.
71
+
72
+ Узлы с типом `TextNode` предназначены ТОЛЬКО для расположения текста на определенном уровне в структуре(дереве), чтобы при рендеринге компонента не происходило выталкивание вверх текстовых вставок:
73
+
74
+ ```slim
75
+ / При такой структуре 'span Content' всплывет на верх
76
+ = define_component bem_cascade: true do |component|
77
+ = component.block :block_name
78
+ span Content
79
+
80
+ / =>
81
+ / <span>Content</span>
82
+ / <div class="block-name"></div>
83
+
84
+ = define_component bem_cascade: true do |component|
85
+ = component.block :block_name
86
+ = component.text
87
+ span Content
88
+
89
+ / =>
90
+ / <div class="block-name"></div>
91
+ / <span>Content</span>
92
+
93
+ = define_component bem_cascade: true do |component|
94
+ = component.block :block_name
95
+ = component.text 'Content'
96
+
97
+ / =>
98
+ / <div class="block-name"></div>
99
+ / Content
100
+ ```
101
+
102
+ В данном случае, результат будет одинаковым, но лучше избегать использование методов `block` и `elem` внутри метода `text`:
103
+ ```slim
104
+ = define_component bem_cascade: true do |component|
105
+ = component.block :block1
106
+ = component.text
107
+ = component.block :block2 do |block2|
108
+ = block2.elem :elem
109
+
110
+ = define_component bem_cascade: true do |component|
111
+ = component.block :block1
112
+ = component.block :block2 do |block2|
113
+ = block2.elem :elem
114
+
115
+ / =>
116
+ / <div class="block1"></div>
117
+ / <div class="block2">
118
+ / <div class="block2__elem"></div>
119
+ / </div>
120
+ ```
121
+
122
+ ## Параметры по умолчанию
123
+
124
+ В `define_component` можно передать такие же параметры как и в методы `block` и `elem`, которые будут значениями по умолчанию для узлов дерева (структуры) компонента:
125
+ ```slim
126
+ / Эквивалентные записи
127
+ = define_component do |component|
128
+ = component.block :block1, tag: :div, js: true, bem: true
129
+ = component.block :block2, tag: :div, js: true, bem: true do |block2|
130
+ = block2.elem :elem, tag: :div, js: true, bem: true
131
+
132
+ = define_component tag: :div, js: true, bem: true do |component|
133
+ = component.block :block1
134
+ = component.block :block2 do |block2|
135
+ = block2.elem :elem
136
+
137
+ / =>
138
+ / <div data-bem="{"block1":{}}" class="block1 i-bem"></div>
139
+ / <div data-bem="{"block2":{}}" class="block2 i-bem">
140
+ / <div data-bem="{"block2__elem":{}}" class="block2__elem i-bem"></div>
141
+ / </div>
142
+
143
+ / Переопределение дефолтных значений
144
+ = define_component tag: :div, js: true, bem: true do |component|
145
+ = component.block :block1, js: false
146
+ = component.block :block2, js: false do |block2|
147
+ = block2.elem :elem
148
+
149
+ / =>
150
+ / <div class="block1"></div>
151
+ / <div class="block2">
152
+ / <div data-bem="{"block2__elem":{}}" class="block2__elem i-bem"></div>
153
+ / </div>
154
+ ```