pres 1.4.1 → 1.5.0
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 +5 -5
- data/README.md +45 -61
- data/lib/pres.rb +2 -0
- data/lib/pres/presenter.rb +2 -0
- data/lib/pres/presents.rb +13 -3
- data/lib/pres/version.rb +3 -1
- data/lib/pres/view_delegation.rb +8 -6
- metadata +4 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1c299e16a162674ba826b413ab48bbdc0850af84d8958eb6a3e9f440c7cd4e82
|
4
|
+
data.tar.gz: 40e724787b143aa0ede13a41f2d84e6e2b2297584fb7ab36c2b448826609863d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '039604e02f82018fff8345492080896501efb7c8b05dab17ed2dfcf7babf9a4873687fac56986ac3b53ed76d4bc048ad4037be350bca4b5985d76c78ad3d0b5c'
|
7
|
+
data.tar.gz: e53da96e07d916ae51ddb499d171ee566f1df5e300ae61d1cc4e2c4e061a6b7614bb546f42d2d8c39a2e0e40f084bff72bc7dbc1fa73a1877fd5fc9bfcfb7371
|
data/README.md
CHANGED
@@ -5,19 +5,28 @@
|
|
5
5
|
|
6
6
|
## What?
|
7
7
|
|
8
|
-
A Presenter is a rendering class.
|
9
|
-
|
8
|
+
A Presenter is a rendering class. The `pres` gem is a lightweight presenter
|
9
|
+
solution with no runtime gem dependencies.
|
10
|
+
|
11
|
+
`Pres` provides the following:
|
12
|
+
|
13
|
+
1. `Pres::Presenter` is a presenter base class.
|
14
|
+
1. `present` is a convenience method to create presenters.
|
15
|
+
1. `Pres::ViewDelegation` is a delegation module, included in the `Presenter` base class.
|
10
16
|
|
11
17
|
## How and Why?
|
12
18
|
|
19
|
+
Presenters are an alternative to an unorganized mass of helper
|
20
|
+
methods in your ruby application.
|
21
|
+
|
13
22
|
Rails' `ViewContext` contains convenience methods for views, such as `link_to`,
|
14
23
|
`url_for`, `truncate`, `number_to_currency`, etc. It's the thing that makes
|
15
24
|
Rails views nice to work with.
|
16
25
|
|
17
26
|
Other presenter libraries mix in all the methods from the Rails `ViewContext` to
|
18
|
-
make it easy to call those methods in the Presenter class. `pres` instead injects
|
19
|
-
the `ViewContext` as a dependency into the Presenter class, and uses `method_missing`
|
20
|
-
to delegate to `ViewContext` methods. `pres` produces small classes that contain and
|
27
|
+
make it easy to call those methods in the Presenter class. `pres` instead injects
|
28
|
+
the `ViewContext` as a dependency into the Presenter class, and uses `method_missing`
|
29
|
+
to delegate to `ViewContext` methods. `pres` produces small classes that contain and
|
21
30
|
delegate to an existing object that handles server-side rendering.
|
22
31
|
|
23
32
|
## Install
|
@@ -28,6 +37,8 @@ Add it to your Gemfile:
|
|
28
37
|
gem "pres"
|
29
38
|
```
|
30
39
|
|
40
|
+
## Setup with Rails
|
41
|
+
|
31
42
|
Include the `Pres::Presents` module:
|
32
43
|
|
33
44
|
```ruby
|
@@ -53,7 +64,7 @@ class DogePresenter < Pres::Presenter
|
|
53
64
|
end
|
54
65
|
|
55
66
|
def name_header
|
56
|
-
# object is the Doge
|
67
|
+
# object is the Doge used to initialize the presenter
|
57
68
|
content_tag(:h1, object.name)
|
58
69
|
end
|
59
70
|
|
@@ -68,30 +79,24 @@ class DogePresenter < Pres::Presenter
|
|
68
79
|
end
|
69
80
|
```
|
70
81
|
|
71
|
-
Wrap your model object in your controller with `present`:
|
82
|
+
Wrap your model object in a presenter in your controller with `present`:
|
72
83
|
|
73
84
|
```ruby
|
74
85
|
class DogesController
|
75
86
|
def show
|
87
|
+
@doge = present(Doge.find(params[:id]))
|
76
88
|
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
helper_method \
|
81
|
-
def doge
|
82
|
-
@doge ||= present(Doge.find(params[:id]))
|
83
|
-
end
|
84
89
|
end
|
85
90
|
```
|
86
91
|
|
87
92
|
Use the presenter object in `doges/show.haml.html`
|
88
93
|
|
89
94
|
```haml
|
90
|
-
= doge.name_header
|
95
|
+
= @doge.name_header
|
91
96
|
.status
|
92
|
-
You are #{doge.signed_in_status}
|
97
|
+
You are #{@doge.signed_in_status}
|
93
98
|
.links
|
94
|
-
.meme-link= doge.know_your_meme_link
|
99
|
+
.meme-link= @doge.know_your_meme_link
|
95
100
|
```
|
96
101
|
|
97
102
|
#### Collections
|
@@ -104,25 +109,19 @@ class DogePresenter < Pres::Presenter
|
|
104
109
|
end
|
105
110
|
```
|
106
111
|
|
107
|
-
|
112
|
+
Build an array of presenters in your controller with `present`:
|
108
113
|
|
109
114
|
```ruby
|
110
115
|
class DogesController
|
111
116
|
def index
|
117
|
+
@doges = present(Doge.all)
|
112
118
|
end
|
113
|
-
|
114
|
-
private
|
115
|
-
|
116
|
-
helper_method \
|
117
|
-
def doges
|
118
|
-
@doges ||= present(Doge.all)
|
119
|
-
end
|
120
119
|
end
|
121
120
|
```
|
122
121
|
|
123
122
|
Use the presenter objects in `doges/index.haml.html`
|
124
123
|
|
125
|
-
This renders "doges/_doge.html.haml" for each item,
|
124
|
+
This renders "doges/_doge.html.haml" for each item, following rails' usual conventions:
|
126
125
|
|
127
126
|
```haml
|
128
127
|
= render @doges
|
@@ -131,32 +130,34 @@ This renders "doges/_doge.html.haml" for each item, as usual:
|
|
131
130
|
Or use each:
|
132
131
|
|
133
132
|
```haml
|
134
|
-
- doges.each do |doge|
|
133
|
+
- @doges.each do |doge|
|
135
134
|
= doge.name_header
|
136
135
|
```
|
137
136
|
|
138
137
|
#### Present with options
|
139
138
|
|
140
|
-
Pass additional options to a Presenter as a hash
|
139
|
+
Pass additional options to a Presenter as a hash. The presenter class exposes the
|
140
|
+
`options` hash as a method:
|
141
141
|
|
142
142
|
```ruby
|
143
|
-
class UserPresenter < Pres::Presenter
|
144
|
-
def initialize(object, view_context, cool: false)
|
145
|
-
super
|
146
|
-
@cool = cool
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
143
|
user = User.new
|
151
|
-
|
144
|
+
|
145
|
+
# These two lines are the same:
|
146
|
+
# 1. explicit
|
147
|
+
presenter = UserPresenter.new(user, view_context, something: 123)
|
148
|
+
# 2. using #present
|
149
|
+
presenter = present(user, something: 123)
|
152
150
|
=> #<UserPresenter object: #<User> ...>
|
151
|
+
|
152
|
+
presenter.options[:something]
|
153
|
+
=> 123
|
153
154
|
```
|
154
155
|
|
155
|
-
####
|
156
|
+
#### Use a custom presenter class
|
156
157
|
|
157
158
|
By default, a presenter class corresponding to the model class name is
|
158
159
|
constructed in `present`. For example, if you present a `User`, a `UserPresenter`
|
159
|
-
class is constructed. An error is raised if the presenter class does not exist.
|
160
|
+
class is constructed. An error is raised if the presenter class does not exist.
|
160
161
|
To specify a different class, use the `presenter:` key.
|
161
162
|
|
162
163
|
```ruby
|
@@ -178,10 +179,10 @@ present(User.new)
|
|
178
179
|
# => #<MyPresenter object: #<User> ...>
|
179
180
|
```
|
180
181
|
|
181
|
-
####
|
182
|
+
#### Create presenters in views
|
182
183
|
|
183
|
-
|
184
|
-
visible to your views
|
184
|
+
You can create a presenter in your view code. First make the `present` method
|
185
|
+
visible to your views by declaring it a `helper_method`:
|
185
186
|
|
186
187
|
```ruby
|
187
188
|
class ApplicationController
|
@@ -190,29 +191,13 @@ class ApplicationController
|
|
190
191
|
end
|
191
192
|
```
|
192
193
|
|
193
|
-
|
194
|
+
Then you can create presenters inline in a view:
|
194
195
|
|
195
196
|
```haml
|
196
197
|
- present(@doge) do |doge|
|
197
198
|
= doge.name_header
|
198
199
|
```
|
199
200
|
|
200
|
-
### Presenters are objects
|
201
|
-
|
202
|
-
You can mix in common methods.
|
203
|
-
|
204
|
-
```ruby
|
205
|
-
module Shared
|
206
|
-
def truncated_name(length: 40)
|
207
|
-
truncate object.name, length: length
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
class DogePresenter < Pres::Presenter
|
212
|
-
include Shared
|
213
|
-
end
|
214
|
-
```
|
215
|
-
|
216
201
|
You can override methods as usual:
|
217
202
|
|
218
203
|
```ruby
|
@@ -220,7 +205,7 @@ class DogePresenter < Pres::Presenter
|
|
220
205
|
include Shared
|
221
206
|
|
222
207
|
def truncated_name(length: 60)
|
223
|
-
#
|
208
|
+
# override
|
224
209
|
super(length: length)
|
225
210
|
end
|
226
211
|
end
|
@@ -228,8 +213,7 @@ end
|
|
228
213
|
|
229
214
|
#### Presenters can create other presenters
|
230
215
|
|
231
|
-
|
232
|
-
which can then wrap child objects in presenters of their own.
|
216
|
+
Presenters can wrap child objects in presenters of their own.
|
233
217
|
|
234
218
|
```ruby
|
235
219
|
class DogePresenter < Pres::Presenter
|
data/lib/pres.rb
CHANGED
data/lib/pres/presenter.rb
CHANGED
data/lib/pres/presents.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Pres
|
2
4
|
module Presents
|
3
5
|
private
|
@@ -53,12 +55,20 @@ module Pres
|
|
53
55
|
if object.respond_to?(:to_ary)
|
54
56
|
object.map { |item| present(item, presenter: presenter, **args) }
|
55
57
|
else
|
56
|
-
presenter ||=
|
57
|
-
presenter ||= object.respond_to?(:presenter_class) && object.presenter_class
|
58
|
-
presenter ||= Object.const_get("#{object.class.name}Presenter")
|
58
|
+
presenter ||= presenter_klass(object)
|
59
59
|
wrapper = presenter.new(object, view_context, **args)
|
60
60
|
block_given? ? yield(wrapper) : wrapper
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
def presenter_klass(object)
|
65
|
+
if object.nil?
|
66
|
+
Presenter
|
67
|
+
elsif object.respond_to?(:presenter_class)
|
68
|
+
object.presenter_class
|
69
|
+
else
|
70
|
+
Object.const_get("#{object.class.name}Presenter")
|
71
|
+
end
|
72
|
+
end
|
63
73
|
end
|
64
74
|
end
|
data/lib/pres/version.rb
CHANGED
data/lib/pres/view_delegation.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Pres
|
2
4
|
module ViewDelegation
|
3
5
|
def view_context
|
4
6
|
@view_context
|
5
7
|
end
|
6
8
|
|
7
|
-
# Send missing
|
8
|
-
def method_missing(
|
9
|
-
if view_context.respond_to?(
|
10
|
-
view_context.send(
|
9
|
+
# Send missing methods to view_context first
|
10
|
+
def method_missing(method, *args, &block)
|
11
|
+
if view_context.respond_to?(method, true)
|
12
|
+
view_context.send(method, *args, &block)
|
11
13
|
else
|
12
14
|
super
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def respond_to_missing?(
|
17
|
-
view_context.respond_to?(
|
18
|
+
def respond_to_missing?(method, _ = false)
|
19
|
+
view_context.respond_to?(method, true) || super
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tee Parham
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-12-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: bundler
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '1.7'
|
21
|
-
type: :development
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - "~>"
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '1.7'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: minitest
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +66,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
66
|
requirements:
|
81
67
|
- - ">="
|
82
68
|
- !ruby/object:Gem::Version
|
83
|
-
version: 2.
|
69
|
+
version: 2.3.0
|
84
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
71
|
requirements:
|
86
72
|
- - ">="
|
@@ -88,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
74
|
version: '0'
|
89
75
|
requirements: []
|
90
76
|
rubyforge_project:
|
91
|
-
rubygems_version: 2.
|
77
|
+
rubygems_version: 2.7.8
|
92
78
|
signing_key:
|
93
79
|
specification_version: 4
|
94
80
|
summary: A Simple Rails Presenter
|