nice_partials 0.1.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a2bc1c656f72b37d7766bd5353a4320fc516dd2bfa808352f8b96217991c78b
4
- data.tar.gz: fefb7742857fec22b402f714ce10e5d4e6b33279b3fe7abdb84b1408b31cb38c
3
+ metadata.gz: b3b70755595cff02588aa600004e44ec9f20847a4fdd026e0326876a2cad7f52
4
+ data.tar.gz: 24e42267606eb6a56ed481d2b82d137210618dff3282f6586036aa68bfad71c0
5
5
  SHA512:
6
- metadata.gz: 40b811eb0e0231da0ed04d023af718200400880dffac5e64cb8f8c80de2f30ae187fb0e4c43235d305f1a60e74c321b370c4ff6d07a18fc975becea8c5faa975
7
- data.tar.gz: 9ae278eb935fc27bb1f7ae46bb71efcdbf84d3ef0157e0897f4412208a1c8864251a8f8cec5ea9961d01c1884f451b6695c2a8862d2456c4f7ee2698a124362a
6
+ metadata.gz: de339636e922f606a268eb0a9888686e3f0c6b3bdd0f874c8c50998a55437dfc8dff7f4a1c4293d4814277f75a49a959aa47ba9318ad9d9898d651c87d5fc6f8
7
+ data.tar.gz: ed7d3ff442df563d12aba16982a7a3ecae8a5f5b3022255e733bd2b5fd816c828064ddb659162839ef234fc26b22bd3f3a3a6be175e918a5518688a5cfe8bde2
data/CHANGELOG.md CHANGED
@@ -1,9 +1,221 @@
1
1
  ## CHANGELOG
2
2
 
