nice_partials 0.1.9 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|