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.
- checksums.yaml +5 -5
- data/{LICENSE-RU → LICENSE-RU.txt} +0 -0
- data/{LICENSE → LICENSE.txt} +5 -5
- data/README.md +47 -16
- data/docs/BEMHTML.md +5 -0
- 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
- 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
- data/docs//320/237/321/200/320/265/320/264/320/270/320/272/320/260/321/202/321/213.md +205 -0
- data/docs//320/240/320/265/320/266/320/270/320/274/321/213.md +274 -0
- 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
- 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
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mix.md +62 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mods.md +63 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-block_tag.md +215 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_asset_path.md +71 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_pack.md +101 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_partial_path.md +28 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_component.md +154 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_templates.md +96 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-elem_tag.md +38 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-refine_component.md +114 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-render_component.md +108 -0
- data/docs//320/250/320/260/320/261/320/273/320/276/320/275/321/213.md +44 -0
- data/lib/bemer.rb +3 -1
- data/lib/bemer/builders.rb +8 -0
- data/lib/bemer/builders/tree.rb +0 -8
- data/lib/bemer/configuration.rb +3 -1
- data/lib/bemer/context_extentions/structure.rb +2 -3
- data/lib/bemer/entity.rb +2 -2
- data/lib/bemer/entity_builder.rb +5 -9
- data/lib/bemer/helpers.rb +10 -0
- data/lib/bemer/mixin_list.rb +1 -1
- data/lib/bemer/modifier_list.rb +2 -2
- data/lib/bemer/path_resolver.rb +23 -0
- data/lib/bemer/pipeline/handler.rb +4 -6
- data/lib/bemer/railtie.rb +22 -9
- data/lib/bemer/renderer.rb +1 -1
- data/lib/bemer/template_list.rb +2 -4
- data/lib/bemer/tree.rb +3 -3
- data/lib/bemer/tree/node.rb +5 -7
- data/lib/bemer/version.rb +1 -1
- data/spec/bemer/railtie_spec.rb +95 -0
- data/spec/dummy/config/application.rb +30 -12
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -5
- data/spec/dummy/config/initializers/bemer.rb +1 -3
- data/spec/rails_helper.rb +5 -9
- metadata +87 -129
- data/.gitignore +0 -17
- data/.overcommit.yml +0 -59
- data/.rspec +0 -4
- data/.rubocop.yml +0 -21
- data/.rubocop_todo.yml +0 -11
- data/Gemfile +0 -12
- data/Rakefile +0 -12
- data/bemer.gemspec +0 -43
- data/spec/dummy/Rakefile +0 -8
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +0 -4
- data/spec/dummy/app/jobs/application_job.rb +0 -4
- data/spec/dummy/app/mailers/application_mailer.rb +0 -6
- data/spec/dummy/app/models/application_record.rb +0 -5
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +0 -13
- data/spec/dummy/app/views/layouts/mailer.text.erb +0 -1
- data/spec/dummy/bin/bundle +0 -5
- data/spec/dummy/bin/rails +0 -6
- data/spec/dummy/bin/rake +0 -6
- data/spec/dummy/bin/setup +0 -39
- data/spec/dummy/bin/update +0 -31
- data/spec/dummy/bin/yarn +0 -13
- data/spec/dummy/config/cable.yml +0 -10
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environments/development.rb +0 -51
- data/spec/dummy/config/environments/production.rb +0 -84
- data/spec/dummy/config/environments/test.rb +0 -44
- data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -7
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -6
- data/spec/dummy/config/initializers/inflections.rb +0 -17
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummy/config/locales/en.yml +0 -33
- data/spec/dummy/config/puma.rb +0 -58
- data/spec/dummy/config/routes.rb +0 -5
- data/spec/dummy/config/secrets.yml +0 -32
- data/spec/dummy/config/spring.rb +0 -8
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/package.json +0 -5
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- 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">×</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' ×
|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
@@ -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
|
+
```
|