forked from niko/representer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME
More file actions
168 lines (149 loc) · 6.03 KB
/
README
File metadata and controls
168 lines (149 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# (Re)Presenters for Rails
# A possible presenter solution.
# Ask/Write florian.hanke@gmail.com if you have questions/feedback, thanks! :)
# Fork if you have improvements. Tell me where to merge them from, thanks!
#
# Problem: Display Methods are not well placed either in
# * models: Violation of the MVC principle.
# * helpers: No Polymorphism.
# Solution:
# A thin proxy layer over a model, with access to the controller, used by the view or controller.
#
# IMPORTANT NOTE:
# As of yet it is needed to copy the representer/views/presenters/collection
# directory to the corresponding location in app/views/presenters/collection.
# This is only needed if you wish to use the collection presenter.
# Note: Rewrite the collection templates as needed, they are rather basic.
#
# * Getting a presenter in a view or a controller.
#
# Call presenter_for:
# Note: By convention, uses Presenters::Model::Class::Name, thus prefixing Presenters:: to
# the model class name.
presenter_instance = presenter_for model_instance
# * Getting a collection presenter in a view.
#
# The collection presenter renders each of the given items with its presenter.
#
# Call collection_presenter_for:
collection_presenter_instance = collection_presenter_for enumerable_containing_model_instances
# Rendering a list.
collection_presenter_instance.list
# Rendering a collection.
collection_presenter_instance.collection
# Rendering a table.
collection_presenter_instance.table
# Rendering a pagination.
# Note: Only works if the passed parameter for collection_presenter_for is a PaginationEnumeration.
collection_presenter_instance.pagination
# * Writing filtered delegate methods on the presenter.
#
# Will create two delegate methods first_name and last_name that delegate to the model.
model_reader :first_name, :last_name
# Will create a description delegate method that filters the model value through h.
model_reader :description, :filter_through => :h
# Will create a description delegate method that filters the model value through first textilize, then h.
model_reader :description, :filter_through => [:textilize, :h]
# Will create both a first_name and last_name delegate method
# that filters the model value through first textilize, then h.
model_reader :first_name, :last_name, :filter_through => [:textilize, :h]
# Note: Filter methods can be any method on the presenter with arity 1.
# * Rendering presenter templates
#
# Use render_as(template_name, format = nil).
#
# Gets a Presenters::Model::Class instance
presenter = presenter_for Model::Class.new
# Gets a Presenters::<model_instance.class.name> instance
presenter = presenter_for model_instance
# Renders the 'example' partial in presenters/model/class.
# Note: Renders a format depending on the request. ../index.text will render example.text.erb.
presenter.render_as :example
# Renders the 'example.text.erb' partial in presenters/model/class.
presenter.render_as :example, :text
# * Rails Helpers in Presenters
#
# Use helper as in the controller.
helper ActionView::Helpers::UrlHelper
helper ApplicationHelper
# Note: It is helpful to create a superclass to all presenters in the project
# with generally used helpers.
# We use Presenters::Project a lot, for example. See example below.
# * Controller Delegate Methods
#
# Use controller_method(*args).
#
# Delegates current_user and logger on the presenter to the controller.
controller_method :current_user, :logger
# * Big Example
#
# The following classes all have specs of course ;) But are not shown since they don't help the example.
# Presenters superclass for this project.
#
# We include all of Rails' helpers for the presenters in this project.
# Also, we include the ApplicationHelper.
#
# We delegate logger and current_user calls in the presenters to
# the active controller.
#
class Presenters::Project < Presenters::Base
# All of Rails' standard helpers.
helper ActionView::Helpers::ActiveRecordHelper
helper ActionView::Helpers::TagHelper
helper ActionView::Helpers::FormTagHelper
helper ActionView::Helpers::FormOptionsHelper
helper ActionView::Helpers::FormHelper
helper ActionView::Helpers::UrlHelper
helper ActionView::Helpers::AssetTagHelper
helper ActionView::Helpers::PrototypeHelper
helper ActionView::Helpers::TextHelper
helper ApplicationHelper
controller_method :logger, :current_user
end
# All items have a description that needs to be filtered by textilize.
#
class Presenters::Item < Presenters::Project
model_reader :description, :filter_through => :textilize
# Use price in the view as follows:
# = presenter.price - will display e.g. 16.57 CHF, since it is filtered first through localize_currency
model_reader :price, :filter_through => :localize_currency
# Converts a database price tag to the users chosen value, with the users preferred currency appended.
# If the user is Swiss, localize_currency will convert 10 Euros to "16.57 CHF"
#
def localize_currency(price_in_euros)
converted_price = current_user.convert_price(price_in_euros)
"#{converted_price} #{current_user.currency.to_s}"
end
end
# This class also has partial templates in the directory
# app/views/presenters/book
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call presenter_for on a book in the view or controller to get this presenter.
#
class Presenters::Book < Presenters::Item
model_reader :author, :title, :pages
model_reader :excerpt, :filter_through => :textilize
def header
content_tag(:h1, "#{author} – #{title}")
end
def full_description
content_tag(:p, "#{excerpt} #{description}", :class => 'description full')
end
end
# This class also has partial templates in the directory
# app/views/presenters/toy
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call presenter_for on a toy in the view or controller to get this presenter.
#
class Presenters::Toy < Presenters::Item
model_reader :starting_age, :small_dangerous_parts
def obligatory_parental_warning
"Warning, this toy can only be used by kids ages #{starting_age} and up. Your department of health. Thank you."
end
end