blocks 3.0.0.rc4 → 3.0.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -2
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.rdoc +7 -0
- data/Gemfile +10 -3
- data/README.md +25 -9
- data/_config.yml +20 -0
- data/bin/deploy_docs +2 -0
- data/docs/.gitignore +4 -0
- data/docs/404.html +23 -0
- data/docs/_includes/acknowledgements.md +13 -0
- data/docs/_includes/caller-id.md +3 -0
- data/docs/_includes/configuration.md +3 -0
- data/docs/_includes/custom-builders.md +3 -0
- data/docs/_includes/defining.md +615 -0
- data/docs/_includes/demos/hooks-and-wrappers-output.html +109 -0
- data/docs/_includes/hooks.md +1156 -0
- data/docs/_includes/installation.md +25 -0
- data/docs/_includes/introduction.md +18 -0
- data/docs/_includes/option-merging.md +5 -0
- data/docs/_includes/rendering.md +622 -0
- data/docs/_includes/reserved-keywords.md +59 -0
- data/docs/_includes/skipping.md +403 -0
- data/docs/_includes/slate/assets.html +34 -0
- data/docs/_includes/slate/language-tabs.html +11 -0
- data/docs/_includes/templating.md +48 -0
- data/docs/_includes/templating/bootstrap_4_cards.md +753 -0
- data/docs/_includes/use-cases.md +23 -0
- data/docs/_includes/wip.md +34 -0
- data/docs/_includes/wrappers.md +629 -0
- data/docs/_layouts/slate.html +75 -0
- data/docs/_plugins/gem_version.rb +11 -0
- data/docs/_plugins/highlight_with_div.rb +25 -0
- data/docs/_sass/_default_styling.scss +627 -0
- data/docs/_sass/_icon-font.scss +26 -0
- data/docs/_sass/_normalize.scss +427 -0
- data/docs/_sass/_styling_overrides.scss +31 -0
- data/docs/_sass/_syntax.scss +78 -0
- data/docs/_sass/_variable_overrides.scss +10 -0
- data/docs/_sass/_variables.scss +105 -0
- data/docs/assets/javascripts/script.js +18 -0
- data/docs/assets/stylesheets/formChanges.less +106 -0
- data/docs/assets/stylesheets/style.css +46 -0
- data/docs/fonts/slate.eot +0 -0
- data/docs/fonts/slate.svg +14 -0
- data/docs/fonts/slate.ttf +0 -0
- data/docs/fonts/slate.woff +0 -0
- data/docs/fonts/slate.woff2 +0 -0
- data/docs/hooks.html +149 -0
- data/docs/hooks_and_wrappers_demo.html +313 -0
- data/docs/images/favicon.ico +0 -0
- data/docs/images/logo.png +0 -0
- data/docs/images/navbar.png +0 -0
- data/docs/images/placeholder.jpg +0 -0
- data/docs/images/render_strategies.png +0 -0
- data/docs/images/templating.png +0 -0
- data/docs/index.md +32 -0
- data/docs/javascripts/all.js +4 -0
- data/docs/javascripts/all_nosearch.js +3 -0
- data/docs/javascripts/app/lang.js +166 -0
- data/docs/javascripts/app/search.js +75 -0
- data/docs/javascripts/app/toc.js +57 -0
- data/docs/javascripts/demos/hooks_and_wrappers.js +9 -0
- data/docs/javascripts/lib/energize.js +169 -0
- data/docs/javascripts/lib/imagesloaded.min.js +7 -0
- data/docs/javascripts/lib/jquery.highlight.js +108 -0
- data/docs/javascripts/lib/jquery.js +9831 -0
- data/docs/javascripts/lib/jquery.tocify.js +1042 -0
- data/docs/javascripts/lib/jquery_ui.js +566 -0
- data/docs/javascripts/lib/lunr.js +1910 -0
- data/docs/stylesheets/demos/hooks_and_wrappers.scss +32 -0
- data/docs/stylesheets/print.scss +150 -0
- data/docs/stylesheets/screen.scss +10 -0
- data/lib/blocks/action_view_extensions/view_extensions.rb +1 -0
- data/lib/blocks/renderers/renderer.rb +1 -0
- data/lib/blocks/renderers/runtime_context.rb +30 -17
- data/lib/blocks/utilities/hash_with_render_strategy.rb +3 -0
- data/lib/blocks/version.rb +1 -1
- metadata +70 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3181343926f563e7c9ae1a5a7d4754a3e2a32fb
|
4
|
+
data.tar.gz: f88aa1db3c2078d5dacbea759fca59c7d9b4a1d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1720042c59c57226a0a44785b9ea646a0b79e6ff90948414d801609a3cb52253342d22772c58ec4df3a2de6959e5911c17c2e057e9fb608f2f65c5a05f344dd3
|
7
|
+
data.tar.gz: 975c4e0b9ee87b4a6b35d293c2006ed84941033ce97bcf92bd690a847ec97a69785df215fa33418370995a0be79637b39ab7d549b8a090d00f5d643488d70b47
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4
|
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
3.0.0 ()
|
2
|
+
* Complete rewrite of the blocks gem
|
3
|
+
* Extensive test coverage added
|
4
|
+
* Jenkins CI integration
|
5
|
+
* Extensive documentation added: http://hunterae.github.io/blocks/
|
6
|
+
* Blocks branding and documentation styling applied: Thanks [Alexis Gormley](https://github.com/n2diving)
|
7
|
+
|
1
8
|
2.8.0 (January 21, 2016)
|
2
9
|
* When rendering a collection of blocks through blocks.render BLOCK_NAME, collection: COLLECTION,
|
3
10
|
current_index will now be passed as a param for the options hash passed to the block. Example:
|
data/Gemfile
CHANGED
@@ -7,13 +7,20 @@ gem "capybara"
|
|
7
7
|
gem "rspec", "~> 3.6.0"
|
8
8
|
gem "arel", github: "rails/arel"
|
9
9
|
gem "rails", github: "rails/rails"
|
10
|
-
gem
|
10
|
+
gem "rack"
|
11
11
|
gem "shoulda-matchers", "~> 2.0"
|
12
12
|
gem "haml"
|
13
13
|
|
14
14
|
# Extra development utilities
|
15
|
-
gem
|
16
|
-
gem
|
15
|
+
gem "ruby_dep"
|
16
|
+
gem "guard-rspec", "~> 4.7"
|
17
17
|
gem "terminal-notifier-guard"
|
18
18
|
gem "byebug"
|
19
19
|
gem "codeclimate-test-reporter", "~> 1.0.8"
|
20
|
+
|
21
|
+
group :development, :test do
|
22
|
+
gem "jekyll"
|
23
|
+
gem "jgd"
|
24
|
+
gem "jekyll-feed", "~> 0.6"
|
25
|
+
gem "jekyll-coffeescript"
|
26
|
+
end
|
data/README.md
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
# Blocks
|
2
2
|
|
3
|
-
|
3
|
+
The Blocks gem is many things.
|
4
4
|
|
5
|
-
|
5
|
+
It acts as:
|
6
|
+
|
7
|
+
* a container for reusable blocks of code and options
|
8
|
+
* a common interface for rendering code, whether the code was defined previously in Ruby blocks, Rails partials, or proxies to other blocks of code
|
9
|
+
* a series of hooks and wrappers that can be utilized to render code before, after, and around other blocks of code, as well as before each, after each, and around each item in a collection
|
10
|
+
* a templating utility for easily building reusable and highly customizable UI components
|
11
|
+
* a means for DRYing up oft-repeated code in your layouts and views
|
12
|
+
* a simple mechanism for changing or skipping the rendering behavior for particular blocks of code
|
13
|
+
|
14
|
+
Essentially, this all boils down to the following: Blocks makes it easy to define blocks of code that can be rendered either verbatim or with replacements and modifications at some later point in time.
|
15
|
+
|
16
|
+
[![Build Status](https://travis-ci.org/hunterae/blocks.svg?branch=3-0-stable)](https://travis-ci.org/hunterae/blocks)
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Please checkout the documentation for the Blocks gem here: http://hunterae.github.io/blocks/.
|
6
21
|
|
7
22
|
## Installation
|
8
23
|
|
@@ -20,20 +35,21 @@ Or install it yourself as:
|
|
20
35
|
|
21
36
|
$ gem install blocks
|
22
37
|
|
23
|
-
##
|
38
|
+
## Development
|
24
39
|
|
25
|
-
|
40
|
+
After checking out the repo, run `bundle install` (and possibly `gem install bundler` if you don't already have bundler installed) to install dependencies. Then, run `rake` to run the tests. You can also run `bundle console` for an interactive prompt that will allow you to experiment.
|
26
41
|
|
27
|
-
##
|
42
|
+
## Documentation
|
28
43
|
|
29
|
-
|
44
|
+
The documentation is generated using [Jekyll](https://jekyllrb.com/) and hosted on the [Blocks gh-pages branch](https://github.com/hunterae/blocks/tree/gh-pages).
|
30
45
|
|
31
|
-
|
46
|
+
The static content is generated based on the source code within the [docs directory](https://github.com/hunterae/blocks/tree/3-0-stable/docs).
|
32
47
|
|
33
|
-
|
48
|
+
To run the documentation locally or make changes for a corresponding pull request, follow the steps in the [Development Section above](#development). Then run `jekyll serve` and visit http://127.0.0.1:4000/blocks/.
|
34
49
|
|
35
|
-
|
50
|
+
## Contributing
|
36
51
|
|
52
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/hunterae/blocks.
|
37
53
|
|
38
54
|
## License
|
39
55
|
|
data/_config.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
title: Blocks Docs
|
2
|
+
email: hunterae@gmail.com
|
3
|
+
description: Blocks gives you total control over how your blocks of code render.
|
4
|
+
baseurl: "/blocks" # the subpath of your site, e.g. /blog
|
5
|
+
url: "" # the base hostname & protocol for your site, e.g. http://example.com
|
6
|
+
github_username: hunterae
|
7
|
+
google_analytics: "UA-104699666-1"
|
8
|
+
markdown: kramdown
|
9
|
+
source: docs
|
10
|
+
destination: _site
|
11
|
+
plugins:
|
12
|
+
- jekyll-feed
|
13
|
+
- jekyll-coffeescript
|
14
|
+
sass:
|
15
|
+
sass_dir: _sass
|
16
|
+
style: compressed
|
17
|
+
css_dir: blocks/stylesheets
|
18
|
+
js_dir: blocks/javascripts
|
19
|
+
images_dir: blocks/images
|
20
|
+
fonts_dir: blocks/fonts
|
data/bin/deploy_docs
ADDED
data/docs/.gitignore
ADDED
data/docs/404.html
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
|
4
|
+
<style type="text/css" media="screen">
|
5
|
+
.container {
|
6
|
+
margin: 10px auto;
|
7
|
+
max-width: 600px;
|
8
|
+
text-align: center;
|
9
|
+
}
|
10
|
+
h1 {
|
11
|
+
margin: 30px 0;
|
12
|
+
font-size: 4em;
|
13
|
+
line-height: 1;
|
14
|
+
letter-spacing: -1px;
|
15
|
+
}
|
16
|
+
</style>
|
17
|
+
|
18
|
+
<div class="container">
|
19
|
+
<h1>404</h1>
|
20
|
+
|
21
|
+
<p><strong>Page not found :(</strong></p>
|
22
|
+
<p>The requested page could not be found.</p>
|
23
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Acknowledgements
|
2
|
+
|
3
|
+
The [blocks gem](http://github.com/hunterae/blocks) was written and is maintained by [Andrew Hunter](http://github.com/hunterae).
|
4
|
+
|
5
|
+
If you think this looks somewhat familiar, there's good reason for that. Any similarities you may notice with [Rails's content_for with yield](http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for) and [rendering partials in Rails](https://apidock.com/rails/ActionController/Base/render) are intentional (the proxying feature may even remind you of [Ruby's Forwardable Module](http://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html)). Part of the original reasoning for the creating this gem was to provide a common interface for rendering both Ruby blocks and Rails' partials.
|
6
|
+
|
7
|
+
Special thanks to the following people for helping advance this gem and its corresponding documentation forward:
|
8
|
+
|
9
|
+
* [Todd Fisher](https://github.com/taf2) - For helping me visualize and create the initial inception of this gem back in 2011 and understand how Ruby blocks work
|
10
|
+
* [Jon Phillips](https://github.com/elguapo1611) - For helping me work out syntax and use cases for the Blocks gem
|
11
|
+
* [Various people and teams at LivingSocial](https://www.livingsocial.com/) - For allowing and believing in me to run with an experimental and unproven technology to help my gem start to take shape into what it is today.
|
12
|
+
* [Various people at MobileCause](https://www.mobilecause.com/) - For helping me to advance my vision for this gem into what it is today and what is being documented here.
|
13
|
+
* [Alexis Gormley](https://github.com/n2diving) - For suggesting the [Slate theme](https://github.com/lord/slate) for the documentation, designing the gem's branding, and proofing the documentation.
|
@@ -0,0 +1,615 @@
|
|
1
|
+
# Defining Blocks
|
2
|
+
|
3
|
+
```erb
|
4
|
+
<% blocks.define :my_block %>
|
5
|
+
<!-- OR -->
|
6
|
+
<% blocks.define "my_block" %>
|
7
|
+
```
|
8
|
+
|
9
|
+
```haml
|
10
|
+
- blocks.define :my_block
|
11
|
+
#- OR
|
12
|
+
- blocks.define "my_block"
|
13
|
+
```
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# where builder is an instance
|
17
|
+
# of Blocks::Builder
|
18
|
+
builder.define :my_block
|
19
|
+
# OR
|
20
|
+
builder.define "my_block"
|
21
|
+
```
|
22
|
+
|
23
|
+
With Blocks, you can define a block of code for later rendering using Ruby blocks, Rails partials, and proxies to other blocks.
|
24
|
+
|
25
|
+
A block consists of a name, a hash of options, and a rendering strategy (also called its definition).
|
26
|
+
|
27
|
+
A block's name can be a symbol or a string. The underlying system treats symbols and strings the same. Therefore, any block that is defined with a String name can be accessed with its corresponding symbol name and vice-versa.
|
28
|
+
|
29
|
+
## With a Ruby Block
|
30
|
+
|
31
|
+
```erb
|
32
|
+
<% blocks.define :my_block do %>
|
33
|
+
content
|
34
|
+
<% end %>
|
35
|
+
```
|
36
|
+
|
37
|
+
```haml
|
38
|
+
- blocks.define :my_block do
|
39
|
+
content
|
40
|
+
```
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# where builder is an instance
|
44
|
+
# of Blocks::Builder
|
45
|
+
builder.define :my_block do
|
46
|
+
"content"
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
A Block may be defined as a standard Ruby block.
|
51
|
+
|
52
|
+
### With a Proc
|
53
|
+
|
54
|
+
```erb
|
55
|
+
<% my_block =
|
56
|
+
Proc.new { "content" } %>
|
57
|
+
<% blocks.define :my_block,
|
58
|
+
block: my_block %>
|
59
|
+
<!-- OR -->
|
60
|
+
<% blocks.define :my_block,
|
61
|
+
&my_block %>
|
62
|
+
```
|
63
|
+
|
64
|
+
```haml
|
65
|
+
- my_block = Proc.new { "content" }
|
66
|
+
- blocks.define :my_block,
|
67
|
+
block: my_block
|
68
|
+
-# OR
|
69
|
+
- blocks.define :my_block, &my_block
|
70
|
+
```
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# where builder is an instance
|
74
|
+
# of Blocks::Builder
|
75
|
+
my_block = Proc.new { "content" }
|
76
|
+
builder.define :my_block,
|
77
|
+
block: my_block
|
78
|
+
#OR...
|
79
|
+
builder.define :my_block, &my_block
|
80
|
+
```
|
81
|
+
|
82
|
+
It may also be defined with a Proc
|
83
|
+
|
84
|
+
### With a Lambda
|
85
|
+
|
86
|
+
```erb
|
87
|
+
<% my_block = lambda { "content" } %>
|
88
|
+
<% blocks.define :my_block,
|
89
|
+
block: my_block %>
|
90
|
+
<!-- OR -->
|
91
|
+
<% blocks.define :my_block, &my_block %>
|
92
|
+
```
|
93
|
+
|
94
|
+
```haml
|
95
|
+
Lambdas are kind of a pain in Haml
|
96
|
+
and Procs should be used instead
|
97
|
+
```
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# where builder is an instance
|
101
|
+
# of Blocks::Builder
|
102
|
+
my_block = lambda { "content" }
|
103
|
+
builder.define :my_block,
|
104
|
+
block: my_block
|
105
|
+
# OR...
|
106
|
+
builder.define :my_block, &my_block
|
107
|
+
```
|
108
|
+
|
109
|
+
It may also be defined with a Lambda
|
110
|
+
|
111
|
+
## With a Rails Partial
|
112
|
+
|
113
|
+
```erb
|
114
|
+
<%= blocks.define :my_block,
|
115
|
+
partial: "my_partial" %>
|
116
|
+
```
|
117
|
+
|
118
|
+
```haml
|
119
|
+
- blocks.define :my_block,
|
120
|
+
partial: "my_partial"
|
121
|
+
```
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
# where builder is an instance
|
125
|
+
# of Blocks::Builder
|
126
|
+
- builder.define :my_block,
|
127
|
+
partial: "my_partial"
|
128
|
+
```
|
129
|
+
|
130
|
+
A Block may be defined as a Rails partial using the "partial" keyword in the parameters. Whenever the Block gets rendered, the partial actually gets rendered.
|
131
|
+
|
132
|
+
## With a Proxy to Another Block
|
133
|
+
|
134
|
+
```erb
|
135
|
+
<% blocks.define :my_block,
|
136
|
+
with: :some_proxy_block %>
|
137
|
+
```
|
138
|
+
|
139
|
+
```haml
|
140
|
+
- blocks.define :my_block,
|
141
|
+
with: :some_proxy_block
|
142
|
+
```
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# where builder is an instance
|
146
|
+
# of Blocks::Builder
|
147
|
+
- builder.define :my_block,
|
148
|
+
with: :some_proxy_block
|
149
|
+
```
|
150
|
+
|
151
|
+
A Block may be defined as a proxy to another block using the "with" keyword in the parameters.
|
152
|
+
|
153
|
+
### Proxying to a method
|
154
|
+
|
155
|
+
```erb
|
156
|
+
<% builder.define :my_block,
|
157
|
+
with: :column %>
|
158
|
+
```
|
159
|
+
|
160
|
+
```haml
|
161
|
+
- builder.define :my_block,
|
162
|
+
with: :column
|
163
|
+
```
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
builder.define :my_block,
|
167
|
+
with: :column
|
168
|
+
```
|
169
|
+
|
170
|
+
> Where "builder" is an instance of a class that extends Blocks::Builder and has a method called "column".
|
171
|
+
|
172
|
+
The "with" keyword may also specify the name of a method that will be called on the builder instance when the block is rendered. By default, this will be an instance of Blocks::Builder.
|
173
|
+
|
174
|
+
Also, a Proxy block can point to a method on the builder instance (by default, this is an instance of Blocks::Builder).
|
175
|
+
|
176
|
+
### Proxying to a Proxy
|
177
|
+
|
178
|
+
```erb
|
179
|
+
<% blocks.define :my_block,
|
180
|
+
with: :proxy_1 %>
|
181
|
+
<% blocks.define :proxy_1,
|
182
|
+
with: :proxy_2 %>
|
183
|
+
<% blocks.define :proxy_2 do %>
|
184
|
+
My proxied proxied content
|
185
|
+
<% end %>
|
186
|
+
```
|
187
|
+
|
188
|
+
```haml
|
189
|
+
- blocks.define :my_block,
|
190
|
+
with: :proxy_1
|
191
|
+
- blocks.define :proxy_1,
|
192
|
+
with: :proxy_2
|
193
|
+
- blocks.define :proxy_2 do
|
194
|
+
My proxied proxied content
|
195
|
+
```
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
# where builder is an instance
|
199
|
+
# of Blocks::Builder
|
200
|
+
builder.define :my_block,
|
201
|
+
with: :proxy_1
|
202
|
+
builder.define :proxy_1,
|
203
|
+
with: :proxy_2
|
204
|
+
builder.define :proxy_2 do
|
205
|
+
"My proxied proxied content"
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
209
|
+
Proxy Blocks can also be chained together though separate definitions. The order of Block definitions is irrelevant - with two caveats:
|
210
|
+
|
211
|
+
1. Proxies must be setup before attempting to render them
|
212
|
+
2. If the same block name is defined multiple times with different proxy names, the first one defined will be used
|
213
|
+
|
214
|
+
## With Multiple Definitions
|
215
|
+
|
216
|
+
```erb
|
217
|
+
<% blocks.define :my_block,
|
218
|
+
partial: "my_partial" %>
|
219
|
+
<% blocks.define :my_block,
|
220
|
+
with: :my_proxy %>
|
221
|
+
<% blocks.define :my_block do %>
|
222
|
+
My Block Definition
|
223
|
+
<% end %>
|
224
|
+
```
|
225
|
+
|
226
|
+
```haml
|
227
|
+
- blocks.define :my_block,
|
228
|
+
partial: "my_partial"
|
229
|
+
- blocks.define :my_block,
|
230
|
+
with: :my_proxy
|
231
|
+
- blocks.define :my_block do
|
232
|
+
My Block Definition
|
233
|
+
```
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
# where builder is an instance
|
237
|
+
# of Blocks::Builder
|
238
|
+
builder.define :my_block,
|
239
|
+
partial: "my_partial"
|
240
|
+
builder.define :my_block,
|
241
|
+
with: :my_proxy
|
242
|
+
builder.define :my_block do
|
243
|
+
"My Block Definition"
|
244
|
+
end
|
245
|
+
```
|
246
|
+
|
247
|
+
> :my_block will use the partial: "my_partial" when rendered
|
248
|
+
|
249
|
+
When multiple definitions for the same block name are provided, Blocks will utilize the first definition to occur, whether it's a Ruby block, a Rails partial, or a Proxy to another block.
|
250
|
+
|
251
|
+
## Without a Definition
|
252
|
+
|
253
|
+
```erb
|
254
|
+
<% blocks.define :my_block %>
|
255
|
+
```
|
256
|
+
|
257
|
+
```haml
|
258
|
+
- blocks.define :my_block
|
259
|
+
```
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
# where builder is an instance
|
263
|
+
# of Blocks::Builder
|
264
|
+
builder.define :my_block
|
265
|
+
```
|
266
|
+
|
267
|
+
Blocks do not need to have a definition provided. When they are rendered, no output is generated.
|
268
|
+
|
269
|
+
This, in itself, is not particularly useful, but can become more and more useful when block options and hooks and wrappers are combined.
|
270
|
+
|
271
|
+
## With a Collection
|
272
|
+
|
273
|
+
```erb
|
274
|
+
<% blocks.define :my_block,
|
275
|
+
collection: [1, 2, 3, 4] do |item| %>
|
276
|
+
<li>Item: <%= item %></li>
|
277
|
+
<% end %>
|
278
|
+
```
|
279
|
+
|
280
|
+
```haml
|
281
|
+
- blocks.define :my_block,
|
282
|
+
collection: [1, 2, 3, 4] do |item|
|
283
|
+
%li= "Item: #{item}"
|
284
|
+
```
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
# where builder is an instance
|
288
|
+
# of Blocks::Builder
|
289
|
+
builder.define :my_block,
|
290
|
+
collection: [1, 2, 3, 4] do |item|
|
291
|
+
builder.content_tag :li,
|
292
|
+
"Item #{item}"
|
293
|
+
end
|
294
|
+
```
|
295
|
+
|
296
|
+
A collection may be defined for a block, in which case, when that block is rendered, it will actually render the block multiple times, once for each item in the collection.
|
297
|
+
|
298
|
+
<aside class="warning">
|
299
|
+
When the block definition is a Ruby block, the block should be prepared to take each item from the collection as a parameter.
|
300
|
+
</aside>
|
301
|
+
|
302
|
+
|
303
|
+
### With an Alias
|
304
|
+
|
305
|
+
```erb
|
306
|
+
<% blocks.define :my_block,
|
307
|
+
collection: [1, 2, 3, 4],
|
308
|
+
as: :item,
|
309
|
+
partial: "my_partial" %>
|
310
|
+
```
|
311
|
+
|
312
|
+
```haml
|
313
|
+
- blocks.define :my_block,
|
314
|
+
collection: [1, 2, 3, 4],
|
315
|
+
as: :item,
|
316
|
+
partial: "my_partial"
|
317
|
+
```
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
# where builder is an instance
|
321
|
+
# of Blocks::Builder
|
322
|
+
builder.define :my_block,
|
323
|
+
collection: [1, 2, 3, 4],
|
324
|
+
as: :item,
|
325
|
+
partial: "my_partial"
|
326
|
+
```
|
327
|
+
|
328
|
+
Additionally, you can set an alias for each item in the collection as the collection is iterated over. This is done using the "as" option.
|
329
|
+
|
330
|
+
If the block being rendered is a partial, it will alias each item in the collection with the specified option (i.e. the value of the "as" option will become the name of the variable available in the partial being rendered and will contain each item in the collection being rendered). Additionally, "current_index" will also be a variable that can be accessed within the partial, and will correspond to the item's index in the collection.
|
331
|
+
|
332
|
+
If the block being rendered is not a partial, it will store the alias name as a key in an options hash that will be optionally passed to the block when it is rendered. Additionally, "current_index" will store the item's current index within the collection.
|
333
|
+
|
334
|
+
### Without an Alias
|
335
|
+
|
336
|
+
When no alias is specified and the block being rendered is a partial, it will alias each item in the collection as "object" (i.e. "object" will become the name of the variable available in the partial being rendered and will contain each item in the collection being rendered).
|
337
|
+
Additionally, "current_index" will also be a variable that can be accessed within the partial, and will correspond to the item's index in the collection.
|
338
|
+
|
339
|
+
If the block being rendered is not a partial, it will store "object" as a key in an options hash that will be optionally passed to the block when it is rendered. Additionally, "current_index" will store the item's current index within the collection.
|
340
|
+
|
341
|
+
## With Options
|
342
|
+
|
343
|
+
```erb
|
344
|
+
<% blocks.define :my_block,
|
345
|
+
a: "First setting of a" %>
|
346
|
+
<% blocks.define :my_block,
|
347
|
+
a: "Second setting of a",
|
348
|
+
b: "First setting of b" %>
|
349
|
+
<% blocks.define :my_block,
|
350
|
+
a: "Third setting of a",
|
351
|
+
b: "Second setting setting of b",
|
352
|
+
c: "First setting of c" %>
|
353
|
+
```
|
354
|
+
|
355
|
+
```haml
|
356
|
+
- blocks.define :my_block,
|
357
|
+
a: "First setting of a"
|
358
|
+
- blocks.define :my_block,
|
359
|
+
a: "Second setting of a",
|
360
|
+
b: "First setting of b"
|
361
|
+
- blocks.define :my_block,
|
362
|
+
a: "Third setting of a",
|
363
|
+
b: "Second setting setting of b",
|
364
|
+
c: "First setting of c"
|
365
|
+
```
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
# where builder is an instance
|
369
|
+
# of Blocks::Builder
|
370
|
+
builder.define :my_block,
|
371
|
+
a: "First setting of a"
|
372
|
+
builder.define :my_block,
|
373
|
+
a: "Second setting of a",
|
374
|
+
b: "First setting of b"
|
375
|
+
builder.define :my_block,
|
376
|
+
a: "Third setting of a",
|
377
|
+
b: "Second setting setting of b",
|
378
|
+
c: "First setting of c"
|
379
|
+
```
|
380
|
+
|
381
|
+
> After running the above code, the options for :my_block will look like this:
|
382
|
+
|
383
|
+
```JavaScript
|
384
|
+
{
|
385
|
+
a: "First setting of a",
|
386
|
+
b: "First setting of b",
|
387
|
+
c: "First setting of c"
|
388
|
+
}
|
389
|
+
```
|
390
|
+
|
391
|
+
Blocks are maintaining a merged, mutable options hash. This set is mutated with repeated calls to "define".
|
392
|
+
|
393
|
+
When the same option key is used in successive "define" calls, the first call to define a key's value is given priority.
|
394
|
+
|
395
|
+
### Indifferent Access
|
396
|
+
|
397
|
+
```erb
|
398
|
+
<% blocks.define :my_block,
|
399
|
+
a: "First setting of a",
|
400
|
+
"b" => "First setting of b" %>
|
401
|
+
<% blocks.define :my_block,
|
402
|
+
"a" => "Second setting of a",
|
403
|
+
b: "Second setting of b" %>
|
404
|
+
```
|
405
|
+
|
406
|
+
```haml
|
407
|
+
- blocks.define :my_block,
|
408
|
+
a: "First setting of a",
|
409
|
+
"b" => "First setting of b"
|
410
|
+
- blocks.define :my_block,
|
411
|
+
"a" => "Second setting of a",
|
412
|
+
b: "Second setting of b"
|
413
|
+
```
|
414
|
+
|
415
|
+
```ruby
|
416
|
+
# where builder is an instance of
|
417
|
+
# Blocks::Builder
|
418
|
+
builder.define :my_block,
|
419
|
+
a: "First setting of a",
|
420
|
+
"b" => "First setting of b"
|
421
|
+
builder.define :my_block,
|
422
|
+
"a" => "Second setting of a",
|
423
|
+
b: "First setting of b"
|
424
|
+
```
|
425
|
+
|
426
|
+
> After running the above code, the options for :my_block will look like this:
|
427
|
+
|
428
|
+
```JavaScript
|
429
|
+
{
|
430
|
+
a: "First setting of a",
|
431
|
+
b: "First setting of b"
|
432
|
+
}
|
433
|
+
```
|
434
|
+
|
435
|
+
Like the name of the block itself, the options hash does not care whether a symbol or a string is provided as a hash key; they are treated the same.
|
436
|
+
|
437
|
+
### Deep Merging of Options
|
438
|
+
|
439
|
+
```erb
|
440
|
+
<% blocks.define :my_block,
|
441
|
+
a: 1,
|
442
|
+
shared_key: {
|
443
|
+
a: "a1"
|
444
|
+
} %>
|
445
|
+
<% blocks.define :my_block,
|
446
|
+
b: 1,
|
447
|
+
shared_key: {
|
448
|
+
a: "a2",
|
449
|
+
b: "b1"
|
450
|
+
} %>
|
451
|
+
```
|
452
|
+
|
453
|
+
```haml
|
454
|
+
- blocks.define :my_block,
|
455
|
+
a: 1,
|
456
|
+
shared_key: { a: "a1" }
|
457
|
+
- blocks.define :my_block,
|
458
|
+
b: 1,
|
459
|
+
shared_key: { a: "a2",
|
460
|
+
b: "b1" }
|
461
|
+
```
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
# where builder is an instance of
|
465
|
+
# Blocks::Builder
|
466
|
+
builder.define :my_block,
|
467
|
+
a: 1,
|
468
|
+
shared_key: {
|
469
|
+
a: "a1"
|
470
|
+
}
|
471
|
+
builder.define :my_block,
|
472
|
+
b: 1,
|
473
|
+
shared_key: {
|
474
|
+
a: "a2",
|
475
|
+
b: "b1"
|
476
|
+
}
|
477
|
+
```
|
478
|
+
|
479
|
+
> After running the above code, the options for :my_block will look like this:
|
480
|
+
|
481
|
+
```JavaScript
|
482
|
+
{
|
483
|
+
a: 1,
|
484
|
+
shared_key: {
|
485
|
+
a: "a1",
|
486
|
+
b: "b1"
|
487
|
+
},
|
488
|
+
b: 1
|
489
|
+
}
|
490
|
+
```
|
491
|
+
|
492
|
+
When the same option key is used in successive "define" calls and the values for the duplicate key are both hashes, they are deep merged, giving precedence for duplicate nested keys to whatever key was defined first.
|
493
|
+
|
494
|
+
### Runtime and Default Options
|
495
|
+
|
496
|
+
```erb
|
497
|
+
<% blocks.define :my_block,
|
498
|
+
a: "standard",
|
499
|
+
b: "standard",
|
500
|
+
runtime: {
|
501
|
+
a: "runtime",
|
502
|
+
c: "runtime"
|
503
|
+
},
|
504
|
+
defaults: {
|
505
|
+
a: "default",
|
506
|
+
d: "default"
|
507
|
+
} %>
|
508
|
+
```
|
509
|
+
|
510
|
+
```haml
|
511
|
+
- blocks.define :my_block,
|
512
|
+
a: "standard",
|
513
|
+
b: "standard",
|
514
|
+
runtime: { a: "runtime",
|
515
|
+
c: "runtime" },
|
516
|
+
defaults: { a: "default",
|
517
|
+
d: "default" }
|
518
|
+
```
|
519
|
+
|
520
|
+
```ruby
|
521
|
+
# where builder is an instance of
|
522
|
+
# Blocks::Builder
|
523
|
+
builder.define :my_block,
|
524
|
+
a: "standard",
|
525
|
+
b: "standard",
|
526
|
+
runtime: {
|
527
|
+
a: "runtime",
|
528
|
+
c: "runtime"
|
529
|
+
},
|
530
|
+
defaults: {
|
531
|
+
a: "default",
|
532
|
+
d: "default"
|
533
|
+
}
|
534
|
+
```
|
535
|
+
|
536
|
+
> After running the above code, the options for :my_block will look like this:
|
537
|
+
|
538
|
+
```JavaScript
|
539
|
+
{
|
540
|
+
a: "runtime",
|
541
|
+
c: "runtime",
|
542
|
+
b: "standard",
|
543
|
+
d: "default"
|
544
|
+
}
|
545
|
+
```
|
546
|
+
|
547
|
+
There are three levels of options: runtime, standard, and default. They are given merge precedence in that order.
|
548
|
+
|
549
|
+
Runtime options are specified as a nested hash with "runtime" as the key.
|
550
|
+
|
551
|
+
Default options are specified as a nested hash with "defaults" as the key.
|
552
|
+
|
553
|
+
All other keys in the hash are considered standard options.
|
554
|
+
|
555
|
+
## With Parameters
|
556
|
+
|
557
|
+
```erb
|
558
|
+
<% blocks.define :my_block,
|
559
|
+
a: 1 do |options| %>
|
560
|
+
My options are <%= options.inspect %>
|
561
|
+
<% end %>
|
562
|
+
```
|
563
|
+
|
564
|
+
```haml
|
565
|
+
- blocks.define :my_block,
|
566
|
+
a: 1 do |options|
|
567
|
+
My options are
|
568
|
+
= options.inspect
|
569
|
+
```
|
570
|
+
|
571
|
+
```ruby
|
572
|
+
# where builder is an instance of
|
573
|
+
# Blocks::Builder
|
574
|
+
builder.define :my_block,
|
575
|
+
a: 1 do |options|
|
576
|
+
"My options are #{options.inspect}"
|
577
|
+
end
|
578
|
+
```
|
579
|
+
> If this block were rendered, the output would be:
|
580
|
+
|
581
|
+
```
|
582
|
+
My options are { a: 1 }
|
583
|
+
```
|
584
|
+
|
585
|
+
Every block that are defined with a Ruby block or a proxy to a Block that is defined with a Ruby block (or a proxy to a proxy to ... to a block that is defined with a Ruby block) can optionally receive the merged options as a parameter.
|
586
|
+
|
587
|
+
## Without a Name
|
588
|
+
|
589
|
+
```erb
|
590
|
+
See Ruby tab
|
591
|
+
```
|
592
|
+
|
593
|
+
```haml
|
594
|
+
See Ruby tab
|
595
|
+
```
|
596
|
+
|
597
|
+
```ruby
|
598
|
+
# where builder is an instance of
|
599
|
+
# Blocks::Builder
|
600
|
+
anonymous_block = builder.define do
|
601
|
+
"hello"
|
602
|
+
end
|
603
|
+
|
604
|
+
puts anonymous_block.name
|
605
|
+
# Outputs "anonymous_block_1"
|
606
|
+
|
607
|
+
puts anonymous_block.anonymous
|
608
|
+
# Outputs true
|
609
|
+
```
|
610
|
+
|
611
|
+
Blocks may be defined without a name. When no block name is provided, an anonymous name will be generated.
|
612
|
+
|
613
|
+
<aside class="notice">
|
614
|
+
This is really only useful directly within the Ruby code or when extending the Blocks::Builder class.
|
615
|
+
</aside>
|