3
+ * Fix rendering with special characters in a view path.
4
+
5
+ Ref: https://github.com/bullet-train-co/nice_partials/pull/70
6
+
7
+ * Seed Nice Partials content from `local_assigns`
8
+
9
+ Previously, the only way to assign content to a Nice Partial was through passing a block:
10
+
11
+ ```erb
12
+ # app/views/posts/show.html.erb
13
+ <%= render "posts/post", byline: "Some guy" %>
14
+
15
+ # app/views/posts/_post.html.erb
16
+ <%= render "card" do |partial| %>
17
+ <% partial.title "Hello there" %>
18
+ <% partial.byline byline %> <%# `byline` comes from the outer `render` call above. %>
19
+ <% end %>
20
+
21
+ Now, Nice Partials will automatically use Rails' `local_assigns`, which contain any `locals:` passed to `render`, as the seed for content. So this works:
22
+
23
+ ```erb
24
+ <%= render "card", title: "Hello there", byline: byline %>
25
+ ```
26
+
27
+ And the `card` partial is now oblivious to whether its `title` or `byline` were passed as render `locals:` or through the usual assignments in a block.
28
+
29
+ ```erb
30
+ # app/views/_card.html.erb
31
+ <%= partial.title %> written by <%= partial.byline %>
32
+ ```
33
+
34
+ Previously to get this behavior you'd need to write:
35
+
36
+ ```erb
37
+ # app/views/_card.html.erb
38
+ <%= partial.title.presence || local_assigns[:title] %> written by <%= partial.byline.presence || local_assigns[:byline] %>
39
+ ```
40
+
41
+ Passing extra content via a block appends:
42
+
43
+ ```erb
44
+ <%= render "card", title: "Hello there" do |partial| %>
45
+ <% partial.title ", and welcome!" %> # Calling `partial.title` outputs `"Hello there, and welcome!"`
46
+ <% end %>
47
+ ```
48
+
49
+ * Add `NicePartials::Partial#slice`
50
+
51
+ Returns a Hash of the passed keys with their contents, useful for passing to other render calls:
52
+
53
+ ```erb
54
+ <%= render "card", partial.slice(:title, :byline) %>
55
+ ```
56
+
57
+ * Fix `partial.helpers` accidentally adding methods to `ActionView::Base`
58
+
59
+ When using `partial.helpers {}`, internally `class_eval` would be called on the Partial instance, and through `delegate_missing_to` passed on to the view context and thus we'd effectively have a global method, exactly as if we'd just used regular Rails view helpers.
60
+
61
+ * Let partials respond to named content sections
62
+
63
+ ```erb
64
+ <% partial.content_for :title, "Title content" %> # Before
65
+ <% partial.title "Title content" %> # After
66
+
67
+ # Which can then be output
68
+ <% partial.title %> # => "Title content"
69
+ <% partial.title? %> # => true
70
+ ```
71
+
72
+ Note, `title` responds to `present?` so rendering could also be made conditional with:
73
+
74
+ ```erb
75
+ <% partial.title if partial.title? %> # Instead of this…
76
+ <% partial.title.presence %> # …you can do this
77
+ ```
78
+
79
+ #### Passing procs or components
80
+
81
+ Procs and objects that implement `render_in`, like ViewComponents, can also be appended as content:
82
+
83
+ ```erb
84
+ <% partial.title { "some content" } %>
85
+ <% partial.title TitleComponent.new(Current.user) %>
86
+ ```
87
+
88
+ #### Capturing `options`
89
+
90
+ Options can also be captured and output:
91
+
92
+ ```erb
93
+ <% partial.title class: "text-m4" %> # partial.title.options # => { class: "text-m4" }
94
+
95
+ # When output `to_s` is called and options automatically pipe through `tag.attributes`:
96
+ <h1 <% partial.title.options %>> # => <h1 class="text-m4">
97
+ ```
98
+
99
+ #### Proxying to the view context and appending content
100
+
101
+ A content section appends to its content when calling any view context method on it, e.g.:
102
+
103
+ ```erb
104
+ <% partial.title.t ".title" %>
105
+ <% partial.title.link_to @document.name, @document %>
106
+ <% partial.title.render "title", user: Current.user %>
107
+ <% partial.title.render TitleComponent.new(Current.user) do |component| %>
108
+ <% … %>
109
+ <% end %>
110
+ ```
111
+
112
+ #### Building elements with `tag` proxy
113
+
114
+ These `tag` calls let you generate elements based on the stored content and options:
115
+
116
+ ```erb
117
+ <% partial.title "content", class: "post-title" %> # Adding some content and options…
118
+ <% partial.title.h2 %> # => <h2 class="post-title">content</h2>
119
+ <% partial.title.h2 "more" %> # => <h2 class="post-title">contentmore</h2>
120
+ ```
121
+
122
+ * Add `NicePartials#t` to aid I18n.
123
+
124
+ When using NicePartials with I18n you end up with lots of calls that look like:
125
+
126
+ ```erb
127
+ <% partial.title t(".title") %>
128
+ <% partial.description t(".header") %>
129
+ <% partial.byline t("custom.key") %>
130
+ ```
131
+
132
+ With NicePartials' `t` method, you can write the above as:
133
+
134
+ ```erb
135
+ <% partial.t :title, description: :header, byline: "custom.key" %>
136
+ ```
137
+
138
+ Clarifying what keys get converted to what content sections on the partial rather than the syntax heavy `partial.… t(".…")`.
139
+
140
+ Like the Rails built-in `t` method, it's just a shorthand alias for `translate` so that's available too.
141
+
142
+ * Add `Partial#content_from`
143
+
144
+ `content_from` lets a partial extract contents from another partial.
145
+ Additionally, contents can be renamed by passing a hash:
146
+
147
+ ```erb
148
+ <% partial.title "Hello there" %>
149
+ <% partial.byline "Somebody" %>
150
+
151
+ <%= render "shared/title" do |cp| %>
152
+ # Here the inner partial `cp` accesses the outer partial through `partial`
153
+ # extracting the `title` and `byline` contents.
154
+ # `byline` is renamed to `name` in `cp`.
155
+ <% cp.content_from partial, :title, byline: :name %>
156
+ <% end %>
157
+ ```
158
+
159
+ ### 0.1.9
160
+
161
+ * Remove need to insert `<% yield p = np %>` in partials.
162
+
163
+ Nice Partials now automatically captures blocks passed to `render`.
164
+ Instead of `p`, a `partial` method has been added to access the
165
+ current `NicePartials::Partial` object.
166
+
167
+ Here's a script to help update your view code:
168
+
169
+ ```ruby
170
+ files_to_inspect = []
171
+
172
+ Dir["app/views/**/*.html.erb"].each do |path|
173
+ if contents = File.read(path).match(/(<%=? yield\(?.*? = np\)? %>\n+)/m)&.post_match
174
+ files_to_inspect << path if contents.match?(/render.*?do \|/)
175
+
176
+ contents.gsub! /\bp\.(?=yield|helpers|content_for|content_for\?)/, "partial."
177
+ File.write path, contents
178
+ end
179
+ end
180
+
181
+ if files_to_inspect.any?
182
+ puts "These files had render calls with a block parameter and likely require some manual edits:"
183
+ puts files_to_inspect
184
+ else
185
+ puts "No files with render calls with a block parameter found, you're likely all set"
186
+ end
187
+ ```
188
+
189
+ * Support manual `yield`s in partials.
190
+
191
+ Due to the automatic yield support above, support has also been added for manual `yield some_object` calls.
192
+
193
+ Nice Partials automatically appends the `partial` to the yielded arguments, so you can
194
+ change `render … do |some_object|` to `render … do |some_object, partial|`.
195
+
196
+ * Deprecate `p` as the partial object access. Use `partial` instead.
197
+
198
+ * Expose `partial.yield` to access the captured output buffer.
199
+
200
+ Lets you access what a `<%= yield %>` call returned, like this:
201
+
202
+ ```erb
203
+ <%= render "card" do %>
204
+ This is the content of the internal output buffer
205
+ <% end %>
206
+ ```
207
+
208
+ ```erb
209
+ # app/views/cards/_card.html.erb
210
+ # This can be replaced with `partial.yield`.
211
+ <%= yield %> # Will output "This is the content of the internal output buffer"
212
+ ```
213
+
214
+ ### 0.1.7
215
+
3
216
  * Rely on `ActiveSupport.on_load :action_view`
