nice_partials 0.1.4 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +55 -1
- data/README.md +43 -21
- data/Rakefile +4 -4
- data/lib/nice_partials/helper.rb +2 -19
- data/lib/nice_partials/monkey_patch.rb +111 -14
- data/lib/nice_partials/partial/section.rb +43 -0
- data/lib/nice_partials/partial/stack.rb +19 -0
- data/lib/nice_partials/partial.rb +37 -19
- data/lib/nice_partials/version.rb +1 -1
- data/lib/nice_partials.rb +9 -11
- data/nice_partials-0.1.8.gem +0 -0
- data/nice_partials.gemspec +3 -0
- data/test/fixtures/_basic.html.erb +1 -0
- data/test/fixtures/_card.html.erb +11 -0
- data/test/fixtures/_clobberer.html.erb +3 -0
- data/test/fixtures/_partial_accessed_in_outer_context.html.erb +11 -0
- data/test/fixtures/card_test.html.erb +9 -0
- data/test/fixtures/translations/_nice_partials_translated.html.erb +3 -0
- data/test/fixtures/translations/_translated.html.erb +1 -0
- data/test/fixtures/yields/_object.html.erb +1 -0
- data/test/fixtures/yields/_plain.html.erb +1 -0
- data/test/fixtures/yields/_plain_nested.html.erb +3 -0
- data/test/fixtures/yields/_symbol.html.erb +1 -0
- data/test/renderer/translation_test.rb +26 -0
- data/test/renderer_test.rb +83 -0
- data/test/test_helper.rb +17 -0
- metadata +62 -6
- data/lib/partials.rb +0 -2
- data/spec/nice_partials_spec.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc6e751d8a192aa46fe3ee5401fe924c4dc1f5c6c3c7fabe8c22f468ff3a344c
|
4
|
+
data.tar.gz: de5a48e0d84e96a40b85293933af3dadd4977e6dfa2dd06522c85e1a6fbd0576
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f56fb3b92520c7a818b6ced0225def224a265a9ca2400d70e283300df8eef3fc266c6b65fa2e4e24856d7eccb6c0b39bdadf056bdec76c499be68fd9d90a982
|
7
|
+
data.tar.gz: 6a58763a68c0aa76cfee32432c730166cd96a19b2c8a1e8428c26260663ff706fc4883af07e9b1782da0d7e493ca7f4f8883fde223b75674967acce7a3780bc1
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,63 @@
|
|
1
1
|
## CHANGELOG
|
2
2
|
|
3
|
+
* Remove need to insert `<% yield p = np %>` in partials.
|
4
|
+
|
5
|
+
Nice Partials now automatically captures blocks passed to `render`.
|
6
|
+
Instead of `p`, a `partial` method has been added to access the
|
7
|
+
current `NicePartials::Partial` object.
|
8
|
+
|
9
|
+
Here's a script to help update your view code:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
files_to_inspect = []
|
13
|
+
|
14
|
+
Dir["app/views/**/*.html.erb"].each do |path|
|
15
|
+
if contents = File.read(path).match(/(<%=? yield\(?.*? = np\)? %>\n+)/m)&.post_match
|
16
|
+
files_to_inspect << path if contents.match?(/render.*?do \|/)
|
17
|
+
|
18
|
+
contents.gsub! /\bp\.(?=yield|helpers|content_for|content_for\?)/, "partial."
|
19
|
+
File.write path, contents
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if files_to_inspect.any?
|
24
|
+
puts "These files had render calls with a block parameter and likely require some manual edits:"
|
25
|
+
puts files_to_inspect
|
26
|
+
else
|
27
|
+
puts "No files with render calls with a block parameter found, you're likely all set"
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
* Support manual `yield`s in partials.
|
32
|
+
|
33
|
+
Due to the automatic yield support above, support has also been added for manual `yield some_object` calls.
|
34
|
+
|
35
|
+
Nice Partials automatically appends the `partial` to the yielded arguments, so you can
|
36
|
+
change `render … do |some_object|` to `render … do |some_object, partial|`.
|
37
|
+
|
38
|
+
* Deprecate `p` as the partial object access. Use `partial` instead.
|
39
|
+
|
40
|
+
* Expose `partial.yield` to access the captured output buffer.
|
41
|
+
|
42
|
+
Lets you access what a `<%= yield %>` call returned, like this:
|
43
|
+
|
44
|
+
```erb
|
45
|
+
<%= render "card" do %>
|
46
|
+
This is the content of the internal output buffer
|
47
|
+
<% end %>
|
48
|
+
```
|
49
|
+
|
50
|
+
```erb
|
51
|
+
# app/views/cards/_card.html.erb
|
52
|
+
# This can be replaced with `partial.yield`.
|
53
|
+
<%= yield %> # Will output "This is the content of the internal output buffer"
|
54
|
+
```
|
55
|
+
|
56
|
+
### 0.1.7
|
57
|
+
|
3
58
|
* Rely on `ActiveSupport.on_load :action_view`
|
4
59
|
* Add support for Ruby 3.0
|
5
60
|
|
6
61
|
### 0.1.0
|
7
62
|
|
8
63
|
* Initial release
|
9
|
-
|
data/README.md
CHANGED
@@ -1,34 +1,34 @@
|
|
1
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)
|
2
2
|
|
3
|
-
Nice Partials
|
3
|
+
Nice Partials lets [`content_for` and `yield`](https://guides.rubyonrails.org/layouts_and_rendering.html#using-the-content-for-method) calls be partial specific, to provide named "content areas" or "slots". This optional layer of magic helps make traditional Rails view partials a better fit for extracting components from your views, like so:
|
4
4
|
|
5
5
|
`app/views/components/_card.html.erb`:
|
6
6
|
```html+erb
|
7
7
|
<div class="card">
|
8
|
-
<%=
|
8
|
+
<%= partial.yield :image %>
|
9
9
|
<div class="card-body">
|
10
10
|
<h5 class="card-title"><%= title %></h5>
|
11
|
-
<% if
|
11
|
+
<% if partial.content_for? :body %>
|
12
12
|
<p class="card-text">
|
13
|
-
<%=
|
13
|
+
<%= partial.yield :body %>
|
14
14
|
</p>
|
15
15
|
<% end %>
|
16
16
|
</div>
|
17
17
|
</div>
|
18
18
|
```
|
19
19
|
|
20
|
-
|
20
|
+
Then you can call `render`, but specify how to populate the content areas:
|
21
21
|
|
22
22
|
```html+erb
|
23
|
-
<%= render 'components/card', title: 'Some Title' do |
|
24
|
-
<%
|
23
|
+
<%= render 'components/card', title: 'Some Title' do |partial| %>
|
24
|
+
<% partial.content_for :body do %>
|
25
25
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
26
26
|
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
27
27
|
<strong>quis nostrud exercitation ullamco laboris</strong> nisi ut aliquip
|
28
28
|
ex ea commodo consequat.
|
29
29
|
<% end %>
|
30
30
|
|
31
|
-
<%
|
31
|
+
<% partial.content_for :image do %>
|
32
32
|
<%= image_tag image_path('example.jpg'), alt: 'An example image' %>
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
@@ -50,7 +50,7 @@ Nice Partials is a lightweight and hopefully more Rails-native alternative to [V
|
|
50
50
|
|
51
51
|
## Benefits of Nice Partials
|
52
52
|
|
53
|
-
|
53
|
+
Nice Partials:
|
54
54
|
|
55
55
|
- is just regular Rails view partials like you're used to.
|
56
56
|
- reduces the friction when extracting components.
|
@@ -104,32 +104,46 @@ You only need to use Nice Partials when:
|
|
104
104
|
|
105
105
|
- you want to specifically isolate your helper methods for a specific partial.
|
106
106
|
|
107
|
-
###
|
107
|
+
### Using Nice Partials
|
108
108
|
|
109
|
-
|
109
|
+
Nice Partials is invoked automatically when you render your partial with a block like so:
|
110
110
|
|
111
111
|
```html+erb
|
112
|
-
|
112
|
+
<%= render 'components/card' do |partial| %>
|
113
|
+
<%= partial.content_for :some_section do %>
|
114
|
+
Some content!
|
115
|
+
<% end %>
|
116
|
+
<% end %>
|
113
117
|
```
|
114
118
|
|
115
|
-
|
119
|
+
Now within the partial file itself, you can use `<%= partial.yield :some_section %>` to render whatever content areas you want to be passed into your partial.
|
116
120
|
|
117
|
-
|
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.
|
121
|
+
### Accessing the content returned from `yield`
|
121
122
|
|
122
|
-
|
123
|
+
In a regular Rails partial:
|
123
124
|
|
124
|
-
|
125
|
+
```html+erb
|
126
|
+
<%= render 'components/card' do %>
|
127
|
+
Some content!
|
128
|
+
Yet more content!
|
129
|
+
<% end %>
|
130
|
+
```
|
125
131
|
|
132
|
+
You can access the inner content lines through what's returned from `yield`:
|
133
|
+
|
134
|
+
```html+erb
|
135
|
+
<%# app/views/components/_card.html.erb %>
|
136
|
+
<%= yield %> # => "Some content!\n\nYet more content!"
|
137
|
+
```
|
138
|
+
|
139
|
+
With Nice Partials, you can call `partial.yield` without arguments and return the same `"Some content!\n\nYet more content!"`.
|
126
140
|
|
127
141
|
### Defining and using well isolated helper methods
|
128
142
|
|
129
143
|
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:
|
130
144
|
|
131
145
|
```html+erb
|
132
|
-
<%
|
146
|
+
<% partial.helpers do
|
133
147
|
|
134
148
|
# references should be a link if the user can drill down, otherwise just a text label.
|
135
149
|
def reference_to(user)
|
@@ -147,7 +161,15 @@ end %>
|
|
147
161
|
Then later in the partial you can use the helper method like so:
|
148
162
|
|
149
163
|
```html+erb
|
150
|
-
<td><%=
|
164
|
+
<td><%= partial.reference_to(user) %></td>
|
165
|
+
```
|
166
|
+
|
167
|
+
## Development
|
168
|
+
|
169
|
+
### Testing
|
170
|
+
|
171
|
+
```sh
|
172
|
+
bundle exec rake test
|
151
173
|
```
|
152
174
|
|
153
175
|
## MIT License
|
data/Rakefile
CHANGED
@@ -30,8 +30,8 @@ end
|
|
30
30
|
# # #
|
31
31
|
# Run specs
|
32
32
|
|
33
|
-
desc "#{gemspec.name} |
|
34
|
-
task :
|
35
|
-
sh "for file in
|
33
|
+
desc "#{gemspec.name} | Test"
|
34
|
+
task :test do
|
35
|
+
sh "for file in test/{**/,}*_test.rb; do ruby -Ilib:test $file; done"
|
36
36
|
end
|
37
|
-
task default: :
|
37
|
+
task default: :test
|
data/lib/nice_partials/helper.rb
CHANGED
@@ -1,25 +1,8 @@
|
|
1
1
|
require_relative "partial"
|
2
2
|
|
3
3
|
module NicePartials::Helper
|
4
|
-
def
|
4
|
+
def nice_partial
|
5
5
|
NicePartials::Partial.new(self)
|
6
6
|
end
|
7
|
-
|
8
|
-
def nice_partials_push_t_prefix(prefix)
|
9
|
-
@_nice_partials_t_prefixes ||= []
|
10
|
-
@_nice_partials_t_prefixes << prefix
|
11
|
-
end
|
12
|
-
|
13
|
-
def nice_partials_pop_t_prefix
|
14
|
-
@_nice_partials_t_prefixes ||= []
|
15
|
-
@_nice_partials_t_prefixes.pop
|
16
|
-
end
|
17
|
-
|
18
|
-
def t(key, options = {})
|
19
|
-
if @_nice_partials_t_prefixes&.any? && key.first == '.'
|
20
|
-
key = "#{@_nice_partials_t_prefixes.last}#{key}"
|
21
|
-
end
|
22
|
-
|
23
|
-
super(key, options)
|
24
|
-
end
|
7
|
+
alias_method :np, :nice_partial
|
25
8
|
end
|
@@ -1,23 +1,120 @@
|
|
1
1
|
# Monkey patch required to make `t` work as expected. Is this evil?
|
2
2
|
# TODO Do we need to monkey patch other types of renderers as well?
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
module NicePartials::RenderingWithLocalePrefix
|
4
|
+
ActionView::Base.prepend self
|
5
|
+
|
6
|
+
def capture(*, &block)
|
7
|
+
with_nice_partials_t_prefix(lookup_context, block) { super }
|
8
|
+
end
|
9
|
+
|
10
|
+
def t(key, options = {})
|
11
|
+
if (prefix = @_nice_partials_t_prefix) && key.first == '.'
|
12
|
+
key = "#{prefix}#{key}"
|
13
|
+
end
|
14
|
+
|
15
|
+
super(key, **options)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def with_nice_partials_t_prefix(lookup_context, block)
|
21
|
+
_nice_partials_t_prefix = @_nice_partials_t_prefix
|
22
|
+
@_nice_partials_t_prefix = block ? NicePartials.locale_prefix_from(lookup_context, block) : nil
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
@_nice_partials_t_prefix = _nice_partials_t_prefix
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require "active_support/deprecation"
|
30
|
+
NicePartials::DEPRECATOR = ActiveSupport::Deprecation.new("1.0", "nice_partials")
|
31
|
+
|
32
|
+
module NicePartials::RenderingWithAutoContext
|
33
|
+
ActionView::Base.prepend self
|
34
|
+
|
35
|
+
def __partials
|
36
|
+
@__partials ||= NicePartials::Partial::Stack.new
|
37
|
+
end
|
38
|
+
delegate :partial, to: :__partials
|
39
|
+
|
40
|
+
def p(*args)
|
41
|
+
if args.empty?
|
42
|
+
NicePartials::DEPRECATOR.deprecation_warning :p, :partial # In-branch printing so we don't warn on legit `Kernel.p` calls.
|
43
|
+
partial
|
44
|
+
else
|
45
|
+
super # …we're really Kernel.p
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Overrides `ActionView::Helpers::RenderingHelper#render` to push a new `nice_partial`
|
50
|
+
# on the stack, so rendering has a fresh `partial` to store content in.
|
51
|
+
def render(*)
|
52
|
+
__partials.prepend nice_partial
|
53
|
+
super
|
54
|
+
ensure
|
55
|
+
__partials.shift
|
56
|
+
end
|
57
|
+
|
58
|
+
# Since Action View passes any `yield`s in partials through `_layout_for`, we
|
59
|
+
# override `_layout_for` to detects if it's a capturing yield and append the
|
60
|
+
# current partial to the arguments.
|
61
|
+
#
|
62
|
+
# So `render … do |some_object|` can become `render … do |some_object, partial|`
|
63
|
+
# without needing to find and update the inner `yield some_object` call.
|
64
|
+
def _layout_for(*arguments, &block)
|
65
|
+
if block && !arguments.first.is_a?(Symbol)
|
66
|
+
capture_with_outer_partial_access(*arguments, &block)
|
11
67
|
else
|
12
|
-
|
13
|
-
context.nice_partials_push_t_prefix ''
|
68
|
+
super
|
14
69
|
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reverts `partial` to return the outer partial before the `render` call started.
|
73
|
+
#
|
74
|
+
# So we don't clobber the `partial` shown here:
|
75
|
+
#
|
76
|
+
# <%= render "card" do |inner_partial| %>
|
77
|
+
# <% inner_partial.content_for :title, partial.content_for(:title) %>
|
78
|
+
# <% end %>
|
79
|
+
#
|
80
|
+
# Note: this happens because the `@partial` instance variable is shared between all
|
81
|
+
# `render` calls since rendering happens in one `ActionView::Base` instance.
|
82
|
+
def capture_with_outer_partial_access(*arguments, &block)
|
83
|
+
__partials.locate_previous
|
84
|
+
__partials.first.capture(*arguments, &block)
|
85
|
+
ensure
|
86
|
+
__partials.reset_locator
|
87
|
+
end
|
88
|
+
end
|
15
89
|
|
16
|
-
|
90
|
+
module NicePartials::PartialRendering
|
91
|
+
ActionView::PartialRenderer.prepend self
|
92
|
+
|
93
|
+
# Automatically captures the `block` in case the partial has no manual capturing `yield` call.
|
94
|
+
#
|
95
|
+
# This manual equivalent would be inserting this:
|
96
|
+
#
|
97
|
+
# <% yield partial %>
|
98
|
+
def render_partial_template(view, locals, template, layout, block)
|
99
|
+
view.capture_with_outer_partial_access(&block) if block && !template.has_capturing_yield?
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
17
103
|
|
18
|
-
|
19
|
-
|
104
|
+
module NicePartials::CapturingYieldDetection
|
105
|
+
ActionView::Template.include self
|
20
106
|
|
21
|
-
|
107
|
+
# Matches yields that'll end up calling `capture`:
|
108
|
+
# <%= yield %>
|
109
|
+
# <%= yield something_else %>
|
110
|
+
#
|
111
|
+
# Doesn't match obfuscated `content_for` invocations, nor custom yields:
|
112
|
+
# <%= yield :message %>
|
113
|
+
# <%= something.yield %>
|
114
|
+
#
|
115
|
+
# Note: `<%= yield %>` becomes `yield :layout` with no `render` `block`, though this method assumes a block is passed.
|
116
|
+
def has_capturing_yield?
|
117
|
+
defined?(@has_capturing_yield) ? @has_capturing_yield :
|
118
|
+
@has_capturing_yield = source.match?(/\byield[\(? ]+(%>|[^:])/)
|
22
119
|
end
|
23
120
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class NicePartials::Partial::Section
|
2
|
+
def initialize(view_context)
|
3
|
+
@view_context = view_context
|
4
|
+
@content = @pending_content = nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def content_for(*arguments, &block)
|
8
|
+
if write_content_for(arguments.first, &block)
|
9
|
+
nil
|
10
|
+
else
|
11
|
+
capture_content_for(*arguments) if pending?
|
12
|
+
@content
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def content?
|
17
|
+
pending? || @content
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def write_content_for(content = nil, &block)
|
23
|
+
if content && !pending?
|
24
|
+
concat content
|
25
|
+
else
|
26
|
+
@pending_content = block if block
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def capture_content_for(*arguments)
|
31
|
+
concat @view_context.capture(*arguments, &@pending_content)
|
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
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class NicePartials::Partial::Stack
|
2
|
+
def initialize
|
3
|
+
@partials = []
|
4
|
+
reset_locator
|
5
|
+
end
|
6
|
+
delegate :prepend, :shift, :first, to: :@partials
|
7
|
+
|
8
|
+
def partial
|
9
|
+
@partials.public_send @locator
|
10
|
+
end
|
11
|
+
|
12
|
+
def locate_previous
|
13
|
+
@locator = :second
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset_locator
|
17
|
+
@locator = :first
|
18
|
+
end
|
19
|
+
end
|
@@ -1,39 +1,57 @@
|
|
1
1
|
module NicePartials
|
2
2
|
class Partial
|
3
|
+
autoload :Section, "nice_partials/partial/section"
|
4
|
+
autoload :Stack, "nice_partials/partial/stack"
|
5
|
+
|
3
6
|
delegate_missing_to :@view_context
|
4
7
|
|
8
|
+
# <%= render "nice_partial" do |p| %>
|
9
|
+
# <% p.content_for :title, "Yo" %>
|
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
|
+
|
5
18
|
def initialize(view_context)
|
6
19
|
@view_context = view_context
|
7
|
-
@
|
20
|
+
@contents = Hash.new { |h, k| h[k] = Section.new(@view_context) }
|
8
21
|
end
|
9
22
|
|
10
|
-
def yield(
|
11
|
-
|
12
|
-
|
23
|
+
def yield(*arguments, &block)
|
24
|
+
if arguments.empty?
|
25
|
+
output_buffer
|
26
|
+
else
|
27
|
+
content_for(*arguments, &block)
|
28
|
+
end
|
13
29
|
end
|
14
30
|
|
15
31
|
def helpers(&block)
|
16
32
|
class_eval &block
|
17
33
|
end
|
18
34
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
return result
|
35
|
+
# Similar to Rails' built-in `content_for` except it defers any block execution
|
36
|
+
# and lets you pass arguments into it, like so:
|
37
|
+
#
|
38
|
+
# # Here we store a block with some eventual content…
|
39
|
+
# <% partial.content_for :title do |tag|
|
40
|
+
# <%= tag.h1 %>
|
41
|
+
# <% end %>
|
42
|
+
#
|
43
|
+
# # …which is then invoked with some predefined options later.
|
44
|
+
# <%= partial.content_for :title, tag.with_options(class: "text-bold") %>
|
45
|
+
def content_for(name, content = nil, *arguments, &block)
|
46
|
+
@contents[name].content_for(content, *arguments, &block)
|
33
47
|
end
|
34
48
|
|
35
49
|
def content_for?(name)
|
36
|
-
@
|
50
|
+
@contents[name].content?
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture(*arguments, &block)
|
54
|
+
self.output_buffer = @view_context.capture(*arguments, self, &block)
|
37
55
|
end
|
38
56
|
end
|
39
57
|
end
|
data/lib/nice_partials.rb
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "nice_partials/version"
|
4
|
-
require_relative "nice_partials/helper"
|
5
|
-
require_relative "nice_partials/monkey_patch"
|
6
|
-
require_relative "partials"
|
7
4
|
|
8
5
|
module NicePartials
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
root_paths.each { |path| partial_location.gsub!(/^#{path}\//, '') }
|
16
|
-
partial_location.split('.').first.gsub('/_', '/').gsub('/', '.')
|
6
|
+
def self.locale_prefix_from(lookup_context, block)
|
7
|
+
root_paths = lookup_context.view_paths.map(&:path)
|
8
|
+
partial_location = block.source_location.first.dup
|
9
|
+
root_paths.each { |path| partial_location.gsub!(/^#{path}\//, '') }
|
10
|
+
partial_location.split('.').first.gsub('/_', '/').gsub('/', '.')
|
11
|
+
end
|
17
12
|
end
|
18
13
|
|
19
14
|
ActiveSupport.on_load :action_view do
|
15
|
+
require_relative "nice_partials/monkey_patch"
|
16
|
+
|
17
|
+
require_relative "nice_partials/helper"
|
20
18
|
include NicePartials::Helper
|
21
19
|
end
|
Binary file
|
data/nice_partials.gemspec
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
<%= partial.yield :message %>
|
@@ -0,0 +1,11 @@
|
|
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>
|
@@ -0,0 +1,11 @@
|
|
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>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= t ".message" %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield Hash.new(custom_key: :custom_value) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield :message %>
|
@@ -0,0 +1,26 @@
|
|
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
|
@@ -0,0 +1,83 @@
|
|
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
ADDED
@@ -0,0 +1,17 @@
|
|
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
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionview
|
@@ -25,6 +25,34 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 4.2.6
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rails
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: standard
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
28
56
|
description: A little bit of magic to make partials perfect for components.
|
29
57
|
email:
|
30
58
|
- andrew.culver@gmail.com
|
@@ -45,10 +73,25 @@ files:
|
|
45
73
|
- lib/nice_partials/helper.rb
|
46
74
|
- lib/nice_partials/monkey_patch.rb
|
47
75
|
- lib/nice_partials/partial.rb
|
76
|
+
- lib/nice_partials/partial/section.rb
|
77
|
+
- lib/nice_partials/partial/stack.rb
|
48
78
|
- lib/nice_partials/version.rb
|
49
|
-
-
|
79
|
+
- nice_partials-0.1.8.gem
|
50
80
|
- nice_partials.gemspec
|
51
|
-
-
|
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
|
52
95
|
homepage: https://github.com/bullet-train-co/nice_partials
|
53
96
|
licenses:
|
54
97
|
- MIT
|
@@ -68,9 +111,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
111
|
- !ruby/object:Gem::Version
|
69
112
|
version: '0'
|
70
113
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
114
|
+
rubygems_version: 3.3.7
|
72
115
|
signing_key:
|
73
116
|
specification_version: 4
|
74
117
|
summary: A little bit of magic to make partials perfect for components.
|
75
118
|
test_files:
|
76
|
-
-
|
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
|
data/lib/partials.rb
DELETED