nice_partials 0.1.9 → 0.9.1
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 +4 -4
- data/CHANGELOG.md +158 -0
- data/Gemfile +10 -0
- data/README.md +197 -80
- data/Rakefile +2 -9
- data/lib/nice_partials/helper.rb +4 -0
- data/lib/nice_partials/monkey_patch.rb +4 -3
- data/lib/nice_partials/partial/content.rb +54 -0
- data/lib/nice_partials/partial/section.rb +36 -27
- data/lib/nice_partials/partial.rb +79 -25
- data/lib/nice_partials/version.rb +1 -1
- data/lib/nice_partials.rb +1 -2
- data/nice_partials.gemspec +9 -3
- metadata +6 -36
- data/.gitignore +0 -3
- data/.travis.yml +0 -19
- data/nice_partials-0.1.8.gem +0 -0
- data/test/fixtures/_basic.html.erb +0 -1
- data/test/fixtures/_card.html.erb +0 -11
- data/test/fixtures/_clobberer.html.erb +0 -3
- data/test/fixtures/_partial_accessed_in_outer_context.html.erb +0 -11
- data/test/fixtures/card_test.html.erb +0 -9
- data/test/fixtures/translations/_nice_partials_translated.html.erb +0 -3
- data/test/fixtures/translations/_translated.html.erb +0 -1
- data/test/fixtures/yields/_object.html.erb +0 -1
- data/test/fixtures/yields/_plain.html.erb +0 -1
- data/test/fixtures/yields/_plain_nested.html.erb +0 -3
- data/test/fixtures/yields/_symbol.html.erb +0 -1
- data/test/renderer/translation_test.rb +0 -26
- data/test/renderer_test.rb +0 -83
- data/test/test_helper.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a1bc9c01590139038135f1cd6856c79529485c970225a5aa4d82a35d11bc33a
|
4
|
+
data.tar.gz: 19f2f3754c6c590745ee649a94e32de934ced12a2602956d0aa7fff7a8db4c74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99fca66a8450503cbd2348187680c0f82b995d1830515cebe35401d9fd4e1d2395ba35fceedeb18bf4bf36ffbc8a4273811344a4c5fa58d7e5981d6d0ac9b866
|
7
|
+
data.tar.gz: b3215bcdb6c639faeed18ec17b57bdcaba2c71c70a738c25c48faf00201535198b5dbb56f18686a2b2a2877d5896246275012cad0555ff2e558c13684291f805
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,163 @@
|
|
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
|
+
|
3
161
|
* Remove need to insert `<% yield p = np %>` in partials.
|
4
162
|
|
5
163
|
Nice Partials now automatically captures blocks passed to `render`.
|
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,150 +1,254 @@
|
|
1
|
-
# nice_partials [![[version]](https://badge.fury.io/rb/nice_partials.svg)](https://badge.fury.io/rb/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
|
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
|
-
<%= partial.
|
12
|
+
<%= partial.image %> # Same as `partial.content_for :image`
|
9
13
|
<div class="card-body">
|
10
|
-
<h5 class="card-title"><%= title %></h5>
|
11
|
-
<% if partial.
|
14
|
+
<h5 class="card-title"><%= partial.title %></h5>
|
15
|
+
<% if partial.body? %>
|
12
16
|
<p class="card-text">
|
13
|
-
<%= partial.
|
17
|
+
<%= partial.body %>
|
14
18
|
</p>
|
15
19
|
<% end %>
|
16
20
|
</div>
|
17
21
|
</div>
|
18
22
|
```
|
19
23
|
|
20
|
-
Then
|
24
|
+
Then in `render` we populate them:
|
21
25
|
|
22
26
|
```html+erb
|
23
|
-
<%= render
|
24
|
-
<% partial.content_for :
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
<% partial.
|
32
|
-
<%= image_tag image_path(
|
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
|
-
|
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
|
-
|
44
|
+
Consider this regular Rails partials rendering:
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
<br/>
|
46
|
+
```html+erb
|
47
|
+
<%= render "components/card" do %>
|
48
|
+
<% content_for :title, "Title content" %>
|
49
|
+
<% end %>
|
47
50
|
|
48
|
-
|
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
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
##
|
88
|
+
## What extra powers does `partial` give me?
|
65
89
|
|
66
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
103
|
+
Can then be used like this:
|
104
|
+
|
105
|
+
```html+erb
|
106
|
+
<%= render "components/card", title: "Hello there", byline: "Some guy" do |partial| %>
|
107
|
+
<% partial.byline ", who writes stuff" %>
|
108
|
+
<% end %>
|
109
|
+
```
|
85
110
|
|
86
|
-
|
111
|
+
This will then output "Hello there written by Some guy, who writes stuff"
|
87
112
|
|
113
|
+
You can also use `slice` to pass on content from an outer partial:
|
88
114
|
|
89
|
-
|
115
|
+
```html+erb
|
116
|
+
<%= render "components/card", partial.slice(:title, :byline) %>
|
117
|
+
```
|
90
118
|
|
91
|
-
|
119
|
+
### Appending content from the view into a section
|
92
120
|
|
93
|
-
|
94
|
-
|
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 %>
|
95
129
|
```
|
96
130
|
|
97
|
-
|
131
|
+
### I18n: translating and setting multiple keys at a time
|
98
132
|
|
99
|
-
|
133
|
+
`partial.t` is a shorthand to translate and assign multiple keys at once:
|
100
134
|
|
101
|
-
|
135
|
+
```html+erb
|
136
|
+
<% partial.t :title, description: :header, byline: "custom.key" %>
|
102
137
|
|
103
|
-
|
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
|
+
```
|
104
143
|
|
105
|
-
|
144
|
+
### Capturing options in the rendering block and building HTML tags in the partial
|
106
145
|
|
107
|
-
|
146
|
+
You can pass keyword options to a writer method and they'll be auto-added to `partial.x.options`, like so:
|
108
147
|
|
109
|
-
|
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.:
|
110
161
|
|
111
162
|
```html+erb
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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 %>
|
168
|
+
```
|
169
|
+
|
170
|
+
### Yielding tag builders into the rendering block
|
171
|
+
|
172
|
+
The above example showed sending options from the rendering block into the partial and having it construct elements.
|
173
|
+
|
174
|
+
But the partial can also prepare tag builders that the rendering block can then extend and finalize:
|
175
|
+
|
176
|
+
```html+erb
|
177
|
+
<% render "components/card" do |partial|
|
178
|
+
<% partial.title { |tag| tag.h1 "Title content" } %>
|
116
179
|
<% end %>
|
180
|
+
|
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>
|
117
183
|
```
|
118
184
|
|
119
|
-
|
185
|
+
### Smoother conditional rendering
|
120
186
|
|
121
|
-
|
187
|
+
In regular Rails partials it's common to see `content_for?` used to conditionally rendering something. With Nice Partials we can do this:
|
122
188
|
|
123
|
-
|
189
|
+
```html+erb
|
190
|
+
<% if partial.title? %>
|
191
|
+
<% partial.title.h1 %>
|
192
|
+
<% end %>
|
193
|
+
```
|
194
|
+
|
195
|
+
But since sections respond to and leverage `present?`, we can shorten the above to:
|
124
196
|
|
125
197
|
```html+erb
|
126
|
-
|
198
|
+
<% partial.title.presence&.h1 %>
|
199
|
+
```
|
200
|
+
|
201
|
+
This way no empty h1 element is rendered.
|
202
|
+
|
203
|
+
### Accessing the content returned via `partial.yield`
|
204
|
+
|
205
|
+
To access the inner content lines in the block here, partials have to manually insert a `<%= yield %>` call.
|
206
|
+
|
207
|
+
```html+erb
|
208
|
+
<%= render "components/card" do %>
|
127
209
|
Some content!
|
128
210
|
Yet more content!
|
129
211
|
<% end %>
|
130
212
|
```
|
131
213
|
|
132
|
-
|
214
|
+
With Nice Partials, `partial.yield` returns the same content:
|
133
215
|
|
134
216
|
```html+erb
|
135
|
-
|
136
|
-
<%= yield %> # => "Some content!\n\nYet more content!"
|
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
|
+
```
|
232
|
+
|
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.
|
236
|
+
|
237
|
+
```html+erb
|
238
|
+
<%= render "components/card" do |cp| %>
|
239
|
+
<% cp.content_from partial, :title, byline: :header %>
|
240
|
+
<% end %>
|
137
241
|
```
|
138
242
|
|
139
|
-
|
243
|
+
Here, we copied the `partial.title` to `cp.title` and `partial.byline` became `cp.header`.
|
140
244
|
|
141
245
|
### Defining and using well isolated helper methods
|
142
246
|
|
143
|
-
|
247
|
+
If you want to have helper methods that are available only within your partials, you can call `partial.helpers` directly:
|
144
248
|
|
145
249
|
```html+erb
|
250
|
+
# app/views/components/_card.html.erb
|
146
251
|
<% partial.helpers do
|
147
|
-
|
148
252
|
# references should be a link if the user can drill down, otherwise just a text label.
|
149
253
|
def reference_to(user)
|
150
254
|
# look! this method has access to the scope of the entire view context and all the other helpers that come with it!
|
@@ -154,17 +258,30 @@ To minimize the amount of pollution in the global helper namespace, you can use
|
|
154
258
|
object.name
|
155
259
|
end
|
156
260
|
end
|
157
|
-
|
158
261
|
end %>
|
159
|
-
```
|
160
262
|
|
161
|
-
|
162
|
-
|
163
|
-
```html+erb
|
263
|
+
# Later in the partial we can use the method:
|
164
264
|
<td><%= partial.reference_to(user) %></td>
|
165
265
|
```
|
166
266
|
|
167
|
-
##
|
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)
|
276
|
+
|
277
|
+
|
278
|
+
## Setup
|
279
|
+
|
280
|
+
Add to your `Gemfile`:
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
gem "nice_partials"
|
284
|
+
```
|
168
285
|
|
169
286
|
### Testing
|
170
287
|
|
@@ -174,4 +291,4 @@ bundle exec rake test
|
|
174
291
|
|
175
292
|
## MIT License
|
176
293
|
|
177
|
-
Copyright (C)
|
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 -Ilib:test $file; done"
|
36
|
-
end
|
37
|
-
task default: :test
|
data/lib/nice_partials/helper.rb
CHANGED
@@ -48,8 +48,9 @@ module NicePartials::RenderingWithAutoContext
|
|
48
48
|
|
49
49
|
# Overrides `ActionView::Helpers::RenderingHelper#render` to push a new `nice_partial`
|
50
50
|
# on the stack, so rendering has a fresh `partial` to store content in.
|
51
|
-
def render(
|
52
|
-
|
51
|
+
def render(options = {}, locals = {}, &block)
|
52
|
+
partial_locals = options.is_a?(Hash) ? options[:locals] : locals
|
53
|
+
__partials.prepend nice_partial_with(partial_locals)
|
53
54
|
super
|
54
55
|
ensure
|
55
56
|
__partials.shift
|
@@ -115,6 +116,6 @@ module NicePartials::CapturingYieldDetection
|
|
115
116
|
# Note: `<%= yield %>` becomes `yield :layout` with no `render` `block`, though this method assumes a block is passed.
|
116
117
|
def has_capturing_yield?
|
117
118
|
defined?(@has_capturing_yield) ? @has_capturing_yield :
|
118
|
-
@has_capturing_yield = source.match?(
|
119
|
+
@has_capturing_yield = source.match?(/[^\.\b]yield[\(? ]+(%>|[^:])/)
|
119
120
|
end
|
120
121
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class NicePartials::Partial::Content
|
2
|
+
class Options < Hash
|
3
|
+
def initialize(view_context)
|
4
|
+
@view_context = view_context
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
@view_context.tag.attributes(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(view_context, content = nil)
|
13
|
+
@view_context, @options = view_context, Options.new(view_context)
|
14
|
+
@content = ActiveSupport::SafeBuffer.new and concat content
|
15
|
+
end
|
16
|
+
delegate :to_s, :present?, to: :@content
|
17
|
+
|
18
|
+
# Contains options passed to a partial:
|
19
|
+
#
|
20
|
+
# <% partial.title class: "post-title" %> # partial.title.options # => { class: "post-title" }
|
21
|
+
#
|
22
|
+
# # Automatically runs `tag.attributes` when `to_s` is called, e.g.:
|
23
|
+
# <h1 <% partial.title.options %>> # => <h1 class="post-title">
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
def write?(content = nil, **new_options, &block)
|
27
|
+
@options.merge! new_options
|
28
|
+
append content or capture block
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(...)
|
32
|
+
write?(...)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def append(content)
|
39
|
+
case
|
40
|
+
when content.respond_to?(:render_in) then concat content.render_in(@view_context)
|
41
|
+
when content.respond_to?(:call) then capture content
|
42
|
+
else
|
43
|
+
concat content
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def capture(block)
|
48
|
+
append @view_context.capture(&block) if block
|
49
|
+
end
|
50
|
+
|
51
|
+
def concat(string)
|
52
|
+
@content << string.to_s if string.present?
|
53
|
+
end
|
54
|
+
end
|
@@ -1,43 +1,52 @@
|
|
1
|
-
class NicePartials::Partial::Section
|
2
|
-
def
|
3
|
-
@view_context
|
4
|
-
|
1
|
+
class NicePartials::Partial::Section < NicePartials::Partial::Content
|
2
|
+
def yield(*arguments)
|
3
|
+
chunks.each { append @view_context.capture(*arguments, &_1) }
|
4
|
+
self
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
7
|
+
def present?
|
8
|
+
chunks.present? || super
|
9
|
+
end
|
10
|
+
|
11
|
+
undef_method :p # Remove Kernel.p here to pipe through method_missing and hit tag proxy.
|
12
|
+
|
13
|
+
# Implements our proxying to the `@view_context` or `@view_context.tag`.
|
14
|
+
#
|
15
|
+
# `@view_context` proxying forwards the message and automatically appends any content, so you can do things like:
|
16
|
+
#
|
17
|
+
# <% partial.body.render "form", tangible_thing: @tangible_thing %>
|
18
|
+
# <% partial.body.link_to @document.name, @document %>
|
19
|
+
# <% partial.body.t ".body" %>
|
20
|
+
#
|
21
|
+
# `@view_context.tag` proxy lets you build bespoke elements based on content and options provided:
|
22
|
+
#
|
23
|
+
# <% partial.title "Some title content", class: "xl" %> # Write the content and options to the `title`
|
24
|
+
# <% partial.title.h2 ", appended" %> # => <h2 class="xl">Some title content, appended</h2>
|
25
|
+
#
|
26
|
+
# Note that NicePartials don't support deep merging attributes out of the box.
|
27
|
+
def method_missing(meth, *arguments, **keywords, &block)
|
28
|
+
if meth != :p && @view_context.respond_to?(meth)
|
29
|
+
append @view_context.public_send(meth, *arguments, **keywords, &block)
|
10
30
|
else
|
11
|
-
|
12
|
-
@content
|
31
|
+
@view_context.tag.public_send(meth, @content + arguments.first.to_s, **options.merge(keywords), &block)
|
13
32
|
end
|
14
33
|
end
|
15
34
|
|
16
|
-
def
|
17
|
-
|
35
|
+
def respond_to_missing?(...)
|
36
|
+
@view_context.respond_to?(...)
|
18
37
|
end
|
19
38
|
|
20
39
|
private
|
21
40
|
|
22
|
-
def
|
23
|
-
if
|
24
|
-
|
41
|
+
def capture(block)
|
42
|
+
if block&.arity&.nonzero?
|
43
|
+
chunks << block
|
25
44
|
else
|
26
|
-
|
45
|
+
super
|
27
46
|
end
|
28
47
|
end
|
29
48
|
|
30
|
-
def
|
31
|
-
|
32
|
-
@pending_content = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
def concat(string)
|
36
|
-
@content ||= ActiveSupport::SafeBuffer.new
|
37
|
-
@content << string.to_s if string.present?
|
38
|
-
end
|
39
|
-
|
40
|
-
def pending?
|
41
|
-
@pending_content
|
49
|
+
def chunks
|
50
|
+
@chunks ||= []
|
42
51
|
end
|
43
52
|
end
|
@@ -1,57 +1,111 @@
|
|
1
1
|
module NicePartials
|
2
2
|
class Partial
|
3
|
+
autoload :Content, "nice_partials/partial/content"
|
3
4
|
autoload :Section, "nice_partials/partial/section"
|
4
5
|
autoload :Stack, "nice_partials/partial/stack"
|
5
6
|
|
6
7
|
delegate_missing_to :@view_context
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
# This content can be accessed through calling `yield`.
|
11
|
-
# <% end %>
|
12
|
-
#
|
13
|
-
# Then in the nice_partial:
|
14
|
-
# <%= content.content_for :title %> # => "Yo"
|
15
|
-
# <%= content.output_buffer %> # => "This line is printed to the `output_buffer`."
|
16
|
-
attr_accessor :output_buffer
|
17
|
-
|
18
|
-
def initialize(view_context)
|
19
|
-
@view_context = view_context
|
20
|
-
@contents = Hash.new { |h, k| h[k] = Section.new(@view_context) }
|
9
|
+
def initialize(view_context, local_assigns = nil)
|
10
|
+
@view_context, @local_assigns = view_context, local_assigns
|
21
11
|
end
|
22
12
|
|
23
13
|
def yield(*arguments, &block)
|
24
14
|
if arguments.empty?
|
25
|
-
|
15
|
+
@captured_buffer
|
26
16
|
else
|
27
17
|
content_for(*arguments, &block)
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
31
21
|
def helpers(&block)
|
32
|
-
class_eval
|
22
|
+
self.class.class_eval(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
# `translate` is a shorthand to set `content_for` with content that's run through
|
26
|
+
# the view's `translate`/`t` context.
|
27
|
+
#
|
28
|
+
# partial.t :title # => partial.content_for :title, t(".title")
|
29
|
+
# partial.t title: :section # => partial.content_for :title, t(".section")
|
30
|
+
# partial.t title: "some.custom.key" # => partial.content_for :title, t("some.custom.key")
|
31
|
+
# partial.t :description, title: :header # Mixing is supported too.
|
32
|
+
#
|
33
|
+
# Note that `partial.t "some.custom.key"` can't derive a `content_for` name, so an explicit
|
34
|
+
# name must be provided e.g. `partial.t title: "some.custom.key"`.
|
35
|
+
def translate(*names, **renames)
|
36
|
+
names.chain(renames).each do |name, key = name|
|
37
|
+
content_for name, @view_context.t(key.is_a?(String) ? key : ".#{key}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
alias t translate
|
41
|
+
|
42
|
+
# Allows an inner partial to copy content from an outer partial.
|
43
|
+
#
|
44
|
+
# Additionally a hash of keys to rename in the new partial context can be passed.
|
45
|
+
#
|
46
|
+
# First, an outer partial gets some content set:
|
47
|
+
# <% partial.title "Hello there" %>
|
48
|
+
# <% partial.byline "Somebody" %>
|
49
|
+
#
|
50
|
+
# Second, a new partial is rendered, but we want to extract the title, byline content but rename the byline key too:
|
51
|
+
# <%= render "shared/title" do |cp| %>
|
52
|
+
# <% cp.content_from partial, :title, byline: :name %>
|
53
|
+
# <% end %>
|
54
|
+
#
|
55
|
+
# # Third, the contents with any renames are accessible in shared/_title.html.erb:
|
56
|
+
# <%= partial.title %> # => "Hello there"
|
57
|
+
# <%= partial.name %> # => "Somebody"
|
58
|
+
def content_from(partial, *names, **renames)
|
59
|
+
names.chain(renames).each { |key, new_key = key| public_send new_key, partial.public_send(key).to_s }
|
33
60
|
end
|
34
61
|
|
35
62
|
# Similar to Rails' built-in `content_for` except it defers any block execution
|
36
63
|
# and lets you pass arguments into it, like so:
|
37
64
|
#
|
38
65
|
# # Here we store a block with some eventual content…
|
39
|
-
# <% partial.
|
40
|
-
# <%= tag.h1 %>
|
41
|
-
# <% end %>
|
66
|
+
# <% partial.title { |tag| tag.h1 } %>
|
42
67
|
#
|
43
|
-
# # …which
|
44
|
-
# <%= partial.
|
45
|
-
def
|
46
|
-
|
68
|
+
# # …which we can then yield into with some predefined options later.
|
69
|
+
# <%= partial.title.yield tag.with_options(class: "text-bold") %>
|
70
|
+
def section(name, content = nil, **options, &block)
|
71
|
+
section_from(name).then { _1.write?(content, **options, &block) ? nil : _1 }
|
72
|
+
end
|
73
|
+
|
74
|
+
def section?(name)
|
75
|
+
@sections&.dig(name).present?
|
47
76
|
end
|
77
|
+
alias content_for? section?
|
48
78
|
|
49
|
-
def content_for
|
50
|
-
|
79
|
+
def content_for(...)
|
80
|
+
section(...)&.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
def slice(*keys)
|
84
|
+
keys.index_with { content_for _1 }
|
51
85
|
end
|
52
86
|
|
53
87
|
def capture(*arguments, &block)
|
54
|
-
|
88
|
+
@captured_buffer = @view_context.capture(*arguments, self, &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def section_from(name)
|
94
|
+
@sections ||= {} and @sections[name] ||= Section.new(@view_context, @local_assigns&.dig(name))
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_missing(meth, *arguments, **keywords, &block)
|
98
|
+
if @view_context.respond_to?(meth)
|
99
|
+
@view_context.public_send(meth, *arguments, **keywords, &block)
|
100
|
+
else
|
101
|
+
define_accessor meth and public_send(meth, *arguments, **keywords, &block)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def define_accessor(name)
|
106
|
+
name = name.to_s.chomp("?").to_sym
|
107
|
+
self.class.define_method(name) { |content = nil, **options, &block| section(name, content, **options, &block) }
|
108
|
+
self.class.define_method("#{name}?") { section?(name) }
|
55
109
|
end
|
56
110
|
end
|
57
111
|
end
|
data/lib/nice_partials.rb
CHANGED
@@ -4,9 +4,8 @@ require_relative "nice_partials/version"
|
|
4
4
|
|
5
5
|
module NicePartials
|
6
6
|
def self.locale_prefix_from(lookup_context, block)
|
7
|
-
root_paths = lookup_context.view_paths.map(&:path)
|
8
7
|
partial_location = block.source_location.first.dup
|
9
|
-
|
8
|
+
lookup_context.view_paths.each { partial_location.delete_prefix!(_1.path)&.delete_prefix!("/") }
|
10
9
|
partial_location.split('.').first.gsub('/_', '/').gsub('/', '.')
|
11
10
|
end
|
12
11
|
end
|
data/nice_partials.gemspec
CHANGED
@@ -12,9 +12,15 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.homepage = "https://github.com/bullet-train-co/nice_partials"
|
13
13
|
gem.license = "MIT"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
gem.
|
15
|
+
# Specify which files should be added to the gem when it is released.
|
16
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
|
+
gem.files = Dir.chdir(__dir__) do
|
18
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
gem.bindir = "exe"
|
23
|
+
gem.executables = gem.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
18
24
|
gem.require_paths = ["lib"]
|
19
25
|
|
20
26
|
gem.required_ruby_version = ">= 2.0"
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nice_partials
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
- Dom Christie
|
9
9
|
autorequire:
|
10
|
-
bindir:
|
10
|
+
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionview
|
@@ -61,8 +61,6 @@ executables: []
|
|
61
61
|
extensions: []
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
|
-
- ".gitignore"
|
65
|
-
- ".travis.yml"
|
66
64
|
- CHANGELOG.md
|
67
65
|
- CODE_OF_CONDUCT.md
|
68
66
|
- Gemfile
|
@@ -73,25 +71,11 @@ files:
|
|
73
71
|
- lib/nice_partials/helper.rb
|
74
72
|
- lib/nice_partials/monkey_patch.rb
|
75
73
|
- lib/nice_partials/partial.rb
|
74
|
+
- lib/nice_partials/partial/content.rb
|
76
75
|
- lib/nice_partials/partial/section.rb
|
77
76
|
- lib/nice_partials/partial/stack.rb
|
78
77
|
- lib/nice_partials/version.rb
|
79
|
-
- nice_partials-0.1.8.gem
|
80
78
|
- nice_partials.gemspec
|
81
|
-
- test/fixtures/_basic.html.erb
|
82
|
-
- test/fixtures/_card.html.erb
|
83
|
-
- test/fixtures/_clobberer.html.erb
|
84
|
-
- test/fixtures/_partial_accessed_in_outer_context.html.erb
|
85
|
-
- test/fixtures/card_test.html.erb
|
86
|
-
- test/fixtures/translations/_nice_partials_translated.html.erb
|
87
|
-
- test/fixtures/translations/_translated.html.erb
|
88
|
-
- test/fixtures/yields/_object.html.erb
|
89
|
-
- test/fixtures/yields/_plain.html.erb
|
90
|
-
- test/fixtures/yields/_plain_nested.html.erb
|
91
|
-
- test/fixtures/yields/_symbol.html.erb
|
92
|
-
- test/renderer/translation_test.rb
|
93
|
-
- test/renderer_test.rb
|
94
|
-
- test/test_helper.rb
|
95
79
|
homepage: https://github.com/bullet-train-co/nice_partials
|
96
80
|
licenses:
|
97
81
|
- MIT
|
@@ -111,22 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
95
|
- !ruby/object:Gem::Version
|
112
96
|
version: '0'
|
113
97
|
requirements: []
|
114
|
-
rubygems_version: 3.
|
98
|
+
rubygems_version: 3.4.1
|
115
99
|
signing_key:
|
116
100
|
specification_version: 4
|
117
101
|
summary: A little bit of magic to make partials perfect for components.
|
118
|
-
test_files:
|
119
|
-
- test/fixtures/_basic.html.erb
|
120
|
-
- test/fixtures/_card.html.erb
|
121
|
-
- test/fixtures/_clobberer.html.erb
|
122
|
-
- test/fixtures/_partial_accessed_in_outer_context.html.erb
|
123
|
-
- test/fixtures/card_test.html.erb
|
124
|
-
- test/fixtures/translations/_nice_partials_translated.html.erb
|
125
|
-
- test/fixtures/translations/_translated.html.erb
|
126
|
-
- test/fixtures/yields/_object.html.erb
|
127
|
-
- test/fixtures/yields/_plain.html.erb
|
128
|
-
- test/fixtures/yields/_plain_nested.html.erb
|
129
|
-
- test/fixtures/yields/_symbol.html.erb
|
130
|
-
- test/renderer/translation_test.rb
|
131
|
-
- test/renderer_test.rb
|
132
|
-
- test/test_helper.rb
|
102
|
+
test_files: []
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
data/nice_partials-0.1.8.gem
DELETED
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= partial.yield :message %>
|
@@ -1,11 +0,0 @@
|
|
1
|
-
<div class="card">
|
2
|
-
<%= partial.yield :image %>
|
3
|
-
<div class="card-body">
|
4
|
-
<h5 class="card-title"><%= title %></h5>
|
5
|
-
<% if partial.content_for? :body %>
|
6
|
-
<p class="card-text">
|
7
|
-
<%= partial.content_for :body, tag.with_options(class: "text-bold") %>
|
8
|
-
</p>
|
9
|
-
<% end %>
|
10
|
-
</div>
|
11
|
-
</div>
|
@@ -1,11 +0,0 @@
|
|
1
|
-
<% partial.content_for :original_message, "hello" %>
|
2
|
-
|
3
|
-
<%= render "basic" do |cp| %>
|
4
|
-
<% cp.content_for :message, partial.content_for(:original_message) %>
|
5
|
-
<% end %>
|
6
|
-
|
7
|
-
<%= render "basic" do |cp| %>
|
8
|
-
<% cp.content_for :message, "goodbye" %>
|
9
|
-
<% end %>
|
10
|
-
|
11
|
-
<span><%= partial.content_for :message %></span>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= t ".message" %>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= yield Hash.new(custom_key: :custom_value) %>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= yield %>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= yield :message %>
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
module Renderer; end
|
4
|
-
|
5
|
-
class Renderer::TranslationTest < NicePartials::Test
|
6
|
-
setup do
|
7
|
-
I18n.backend.store_translations "en", { translations: {
|
8
|
-
translated: { message: "message" },
|
9
|
-
nice_partials_translated: { message: "nice_partials" }
|
10
|
-
} }
|
11
|
-
end
|
12
|
-
|
13
|
-
teardown { I18n.reload! }
|
14
|
-
|
15
|
-
test "clean translation render" do
|
16
|
-
render "translations/translated"
|
17
|
-
|
18
|
-
assert_rendered "message"
|
19
|
-
end
|
20
|
-
|
21
|
-
test "translations insert prefix from originating partial" do
|
22
|
-
render "translations/nice_partials_translated"
|
23
|
-
|
24
|
-
assert_rendered "nice_partials"
|
25
|
-
end
|
26
|
-
end
|
data/test/renderer_test.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class RendererTest < NicePartials::Test
|
4
|
-
test "render basic nice partial" do
|
5
|
-
render("basic") { |p| p.content_for :message, "hello from nice partials" }
|
6
|
-
|
7
|
-
assert_rendered "hello from nice partials"
|
8
|
-
end
|
9
|
-
|
10
|
-
test "render nice partial in card template" do
|
11
|
-
render(template: "card_test")
|
12
|
-
|
13
|
-
assert_rendered "Some Title"
|
14
|
-
assert_rendered '<p class="text-bold">Lorem Ipsum</p>'
|
15
|
-
assert_rendered "https://example.com/image.jpg"
|
16
|
-
end
|
17
|
-
|
18
|
-
test "accessing partial in outer context won't leak state to inner render" do
|
19
|
-
render "partial_accessed_in_outer_context"
|
20
|
-
|
21
|
-
assert_rendered "hello"
|
22
|
-
assert_rendered "goodbye"
|
23
|
-
assert_rendered "<span></span>"
|
24
|
-
assert_not_includes rendered, "hellogoodbye"
|
25
|
-
end
|
26
|
-
|
27
|
-
test "explicit yield without any arguments auto-captures passed block" do
|
28
|
-
render "yields/plain" do |partial, auto_capture_shouldnt_pass_extra_argument|
|
29
|
-
assert_kind_of NicePartials::Partial, partial
|
30
|
-
assert_nil auto_capture_shouldnt_pass_extra_argument
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
test "explicit yield with symbol auto-captures passed block" do
|
35
|
-
render "yields/symbol" do |partial, auto_capture_shouldnt_pass_extra_argument|
|
36
|
-
assert_kind_of NicePartials::Partial, partial
|
37
|
-
assert_nil auto_capture_shouldnt_pass_extra_argument
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
test "explicit yield with object won't auto-capture but make partial available in capture" do
|
42
|
-
render "yields/object" do |object, partial|
|
43
|
-
assert_equal Hash.new(custom_key: :custom_value), object
|
44
|
-
assert_kind_of NicePartials::Partial, partial
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
test "explicit yield without any arguments with nesting" do
|
49
|
-
render "yields/plain_nested" do
|
50
|
-
tag.span "Output in outer partial through yield"
|
51
|
-
end
|
52
|
-
|
53
|
-
assert_rendered "<span>Output in outer partial through yield</span>"
|
54
|
-
end
|
55
|
-
|
56
|
-
test "output_buffer captures content not written via yield/content_for" do
|
57
|
-
nice_partial = nil
|
58
|
-
render "basic" do |p|
|
59
|
-
nice_partial = p
|
60
|
-
p.content_for :message, "hello from nice partials"
|
61
|
-
"Some extra content"
|
62
|
-
end
|
63
|
-
|
64
|
-
assert_rendered "hello from nice partials"
|
65
|
-
assert_equal "Some extra content", nice_partial.yield
|
66
|
-
end
|
67
|
-
|
68
|
-
test "doesn't clobber Kernel.p" do
|
69
|
-
assert_output "\"it's clobbering time\"\n" do
|
70
|
-
render("clobberer") { |p| p.content_for :message, "hello from nice partials" }
|
71
|
-
end
|
72
|
-
|
73
|
-
assert_rendered "hello from nice partials"
|
74
|
-
end
|
75
|
-
|
76
|
-
test "deprecates top-level access through p method" do
|
77
|
-
assert_deprecated /p is deprecated and will be removed from nice_partials \d/, NicePartials::DEPRECATOR do
|
78
|
-
assert_output "\"it's clobbering time\"\n" do
|
79
|
-
render("clobberer") { |p| p.content_for :message, "hello from nice partials" }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require "active_support"
|
2
|
-
require "active_support/testing/autorun"
|
3
|
-
require "action_controller"
|
4
|
-
require "action_view"
|
5
|
-
require "action_view/test_case"
|
6
|
-
|
7
|
-
require "nice_partials"
|
8
|
-
|
9
|
-
class NicePartials::Test < ActionView::TestCase
|
10
|
-
TestController.view_paths << "test/fixtures"
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def assert_rendered(matcher)
|
15
|
-
assert_match matcher, rendered
|
16
|
-
end
|
17
|
-
end
|