4
217
  * Add support for Ruby 3.0
5
218
 
6
219
  ### 0.1.0
7
220
 
8
221
  * Initial release
9
-
data/Gemfile CHANGED
@@ -1,7 +1,17 @@
1
1
  source "https://rubygems.org"
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
2
3
 
3
4
  gemspec
4
5
 
5
6
  gem "minitest"
6
7
  gem "rake"
7
8
  gem "irb"
9
+
10
+ if ENV["RAILS_MAIN"]
11
+ gem "rails", github: "rails/rails", branch: "main"
12
+ else
13
+ gem "rails"
14
+ end
15
+
16
+ gem "view_component"
17
+ gem "capybara"
data/README.md CHANGED
@@ -1,136 +1,254 @@
1
- # nice_partials [![[version]](https://badge.fury.io/rb/nice_partials.svg)](https://badge.fury.io/rb/nice_partials) [![[travis]](https://travis-ci.org/andrewculver/nice_partials.svg)](https://travis-ci.org/andrewculver/nice_partials)
1
+ # nice_partials [![[version]](https://badge.fury.io/rb/nice_partials.svg)](https://badge.fury.io/rb/nice_partials)
2
2
 
3
- Nice Partials extends the concept of [`content_for` blocks and `yield`](https://guides.rubyonrails.org/layouts_and_rendering.html#using-the-content-for-method) for those times when a partial needs to provide one or more named "content areas" or "slots". This thin, optional layer of magic helps make traditional Rails view partials an even better fit for extracting components from your views, like so:
3
+ Nice Partials adds ad-hoc named content areas, or sections, to Action View partials with a lot of extra power on top.
4
+
5
+ Everything happens through a new `partial` method, which at the base of it have method shorthands for partial specific `content_for` and `content_for?`s.
6
+
7
+ See, here we're outputting the `image`, `title`, and `body` sections:
4
8
 
5
9
  `app/views/components/_card.html.erb`:
6
10
  ```html+erb
7
11
  <div class="card">
8
- <%= p.yield :image %>
12
+ <%= partial.image %> # Same as `partial.content_for :image`
9
13
  <div class="card-body">
10
- <h5 class="card-title"><%= title %></h5>
11
- <% if p.content_for? :body %>
14
+ <h5 class="card-title"><%= partial.title %></h5>
15
+ <% if partial.body? %>
12
16
  <p class="card-text">
13
- <%= p.yield :body %>
17
+ <%= partial.body %>
14
18
  </p>
15
19
  <% end %>
16
20
  </div>
17
21
  </div>
18
22
  ```
19
23
 
20
- These partials can still be utilized with a standard `render` call, but you can specify how to populate the content areas like so:
24
+ Then in `render` we populate them:
21
25
 
22
26
  ```html+erb
23
- <%= render 'components/card', title: 'Some Title' do |p| %>
24
- <% p.content_for :body do %>
25
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
26
- tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
27
- <strong>quis nostrud exercitation ullamco laboris</strong> nisi ut aliquip
28
- ex ea commodo consequat.
27
+ <%= render "components/card", title: "Some Title" do |partial| %>
28
+ <% partial.title t(".title") %> # Same as `partial.content_for :title, t(".title")`
29
+
30
+ <% partial.body do %>
31
+ Lorem ipsum dolor sit amet,
29
32
  <% end %>
30
33
 
31
- <% p.content_for :image do %>
32
- <%= image_tag image_path('example.jpg'), alt: 'An example image' %>
34
+ <% partial.image do %>
35
+ <%= image_tag image_path("example.jpg"), alt: "An example image" %>
33
36
  <% end %>
34
37
  <% end %>
35
38
  ```
36
39
 
37
- Nice Partials is a lightweight and hopefully more Rails-native alternative to [ViewComponent](http://viewcomponent.org). It aims to provide many of the same benefits as ViewComponent while requiring less ceremony. This specific approach originated with [Bullet Train](https://bullettrain.co)'s "Field Partials" and was later reimagined and completely reimplemented by Dom Christie.
40
+ So far these uses are pretty similar to Rails' global `content_for` & `content_for?`, except these sections are local to the specific partial, so there's no clashing or leaking.
38
41
 
42
+ ### More-in depth compared to regular Rails partials
39
43
 
40
- ## Sponsored By
44
+ Consider this regular Rails partials rendering:
41
45
 
42
- <a href="https://bullettrain.co" target="_blank">
43
- <img src="https://github.com/CanCanCommunity/cancancan/raw/develop/logo/bullet_train.png" alt="Bullet Train" width="400"/>
44
- </a>
45
- <br/>
46
- <br/>
46
+ ```html+erb
47
+ <%= render "components/card" do %>
48
+ <% content_for :title, "Title content" %>
49
+ <% end %>
47
50
 
48
- > Would you like to support Nice Partials development and have your logo featured here? [Reach out!](http://twitter.com/andrewculver)
51
+ # app/views/components/_card.html.erb
52
+ <%= yield :title %>
53
+ <%= yield %>
54
+ ```
55
+
56
+ There's a number of gotchas here:
49
57
 
58
+ - The `content_for` writes to `:title` across every partial, thus leaking.
59
+ - The rendering block isn't called until `<%= yield %>` is, so the `content_for` isn't called and `<%= yield :title %>` outputs nothing.
50
60
 
51
- ## Benefits of Nice Partials
61
+ With Nice Partials the yield is automatic and we can write content for just that partial without leaking:
62
+
63
+ ```html+erb
64
+ <%= render "components/card" do |partial| %>
65
+ <% partial.title "Title content" %>
66
+ <% end %>
67
+
68
+ # app/views/components/_card.html.erb
69
+ <%= partial.title %>
70
+ ```
71
+
72
+ This happens because Nice Partials checks the partial source code for any `yield` calls that calls Rails' `capture` helper — e.g. `yield` and `yield something` but not `yield :title`. If there's no capturing yields Nice Partials calls `capture` for you.
73
+
74
+ This means Nice Partials also respect existing yield calls in your partial, so you can upgrade existing partials bit by bit or not at all if you don't want to.
52
75
 
53
76
  Nice Partials:
54
77
 
55
- - is just regular Rails view partials like you're used to.
56
- - reduces the friction when extracting components.
57
- - only ends up in the specific partials you need its functionality in.
58
- - reduces context switching.
59
- - allows isolated helper logic alongside your partial view code.
60
- - doesn't require any upgrades to existing partials for interoperability.
61
- - are still testable!
78
+ - are still regular Rails view partials.
79
+ - reduces the friction when extracting components.
80
+ - only ends up in the specific partials you need the functionality.
81
+ - reduces context switching.
82
+ - allows isolated helper logic alongside your partial view code.
83
+ - doesn't require any upgrades to existing partials for interoperability.
84
+ - are still testable!
62
85
 
86
+ Nice Partials are a lightweight and more Rails-native alternative to [ViewComponent](http://viewcomponent.org). Providing many of the same benefits as ViewComponent with less ceremony.
63
87
 
64
- ## Can't I do the same thing without Nice Partials?
88
+ ## What extra powers does `partial` give me?
65
89
 
66
- You can almost accomplish the same thing without Nice Partials, but in practice you end up having to flush the content buffers after using them, leading to something like this:
90
+ Having a `partial` object lets us add abstractions that are hard to replicate in standard Rails partials.
91
+
92
+ ### Passing content from the render call
93
+
94
+ Nice Partials will use Action View's `local_assigns`, which stores any `locals` passed to `render`, as the basis for contents.
95
+
96
+ Given a partial like
67
97
 
68
98
  ```html+erb
69
- <div class="card">
70
- <%= yield :image %>
71
- <% content_for :image, flush: true do '' end %>
72
- <div class="card-body">
73
- <h5 class="card-title"><%= title %></h5>
74
- <% if content_for? :body %>
75
- <p class="card-text">
76
- <%= yield :body %>
77
- <% content_for :body, flush: true do '' end %>
78
- </p>
79
- <% end %>
80
- </div>
81
- </div>
99
+ <%# app/views/components/_card.html.erb %>
100
+ <%= partial.title %> written by <%= partial.byline %>
82
101
  ```
83
102
 
84
- Earlier iterations of Nice Partials aimed to simply clean up this syntax with helper methods like `flush_content_for`, but because the named content buffers were in a global namespace, it was also possible to accidentally create situations where two partials with a `:body` content area would end up interfering with each other, depending on the order they're nested and rendered.
103
+ Can then be used like this:
85
104
 
86
- Nice Partials resolves the last-mile issues with standard view partials and content buffers by introducing a small, generic object that helps transparently namespace your named content buffers. This same object can also be used to define helper methods specific to your partial that are isolated from the global helper namespace.
105
+ ```html+erb
106
+ <%= render "components/card", title: "Hello there", byline: "Some guy" do |partial| %>
107
+ <% partial.byline ", who writes stuff" %>
108
+ <% end %>
109
+ ```
87
110
 
111
+ This will then output "Hello there written by Some guy, who writes stuff"
88
112
 
89
- ## Setup
113
+ You can also use `slice` to pass on content from an outer partial:
90
114
 
91
- Add to your `Gemfile`:
115
+ ```html+erb
116
+ <%= render "components/card", partial.slice(:title, :byline) %>
117
+ ```
92
118
 
93
- ```ruby
94
- gem "nice_partials"
119
+ ### Appending content from the view into a section
120
+
121
+ Nice Partials supports calling any method on `ActionView::Base`, like the helpers shown here, and then have them auto-append to the section.
122
+
123
+ ```html+erb
124
+ <%= render "components/card" do |partial| %>
125
+ <% partial.title.t ".title" %>
126
+ <% partial.body.render "form", tangible_thing: @tangible_thing %>
127
+ <% partial.image.image_tag image_path("example.jpg"), alt: "An example image" %>
128
+ <% end %>
129
+ ```
130
+
131
+ ### I18n: translating and setting multiple keys at a time
132
+
133
+ `partial.t` is a shorthand to translate and assign multiple keys at once:
134
+
135
+ ```html+erb
136
+ <% partial.t :title, description: :header, byline: "custom.key" %>
137
+
138
+ # The above is the same as writing:
139
+ <% partial.title t(".title") %>
140
+ <% partial.description t(".header") %>
141
+ <% partial.byline t("custom.key") %>
142
+ ```
143
+
144
+ ### Capturing options in the rendering block and building HTML tags in the partial
145
+
146
+ You can pass keyword options to a writer method and they'll be auto-added to `partial.x.options`, like so:
147
+
148
+ ```html+erb
149
+ <%= render "components/card" do |partial| %>
150
+ <% partial.title "Title content", class: "text-m4", data: { controller: "title" } %>
151
+ <% end %>
152
+
153
+ # app/views/components/_card.html.erb:
154
+ # From the render above `title.options` now contain `{ class: "text-m4", data: { controller: "title" } }`.
155
+ # The options can be output via `<%=` and are automatically run through `tag.attributes` to be converted to HTML attributes.
156
+
157
+ <h1 <%= partial.title.options %>><%= partial.title %></h1> # => <h1 class="text-m4" data-controller="title">Title content</h1>
158
+ ```
159
+
160
+ `partial` also supports auto-generating an element by calling any of Rails' `tag` methods e.g.:
161
+
162
+ ```html+erb
163
+ # This shorthand gets us the same h1 element from the previous example:
164
+ <%= partial.title.h1 %> # => <h1 class="text-m4" data-controller="title">Title content</h1>
165
+
166
+ # Internally, this is similar to doing:
167
+ <%= tag.h1 partial.title.to_s, partial.title.options %>
95
168
  ```
96
169
 
97
- ## Usage
170
+ ### Yielding tag builders into the rendering block
98
171
 
99
- ### When to use Nice Partials
172
+ The above example showed sending options from the rendering block into the partial and having it construct elements.
100
173
 
101
- You only need to use Nice Partials when:
174
+ But the partial can also prepare tag builders that the rendering block can then extend and finalize:
102
175
 
103
- - you want to define one or more named content areas in your partial. If you don't have multiple named content areas in your partial, you could just pass your content into the partial using the standard block and `yield` approach.
176
+ ```html+erb
177
+ <% render "components/card" do |partial|
178
+ <% partial.title { |tag| tag.h1 "Title content" } %>
179
+ <% end %>
104
180
 
105
- - you want to specifically isolate your helper methods for a specific partial.
181
+ # app/views/components/_card.html.erb
182
+ <% partial.title.yield tag.with_options(class: "text-m4", data: { controller: "title" }) %> # => <h1 class="text-m4" data-controller="title">Title content</h1>
183
+ ```
106
184
 
107
- ### Use Nice Partials in a partial
185
+ ### Smoother conditional rendering
108
186
 
109
- To invoke nice partials, start your partial file with the following:
187
+ In regular Rails partials it's common to see `content_for?` used to conditionally rendering something. With Nice Partials we can do this:
110
188
 
111
189
  ```html+erb
112
- <% yield p = np %>
190
+ <% if partial.title? %>
191
+ <% partial.title.h1 %>
192
+ <% end %>
113
193
  ```
114
194
 
115
- Here's what is happening here:
195
+ But since sections respond to and leverage `present?`, we can shorten the above to:
116
196
 
117
- - `yield` executes the block we receive when someone uses our partial.
118
- - `np` fetches an instance of the generic class that helps isolate our content buffers and helper methods.
119
- - `p = np` ensures we have a reference to that object in this partial.
120
- - `yield p = np` ensures the developer using this partial also has a reference to that object, so they can define what goes in the various content buffers.
197
+ ```html+erb
198
+ <% partial.title.presence&.h1 %>
199
+ ```
121
200
 
122
- (This is, [as far as we know](https://github.com/bullet-train-co/nice_partials/issues/1), the minimum viable invocation.)
201
+ This way no empty h1 element is rendered.
123
202
 
124
- Once you've done this at the top of your partial file, you can then use `<%= p.yield :some_section %>` to render whatever content areas you want to be passed into your partial.
203
+ ### Accessing the content returned via `partial.yield`
125
204
 
205
+ To access the inner content lines in the block here, partials have to manually insert a `<%= yield %>` call.
126
206
 
127
- ### Defining and using well isolated helper methods
207
+ ```html+erb
208
+ <%= render "components/card" do %>
209
+ Some content!
210
+ Yet more content!
211
+ <% end %>
212
+ ```
213
+
214
+ With Nice Partials, `partial.yield` returns the same content:
215
+
216
+ ```html+erb
217
+ # app/views/components/_card.html.erb
218
+ <%= partial.yield %> # => "Some content!\n\nYet more content!"
219
+ ```
220
+
221
+ ### Referring to the outer partial while rendering another
222
+
223
+ During a rendering block `partial` refers to the outer partial, so you can compose them.
224
+
225
+ ```html+erb
226
+ <% partial.title "Title content" %>
227
+
228
+ <%= render "components/card" do |cp| %>
229
+ <% cp.title partial.title %>
230
+ <% end %>
231
+ ```
128
232
 
129
- To minimize the amount of pollution in the global helper namespace, you can use the shared context object to define helper methods specifically for your partials _within your partial_ like so:
233
+ ### Passing content from one partial to the next
234
+
235
+ If you need to pass content into another partial, `content_from` lets you pass the keys to extract and then a hash to rename keys.
130
236
 
131
237
  ```html+erb
132
- <% p.helpers do
238
+ <%= render "components/card" do |cp| %>
239
+ <% cp.content_from partial, :title, byline: :header %>
240
+ <% end %>
241
+ ```
242
+
243
+ Here, we copied the `partial.title` to `cp.title` and `partial.byline` became `cp.header`.
244
+
245
+ ### Defining and using well isolated helper methods
246
+
247
+ If you want to have helper methods that are available only within your partials, you can call `partial.helpers` directly:
133
248
 
249
+ ```html+erb
250
+ # app/views/components/_card.html.erb
251
+ <% partial.helpers do
134
252
  # references should be a link if the user can drill down, otherwise just a text label.
135
253
  def reference_to(user)
136
254
  # look! this method has access to the scope of the entire view context and all the other helpers that come with it!
@@ -140,17 +258,30 @@ To minimize the amount of pollution in the global helper namespace, you can use
140
258
  object.name
141
259
  end
142
260
  end
143
-
144
261
  end %>
262
+
263
+ # Later in the partial we can use the method:
264
+ <td><%= partial.reference_to(user) %></td>
145
265
  ```
146
266
 
147
- Then later in the partial you can use the helper method like so:
267
+ ## Sponsored By
268
+
269
+ <a href="https://bullettrain.co" target="_blank">
270
+ <img src="https://github.com/CanCanCommunity/cancancan/raw/develop/logo/bullet_train.png" alt="Bullet Train" width="400"/>
271
+ </a>
272
+ <br/>
273
+ <br/>
274
+
275
+ > Would you like to support Nice Partials development and have your logo featured here? [Reach out!](http://twitter.com/andrewculver)
148
276
 
149
- ```html+erb
150
- <td><%= p.reference_to(user) %></td>
151
- ```
152
277
 
153
- ## Development
278
+ ## Setup
279
+
280
+ Add to your `Gemfile`:
281
+
282
+ ```ruby
283
+ gem "nice_partials"
284
+ ```
154
285
 
155
286
  ### Testing
156
287
 
@@ -160,4 +291,4 @@ bundle exec rake test
160
291
 
161
292
  ## MIT License
162
293
 
163
- Copyright (C) 2020 Andrew Culver <https://bullettrain.co> and Dom Christie <https://domchristie.co.uk>. Released under the MIT license.
294
+ Copyright (C) 2022 Andrew Culver <https://bullettrain.co> and Dom Christie <https://domchristie.co.uk>. Released under the MIT license.
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  # # #
2
2
  # Get gemspec info
3
3
 
4
+ require "bundler/gem_tasks"
5
+
4
6
  gemspec_file = Dir["*.gemspec"].first
5
7
  gemspec = eval File.read(gemspec_file), binding, gemspec_file
6
8
  info = "#{gemspec.name} | #{gemspec.version} | " \
@@ -26,12 +28,3 @@ desc "#{gemspec.name} | IRB"
26
28
  task :irb do
27
29
  sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}"
28
30
  end
29
-
30
- # # #
31
- # Run specs
32
-
33
- desc "#{gemspec.name} | Test"
34
- task :test do
35
- sh "for file in test/*_test.rb; do ruby $file; done"
36
- end
37
- task default: :test