view 1.0.0.alpha.1 → 1.0.0.alpha.2
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.
- data/README.rdoc +29 -44
- data/lib/view/formatter.rb +126 -35
- data/lib/view/formatters/array.rb +32 -0
- data/lib/view/formatters/auto.rb +47 -24
- data/lib/view/formatters/blank.rb +20 -0
- data/lib/view/formatters/boolean.rb +17 -1
- data/lib/view/formatters/currency.rb +1 -1
- data/lib/view/formatters/date.rb +3 -2
- data/lib/view/formatters/datetime.rb +3 -2
- data/lib/view/formatters/delimited.rb +1 -1
- data/lib/view/formatters/file_link.rb +1 -1
- data/lib/view/formatters/guess.rb +18 -0
- data/lib/view/formatters/html_safe.rb +2 -1
- data/lib/view/formatters/human.rb +1 -1
- data/lib/view/formatters/image.rb +1 -1
- data/lib/view/formatters/link.rb +1 -1
- data/lib/view/formatters/percentage.rb +1 -1
- data/lib/view/formatters/phone.rb +1 -1
- data/lib/view/formatters/precision.rb +1 -1
- data/lib/view/formatters/self.rb +4 -1
- data/lib/view/formatters/sentence.rb +18 -23
- data/lib/view/formatters/size.rb +1 -1
- data/lib/view/helper.rb +1 -1
- data/lib/view/version.rb +1 -1
- data/lib/view.rb +81 -13
- data/spec/view/formatter_spec.rb +13 -0
- data/spec/view/formatters/auto_spec.rb +13 -16
- data/spec/view/formatters/blank_spec.rb +23 -0
- data/spec/view/formatters/boolean_spec.rb +6 -6
- data/spec/view/formatters/date_spec.rb +3 -3
- data/spec/view/formatters/datetime_spec.rb +2 -2
- data/spec/view/formatters/guess_spec.rb +25 -0
- data/spec/view/formatters/self_spec.rb +1 -1
- data/spec/view/formatters/sentence_spec.rb +17 -1
- metadata +28 -10
- data/lib/view/formatters/nil.rb +0 -11
- data/spec/view/formatters/nil_spec.rb +0 -15
- data/spec/view/view_spec.rb +0 -13
data/README.rdoc
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= View
|
2
2
|
|
3
|
+
{Source}[http://github.com/iain/view] | {Documentation}[http://rubydoc.info/github/iain/view/master/frames]
|
4
|
+
|
3
5
|
Automatic viewer. Very configurable. Very flexible. Very alpha (for now).
|
4
6
|
|
5
7
|
It is made for displaying stuff in views. This can be very handy for DSLs that create views.
|
@@ -11,7 +13,7 @@ But first, the view!
|
|
11
13
|
|
12
14
|
Use it from your views:
|
13
15
|
|
14
|
-
|
16
|
+
<%= view @post %>
|
15
17
|
|
16
18
|
View will try to figure out what the most logical way is to present the object you passed in.
|
17
19
|
If the @post object has a title for instance, it will use that.
|
@@ -20,7 +22,7 @@ See the auto formatter for more information.
|
|
20
22
|
|
21
23
|
You can use view anywhere you like:
|
22
24
|
|
23
|
-
puts View.
|
25
|
+
puts View.format(@post)
|
24
26
|
|
25
27
|
But beware that for many formatters, a reference to the template is required.
|
26
28
|
It is a helper for the view part of your application after all.
|
@@ -29,55 +31,56 @@ It is a helper for the view part of your application after all.
|
|
29
31
|
|
30
32
|
View will automatically try to choose the proper formatter. You can specify a formatter yourself:
|
31
33
|
|
32
|
-
|
34
|
+
<%= view @post.created_at, :as => :date %>
|
33
35
|
|
34
36
|
You can add a block to specify your own behavior. The parsed value is passed in as a block-variable.
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
+
<%= view @post.author do |author| %>
|
39
|
+
<%= link_to author, @post.author %>
|
40
|
+
<% end %>
|
38
41
|
|
39
42
|
Most formatters pass their options down to the method they use, such as the image formatter:
|
40
43
|
|
41
|
-
|
44
|
+
<%= view @user.avatar, :as => :image, :size => "40x40", :class => "avatar" %>
|
42
45
|
|
43
46
|
== Examples
|
44
47
|
|
45
48
|
There are many formatters included (18 and counting), but here are some interesting use cases of some of them.
|
46
49
|
|
47
50
|
# Options are passed to the helper methods:
|
48
|
-
|
51
|
+
view @post, :as => :link, :method => :delete, :confirm => "are you sure?"
|
49
52
|
|
50
53
|
# Renders a link to the edit_page of the post:
|
51
|
-
|
54
|
+
view @post, :as => :link, :path => [ :edit ]
|
52
55
|
|
53
56
|
# Renders a sentence of links:
|
54
|
-
|
57
|
+
view Post.all, :each => { :as => :link }
|
55
58
|
|
56
59
|
# When using paperclip, renders the image:
|
57
|
-
|
60
|
+
view @project.logo, :as => :image
|
58
61
|
|
59
62
|
# Renders "yes" or "no" (with I18n support!)
|
60
|
-
|
63
|
+
view @user.admin?
|
61
64
|
|
62
65
|
See the formatters in lib/views/formatters to see their full documentation.
|
63
66
|
|
64
67
|
== Adding formatters
|
65
68
|
|
66
|
-
You can add a formatter by inheriting from View::Formatter
|
67
|
-
The only method you need to implement is the
|
69
|
+
You can add a formatter by inheriting from +View::Formatter+.
|
70
|
+
The only method you need to implement is the +format+ method.
|
68
71
|
|
69
72
|
In the class you have access to the following methods:
|
70
73
|
|
71
|
-
* value
|
72
|
-
* options
|
73
|
-
* all_options
|
74
|
-
* template
|
74
|
+
* +value+: the object passed in
|
75
|
+
* +options+: a filtered hash of options
|
76
|
+
* +all_options+: the unfiltered hash
|
77
|
+
* +template+: call methods like link_to on this
|
75
78
|
|
76
79
|
If you wanted a uppercase formatter for example, you could do this:
|
77
80
|
|
78
81
|
class Uppercase < View::Formatter
|
79
82
|
|
80
|
-
def
|
83
|
+
def format
|
81
84
|
value.to_s.upcase
|
82
85
|
end
|
83
86
|
|
@@ -85,7 +88,7 @@ If you wanted a uppercase formatter for example, you could do this:
|
|
85
88
|
|
86
89
|
The name of the formatter is automatically infered from the name of the class.
|
87
90
|
|
88
|
-
You can use the
|
91
|
+
You can use the +.as+ method to specify a different name.
|
89
92
|
|
90
93
|
class Foo < View::Formatter
|
91
94
|
as :bar
|
@@ -99,20 +102,20 @@ You can control which options are allowed, by adding reserved options:
|
|
99
102
|
end
|
100
103
|
|
101
104
|
Now, the options method will return the options passed by the user, minus foo and bar.
|
102
|
-
To use them, in your code, use the all_options method.
|
105
|
+
To use them, in your code, use the +all_options+ method.
|
103
106
|
This is done to easily pass the options to another method, without cluttering:
|
104
107
|
|
105
108
|
class Paragraph < View::Formatter
|
106
|
-
def
|
109
|
+
def format
|
107
110
|
template.content_tag(:p, value.to_s, options)
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
111
|
-
To more tightly control which options are allowed, specify the
|
114
|
+
To more tightly control which options are allowed, specify the allowed options:
|
112
115
|
|
113
116
|
class Size < View::Formatter
|
114
117
|
self.allowed_options = [ :separator, :delimiter, :precision ]
|
115
|
-
def
|
118
|
+
def format
|
116
119
|
template.number_to_human_size(value, options)
|
117
120
|
end
|
118
121
|
end
|
@@ -121,33 +124,15 @@ You can use the existing formatters as examples.
|
|
121
124
|
|
122
125
|
== Configuration:
|
123
126
|
|
124
|
-
See lib/view.rb for information on configuration.
|
127
|
+
See +lib/view.rb+ for information on configuration.
|
125
128
|
|
126
129
|
== Installation
|
127
130
|
|
128
|
-
|
129
|
-
|
130
|
-
In Rails 3, just add it to your Gemfile:
|
131
|
+
Just add it to your Gemfile:
|
131
132
|
|
132
133
|
gem 'view'
|
133
134
|
|
134
|
-
Run
|
135
|
-
|
136
|
-
=== Rails 2
|
137
|
-
|
138
|
-
In Rails 2, add it to app/environment.rb:
|
139
|
-
|
140
|
-
config.gem 'view'
|
141
|
-
|
142
|
-
And run <tt>rake gems:install</tt> to get it.
|
143
|
-
|
144
|
-
Afterwards, include the helper mehtod manually, by editing app/helpers/application_helper.rb:
|
145
|
-
|
146
|
-
module ApplicationHelper
|
147
|
-
include View::Helper
|
148
|
-
end
|
149
|
-
|
150
|
-
Caution: some helpers may use new helper methods from Rails 3 and might not work in Rails 2.
|
135
|
+
Run +bundle install+ and you're ready to go!
|
151
136
|
|
152
137
|
== Contributing
|
153
138
|
|
data/lib/view/formatter.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module View
|
2
2
|
|
3
|
+
# @abstract Subclass and override {#format} to implement your own formatter.
|
3
4
|
class Formatter
|
4
5
|
|
5
6
|
attr_reader :value, :template, :block
|
@@ -13,58 +14,150 @@ module View
|
|
13
14
|
class_inheritable_array :allowed_options
|
14
15
|
self.allowed_options = []
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
@options = options
|
19
|
-
@template = template
|
20
|
-
@block = block
|
21
|
-
end
|
22
|
-
|
17
|
+
# When you inherit from View::Formatter, the formatters goes on the list,
|
18
|
+
# but in reverse order, so that newer formatters kan override older ones.
|
23
19
|
def self.inherited(formatter)
|
24
20
|
super
|
25
21
|
formatters.unshift(formatter)
|
26
22
|
end
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
# Specify your own name for the formatter. By default the name of the class
|
25
|
+
# will be used (without any namespacing), but you can override it yourself
|
26
|
+
# by calling this method.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# class SomeStrangeName < View::Formatter
|
30
|
+
# as :real_name
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# View.format @foo, :as => :real_name
|
34
|
+
#
|
35
|
+
# @param [Symbol] type The new name of the formatter
|
32
36
|
def self.as(type)
|
33
37
|
@type = type
|
34
38
|
end
|
35
39
|
|
40
|
+
# @return [String] the type of the formatter, either set via +.as+ or
|
41
|
+
# automatically deducted from the class name.
|
42
|
+
#
|
43
|
+
# @see .as
|
36
44
|
def self.type
|
37
45
|
@type || name.split('::').last.underscore
|
38
46
|
end
|
39
47
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
# By default, blank values (nil, empty strings, etc), will override any
|
49
|
+
# formatter you specified. This way empty values are handled globally.
|
50
|
+
#
|
51
|
+
# If you don't want this, you can either turn it off per formatter.
|
52
|
+
# Call this method to turn it off.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# class IHandleMyOwnBlank < View::Formatter
|
56
|
+
# skip_blank_formatter
|
57
|
+
# # etc...
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @see View::Blank
|
61
|
+
def self.skip_blank_formatter
|
62
|
+
@skip_blank_formatter = true
|
63
|
+
end
|
64
|
+
|
65
|
+
# If you didn't specify a format instance method inside specific
|
66
|
+
# formatters, this will raise an error.
|
67
|
+
#
|
68
|
+
# @abstract Subclass and override {#format} to implement your own formatter.
|
69
|
+
# @return [String] the formatted value
|
44
70
|
def format
|
45
|
-
if block
|
46
|
-
captured_value
|
47
|
-
else
|
48
|
-
formatted_value
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def to_s
|
53
71
|
msg <<-MSG.squeeze(' ')
|
54
|
-
The only thing a formatter needs to do is implement the #
|
72
|
+
The only thing a formatter needs to do is implement the #format method.
|
55
73
|
If you see this error, you forgot to do that for the #{self.class.type} formatter.
|
56
74
|
MSG
|
57
75
|
raise NotImplementedError.new(msg)
|
58
76
|
end
|
59
77
|
|
78
|
+
# The "safe" options that you can toss around to helper methods.
|
79
|
+
#
|
80
|
+
# You can specify which methods are "safe" by white listing or black
|
81
|
+
# listing. White listing takes precedence over black listing.
|
82
|
+
#
|
83
|
+
# To access options that are filtered out, use +all_options+.
|
84
|
+
# It's generally a good idea to black list options that you use inside your
|
85
|
+
# formatter.
|
86
|
+
#
|
87
|
+
# The options +:as+ and +:block_arguments+ are black listed by default.
|
88
|
+
#
|
89
|
+
# @example White listing:
|
90
|
+
#
|
91
|
+
# class Sentence < View::Formatter
|
92
|
+
# self.allowed_options = [ :words_connector, :last_word_connector ]
|
93
|
+
#
|
94
|
+
# def format
|
95
|
+
# value.to_sentence(options)
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# @example Black listing:
|
100
|
+
#
|
101
|
+
# class Link < View::Formatter
|
102
|
+
# self.reserved_options = [ :to ]
|
103
|
+
#
|
104
|
+
# def format
|
105
|
+
# template.link_to(value.to_s, all_options[:to], options)
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# @return [Hash] filtered options
|
110
|
+
# @see #all_options
|
60
111
|
def options
|
61
112
|
default_options.merge(all_options).delete_if do |key, value|
|
62
113
|
option_not_allowed?(key)
|
63
114
|
end
|
64
115
|
end
|
65
116
|
|
117
|
+
# This calls the format action. You can override it to do something with
|
118
|
+
# the formatted value. This doesn't (and shouldn't) do any formatting
|
119
|
+
# itself.
|
120
|
+
#
|
121
|
+
# @see #format
|
122
|
+
def to_s
|
123
|
+
format
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return All options, unfiltered.
|
127
|
+
# @see #options
|
128
|
+
def all_options
|
129
|
+
@options
|
130
|
+
end
|
131
|
+
|
66
132
|
private
|
67
133
|
|
134
|
+
def self.skip_blank_formatter?
|
135
|
+
@skip_blank_formatter
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.format(*args, &block)
|
139
|
+
new(*args, &block).send(:format!)
|
140
|
+
end
|
141
|
+
|
142
|
+
def format!
|
143
|
+
if block
|
144
|
+
captured_value
|
145
|
+
else
|
146
|
+
formatted_value
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.formatters
|
151
|
+
View.formatters ||= []
|
152
|
+
end
|
153
|
+
|
154
|
+
def initialize(value, options = {}, template = nil, &block)
|
155
|
+
@value = value
|
156
|
+
@options = options
|
157
|
+
@template = template
|
158
|
+
@block = block
|
159
|
+
end
|
160
|
+
|
68
161
|
def template_can_capture?
|
69
162
|
template && template.respond_to?(:capture)
|
70
163
|
end
|
@@ -78,31 +171,29 @@ module View
|
|
78
171
|
end
|
79
172
|
|
80
173
|
def captured_value_by_template
|
81
|
-
template.capture(
|
174
|
+
template.capture(*block_arguments, &block)
|
82
175
|
end
|
83
176
|
|
84
177
|
def captured_return_value
|
85
|
-
block.call(
|
178
|
+
block.call(*block_arguments)
|
86
179
|
end
|
87
180
|
|
88
181
|
def formatted_value
|
182
|
+
formatter_not_found unless formatter
|
89
183
|
formatter.new(value, all_options, template, &block).to_s
|
90
184
|
end
|
91
185
|
|
92
186
|
def formatter
|
93
|
-
|
187
|
+
blank_formatter || find_formatter
|
94
188
|
end
|
95
189
|
|
96
190
|
def formatter_not_found
|
191
|
+
formatter_names = self.class.formatters.map { |formatter| formatter.type.to_s }
|
97
192
|
raise "Couldn't find the #{as} formatter. Got: #{formatter_names.join(', ')}"
|
98
193
|
end
|
99
194
|
|
100
|
-
def formatter_names
|
101
|
-
self.class.formatters.map { |formatter| formatter.type.to_s }
|
102
|
-
end
|
103
|
-
|
104
195
|
def find_formatter
|
105
|
-
self.class.formatters.find { |formatter| formatter.type.to_s == as.to_s }
|
196
|
+
@formatter ||= self.class.formatters.find { |formatter| formatter.type.to_s == as.to_s }
|
106
197
|
end
|
107
198
|
|
108
199
|
def option_not_allowed?(key)
|
@@ -114,15 +205,15 @@ module View
|
|
114
205
|
end
|
115
206
|
|
116
207
|
def block_arguments
|
117
|
-
all_options[:block_arguments] || []
|
208
|
+
all_options[:block_arguments] || [ formatted_value ]
|
118
209
|
end
|
119
210
|
|
120
211
|
def as
|
121
212
|
all_options[:as] || View.default_formatter
|
122
213
|
end
|
123
214
|
|
124
|
-
def
|
125
|
-
|
215
|
+
def blank_formatter
|
216
|
+
Blank if !find_formatter.skip_blank_formatter? && value.blank?
|
126
217
|
end
|
127
218
|
|
128
219
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module View
|
2
|
+
|
3
|
+
# @abstract Subclass this for html safe lists with formatted each support.
|
4
|
+
class Array < Formatter
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
if all_safe?
|
8
|
+
super.html_safe
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def all_safe?
|
15
|
+
formatted_values.all? do |element|
|
16
|
+
element.respond_to?(:html_safe?) && element.html_safe?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def formatted_values
|
21
|
+
@formatted_values ||= value.map do |element|
|
22
|
+
View.format(element, each, template, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
all_options[:each] || { :as => View.default_formatter }
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/view/formatters/auto.rb
CHANGED
@@ -1,47 +1,70 @@
|
|
1
1
|
module View
|
2
2
|
|
3
|
+
# The auto formatter tries to figure out what other formatter should be the
|
4
|
+
# most appropriate to use and delegates the formatting to that formatter.
|
5
|
+
#
|
6
|
+
# This is fully configurable too. See Auto.add
|
3
7
|
class Auto < Formatter
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
skip_blank_formatter
|
10
|
+
|
11
|
+
# Adds behavior to check which view should automatically be used.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
#
|
15
|
+
# View::Auto.add :boolean do
|
16
|
+
# value == true || value == false
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# @param [Symbol] formatter_name The name of the formatter
|
20
|
+
#
|
21
|
+
# @yield The block is eval'd inside the formatter, so you can use the
|
22
|
+
# instance methods that are available for every formatters, like +value+
|
23
|
+
# and +options+.
|
24
|
+
#
|
25
|
+
# @yieldreturn [true, false] The first block to evaluate to true will
|
26
|
+
# determine the formatter. New blocks are checked first.
|
27
|
+
def self.add(formatter_name, &block)
|
28
|
+
auto_formatters.unshift(:formatter => formatter_name, :block => block)
|
11
29
|
end
|
12
30
|
|
13
|
-
|
14
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def format
|
34
|
+
format!
|
15
35
|
end
|
16
36
|
|
17
|
-
def
|
18
|
-
|
37
|
+
def self.auto_formatters
|
38
|
+
@auto_formatters ||= []
|
19
39
|
end
|
20
40
|
|
21
|
-
def
|
22
|
-
|
41
|
+
def as
|
42
|
+
as = self.class.auto_formatters.find { |auto| instance_eval(&auto[:block]) }
|
43
|
+
as ? as[:formatter] : :guess
|
23
44
|
end
|
24
45
|
|
25
|
-
|
26
|
-
value.
|
46
|
+
add :datetime do
|
47
|
+
value.respond_to?(:strftime)
|
27
48
|
end
|
28
49
|
|
29
|
-
|
30
|
-
value.respond_to?(
|
50
|
+
add :file_link do
|
51
|
+
View.file_methods.any? { |method| value.respond_to?(method) }
|
31
52
|
end
|
32
53
|
|
33
|
-
|
34
|
-
|
54
|
+
add View.default_list_formatter do
|
55
|
+
value.respond_to?(:each)
|
35
56
|
end
|
36
57
|
|
37
|
-
|
38
|
-
|
58
|
+
add :link do
|
59
|
+
all_options.has_key?(:to)
|
39
60
|
end
|
40
61
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
62
|
+
add :blank do
|
63
|
+
value.blank?
|
64
|
+
end
|
65
|
+
|
66
|
+
add :boolean do
|
67
|
+
value == true || value == false
|
45
68
|
end
|
46
69
|
|
47
70
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module View
|
2
|
+
|
3
|
+
# The default formatter for blank objects, like nil, empty strings and empty
|
4
|
+
# arrays. It will display an empty string or something else, which you can
|
5
|
+
# configure with I18n.
|
6
|
+
#
|
7
|
+
# @example config/locales/en.yml
|
8
|
+
# en:
|
9
|
+
# view:
|
10
|
+
# blank: "nothing"
|
11
|
+
#
|
12
|
+
class Blank < Formatter
|
13
|
+
|
14
|
+
def format
|
15
|
+
::I18n.t(:blank, :scope => :view, :default => "").html_safe
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -1,8 +1,24 @@
|
|
1
1
|
module View
|
2
2
|
|
3
|
+
# The default formatter for booleans.
|
4
|
+
#
|
5
|
+
# It will display "Yes" or "No".
|
6
|
+
#
|
7
|
+
# You can configure it with I18n. When writing 'true' and 'false' as keys in
|
8
|
+
# yaml, please don't forget the quotes.
|
9
|
+
#
|
10
|
+
# @example config/locales/en.yml
|
11
|
+
# en:
|
12
|
+
# view:
|
13
|
+
# booleans:
|
14
|
+
# 'true': Yup
|
15
|
+
# 'false': Nope
|
16
|
+
#
|
3
17
|
class Boolean < Formatter
|
4
18
|
|
5
|
-
|
19
|
+
skip_blank_formatter
|
20
|
+
|
21
|
+
def format
|
6
22
|
::I18n.t(boolean_value.to_s, :scope => [:view, :booleans], :default => default)
|
7
23
|
end
|
8
24
|
|
data/lib/view/formatters/date.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module View
|
2
|
+
|
3
|
+
# This formatter is the fallback formatter for auto. It figures out which
|
4
|
+
# method will be called to get a proper version to render.
|
5
|
+
#
|
6
|
+
# @see View.guessing_methods
|
7
|
+
class Guess < Formatter
|
8
|
+
|
9
|
+
def format
|
10
|
+
View.guessing_methods.each do |method|
|
11
|
+
return value.send(method) if value.respond_to?(method)
|
12
|
+
end
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/lib/view/formatters/link.rb
CHANGED
data/lib/view/formatters/self.rb
CHANGED
@@ -1,31 +1,26 @@
|
|
1
1
|
module View
|
2
2
|
|
3
|
-
|
3
|
+
# This formatter is for arrays and stuff into a sentence.
|
4
|
+
#
|
5
|
+
# You can pass the options for sentence and, like any other array formatter,
|
6
|
+
# you can pass an each option, that contains the options for every element in
|
7
|
+
# the array.
|
8
|
+
#
|
9
|
+
# If you don't pass any options in each, it will autoformat every element.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# View.format @dates, :as => :sentence,
|
14
|
+
# :each => { :as => :date, :format => :short }
|
15
|
+
#
|
16
|
+
# @see View::Array
|
17
|
+
# @see http://rubydoc.info/docs/rails/3.0.0/Array:to_sentence
|
18
|
+
class Sentence < Array
|
4
19
|
|
5
20
|
self.allowed_options = [ :words_connector, :two_words_connector, :last_word_connector ]
|
6
21
|
|
7
|
-
def
|
8
|
-
|
9
|
-
sentence.html_safe
|
10
|
-
else
|
11
|
-
sentence
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def all_safe?
|
16
|
-
formatted_values.all? { |element| element.html_safe? }
|
17
|
-
end
|
18
|
-
|
19
|
-
def formatted_values
|
20
|
-
value.map { |element| View.to_s(element, each, template, &block) }
|
21
|
-
end
|
22
|
-
|
23
|
-
def sentence
|
24
|
-
formatted_values.to_sentence if value.present?
|
25
|
-
end
|
26
|
-
|
27
|
-
def each
|
28
|
-
all_options[:each] || { :as => View.default_formatter }
|
22
|
+
def format
|
23
|
+
formatted_values.to_sentence(options)
|
29
24
|
end
|
30
25
|
|
31
26
|
end
|
data/lib/view/formatters/size.rb
CHANGED
data/lib/view/helper.rb
CHANGED
data/lib/view/version.rb
CHANGED
data/lib/view.rb
CHANGED
@@ -4,26 +4,94 @@ module View
|
|
4
4
|
autoload :Helper, 'view/helper'
|
5
5
|
autoload :VERSION, 'view/version'
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
class << self
|
8
|
+
# Used by the guess filter, these are the methods used to format an object.
|
9
|
+
# It will use the first method that the object responds to.
|
10
|
+
attr_accessor :guessing_methods
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
# To determine if something is an uploaded image, it checks
|
13
|
+
# to see whether it responds to one of these methods.
|
14
|
+
attr_accessor :file_methods
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
# To show an image, it will use one of these methods to get the src
|
17
|
+
# attribute.
|
18
|
+
attr_accessor :path_methods
|
15
19
|
|
16
|
-
|
17
|
-
|
20
|
+
# You can set a default argument for rendering images, like the style or size
|
21
|
+
# of the image. It will be passed to one of the path_methods.
|
22
|
+
attr_accessor :path_arguments
|
18
23
|
|
19
|
-
|
20
|
-
|
24
|
+
# Which formatter will be used by default. The default is auto, which does
|
25
|
+
# all sorts of interesting stuff to see what to do.
|
26
|
+
attr_accessor :default_formatter
|
21
27
|
|
22
|
-
|
28
|
+
# The auto formatter will choose this formatter by default when your value is
|
29
|
+
# an array (or really, something that responds to +each+).
|
30
|
+
attr_accessor :default_list_formatter
|
23
31
|
|
32
|
+
# Holds a list of formatters. It will be filled automatically by inheriting
|
33
|
+
# from View::Formatter.
|
34
|
+
attr_accessor :formatters
|
24
35
|
|
25
|
-
|
26
|
-
|
36
|
+
# Shorthand for configuring this gem.
|
37
|
+
#
|
38
|
+
# @example In +config/initializers/view.rb+
|
39
|
+
#
|
40
|
+
# View.configure do |config|
|
41
|
+
# config.default_formatter = :self
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @yield [config] The View module
|
45
|
+
def configure
|
46
|
+
yield self
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
self.guessing_methods = %w|to_label display_name full_name name title
|
52
|
+
username login value to_s|
|
53
|
+
self.file_methods = %w|mounted_as file? public_filename|
|
54
|
+
self.path_methods = %w|mounted_as url public_filename|
|
55
|
+
self.path_arguments = []
|
56
|
+
self.default_formatter = :auto
|
57
|
+
self.default_list_formatter = :sentence
|
58
|
+
|
59
|
+
|
60
|
+
# This is the main method to use this gem. Any formatting from outside this
|
61
|
+
# gem should be done through this method (notwithstanding custom formatters).
|
62
|
+
#
|
63
|
+
# In every day usage you will access it through the +view+ helper method,
|
64
|
+
# because most formatters require a view to render links or images. Any
|
65
|
+
# helper method should also point to this method.
|
66
|
+
#
|
67
|
+
# @see View::Helper#view
|
68
|
+
#
|
69
|
+
# @example Rendering a link
|
70
|
+
# module PostsHelper
|
71
|
+
# def link_to_post
|
72
|
+
# View.format @post, :as => :link, self
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# @param [Object] value the object to be shown
|
77
|
+
# @param [Hash] options Any extra options
|
78
|
+
#
|
79
|
+
# @option options [Symbol] :as (:auto) The name of the formatter
|
80
|
+
# @option options [Array] :block_arguments (nil) Overrides the arguments passed to
|
81
|
+
# the block of this method.
|
82
|
+
#
|
83
|
+
# @param [ActionView::Template] Template the view instance on which to call
|
84
|
+
# helper methods like +link_to+ and +image_tag+.
|
85
|
+
# You need this for many formatters.
|
86
|
+
#
|
87
|
+
# @yield [formatted_string] The block will be captured (using the template if
|
88
|
+
# possible) to alter the formatted string that would otherwise be returned.
|
89
|
+
# Consider it as a final modifier after the view formatter has done its
|
90
|
+
# work.
|
91
|
+
#
|
92
|
+
# @return [String] the object formatted to a string
|
93
|
+
def self.format(value, options = {}, template = nil, &block)
|
94
|
+
Formatter.format(value, options, template, &block)
|
27
95
|
end
|
28
96
|
|
29
97
|
end
|
@@ -2,24 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "Auto formatter" do
|
4
4
|
|
5
|
-
it "
|
6
|
-
|
7
|
-
View.to_s(object).should == "some label"
|
5
|
+
it "formats like a boolean automatically" do
|
6
|
+
View.format(true).should == "Yes"
|
8
7
|
end
|
9
8
|
|
10
|
-
it "
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
View.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
object = Struct.new(:login).new("loginname")
|
22
|
-
View.to_s(object).should == "loginname"
|
9
|
+
it "is configurable" do
|
10
|
+
foo = Class.new(View::Formatter) do
|
11
|
+
as :foo
|
12
|
+
def format
|
13
|
+
"!!!#{value}!!!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
View::Auto.add :foo do
|
17
|
+
value == "foobar"
|
18
|
+
end
|
19
|
+
View.format("foobar").should == "!!!foobar!!!"
|
23
20
|
end
|
24
21
|
|
25
22
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Blank formatter" do
|
4
|
+
|
5
|
+
it "formats nil" do
|
6
|
+
View.format(nil).should == ""
|
7
|
+
end
|
8
|
+
|
9
|
+
it "formats empty strings" do
|
10
|
+
View.format(" ").should == ""
|
11
|
+
end
|
12
|
+
|
13
|
+
it "formats empty arrays" do
|
14
|
+
View.format([]).should == ""
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses i18n for nil" do
|
18
|
+
with_translation :view => { :blank => "nothing" } do
|
19
|
+
View.format(nil).should == "nothing"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -3,24 +3,24 @@ require 'spec_helper'
|
|
3
3
|
describe "Boolean formatter" do
|
4
4
|
|
5
5
|
it "formats true" do
|
6
|
-
View.
|
6
|
+
View.format(true).should == "Yes"
|
7
7
|
end
|
8
8
|
|
9
9
|
it "formats false" do
|
10
|
-
View.
|
10
|
+
View.format(false).should == "No"
|
11
11
|
end
|
12
12
|
|
13
13
|
it "formats boolean values" do
|
14
|
-
View.
|
15
|
-
View.
|
14
|
+
View.format("h", :as => :boolean).should == "Yes"
|
15
|
+
View.format(nil, :as => :boolean).should == "No"
|
16
16
|
end
|
17
17
|
|
18
18
|
it "localizes booleans" do
|
19
19
|
with_translation :view => { :booleans => { :true => "yup" } } do
|
20
|
-
View.
|
20
|
+
View.format(true).should == "yup"
|
21
21
|
end
|
22
22
|
with_translation :view => { :booleans => { :false => "nope" } } do
|
23
|
-
View.
|
23
|
+
View.format(false).should == "nope"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -5,18 +5,18 @@ describe "Date formatter" do
|
|
5
5
|
it "localizes dates" do
|
6
6
|
date = Date.new(2010, 10, 11)
|
7
7
|
with_translation :date => { :formats => { :foo => "%A" }, :day_names => [ "zondag", "maandag" ] } do
|
8
|
-
View.
|
8
|
+
View.format(date, :format => :foo).should == "maandag"
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
it "formats dates" do
|
13
13
|
date = Date.new(2010, 10, 10)
|
14
|
-
View.
|
14
|
+
View.format(date).should == "2010-10-10"
|
15
15
|
end
|
16
16
|
|
17
17
|
it "forces datetimes to date" do
|
18
18
|
time = Time.new(2010, 10, 10, 8, 45, 30, '+01:00')
|
19
|
-
View.
|
19
|
+
View.format(time, :as => :date).should == "2010-10-10"
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
@@ -4,13 +4,13 @@ describe "Datetime formatter" do
|
|
4
4
|
|
5
5
|
it "formats" do
|
6
6
|
time = Time.new(2010, 10, 10, 8, 45, 30, '+01:00')
|
7
|
-
View.
|
7
|
+
View.format(time).should == "Sun, 10 Oct 2010 08:45:30 +0100"
|
8
8
|
end
|
9
9
|
|
10
10
|
it "localizes" do
|
11
11
|
time = Time.new(2010, 10, 10, 8, 45, 30, '+01:00')
|
12
12
|
with_translation :time => { :formats => { :short => "%d-%m-%Y %H:%M" } } do
|
13
|
-
View.
|
13
|
+
View.format(time, :format => :short).should == "10-10-2010 08:45"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Guess formatter" do
|
4
|
+
|
5
|
+
it "guesses the to_label" do
|
6
|
+
object = Struct.new(:to_label).new("some label")
|
7
|
+
View.format(object).should == "some label"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "guesses to_s" do
|
11
|
+
object = Struct.new(:to_s).new("string")
|
12
|
+
View.format(object).should == "string"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "guesses a name" do
|
16
|
+
object = Struct.new(:name).new("my name")
|
17
|
+
View.format(object).should == "my name"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "guesses a login" do
|
21
|
+
object = Struct.new(:login).new("loginname")
|
22
|
+
View.format(object).should == "loginname"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -4,7 +4,23 @@ describe "Sentence formatter" do
|
|
4
4
|
|
5
5
|
it "constructs a sentence" do
|
6
6
|
object = [ 1, 2, 3 ]
|
7
|
-
View.
|
7
|
+
View.format(object).should == "1, 2, and 3"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has options for each element" do
|
11
|
+
object = [ Date.today ]
|
12
|
+
subject = View.format(object, :each => { :format => :short })
|
13
|
+
subject.should == I18n.l(Date.today, :format => :short)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "makes the sentence html safe if all elements are" do
|
17
|
+
object = [ "safe".html_safe ]
|
18
|
+
View.format(object).should be_html_safe
|
19
|
+
end
|
20
|
+
|
21
|
+
it "doesn't make the sentence html safe if not all elements are safe" do
|
22
|
+
object = [ "safe".html_safe, "unsafe" ]
|
23
|
+
View.format(object).should_not be_html_safe
|
8
24
|
end
|
9
25
|
|
10
26
|
end
|
metadata
CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
|
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- alpha
|
10
|
-
-
|
11
|
-
version: 1.0.0.alpha.
|
10
|
+
- 2
|
11
|
+
version: 1.0.0.alpha.2
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Iain Hecker
|
@@ -16,10 +16,24 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-10-
|
19
|
+
date: 2010-10-10 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
|
-
dependencies:
|
22
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: rails
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
segments:
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 3.0.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
23
37
|
description: A very extensible way of viewing objects, easily integrated with other gems
|
24
38
|
email:
|
25
39
|
- iain@iain.nl
|
@@ -31,18 +45,20 @@ extra_rdoc_files:
|
|
31
45
|
- README.rdoc
|
32
46
|
files:
|
33
47
|
- lib/view/formatter.rb
|
48
|
+
- lib/view/formatters/array.rb
|
34
49
|
- lib/view/formatters/auto.rb
|
50
|
+
- lib/view/formatters/blank.rb
|
35
51
|
- lib/view/formatters/boolean.rb
|
36
52
|
- lib/view/formatters/currency.rb
|
37
53
|
- lib/view/formatters/date.rb
|
38
54
|
- lib/view/formatters/datetime.rb
|
39
55
|
- lib/view/formatters/delimited.rb
|
40
56
|
- lib/view/formatters/file_link.rb
|
57
|
+
- lib/view/formatters/guess.rb
|
41
58
|
- lib/view/formatters/html_safe.rb
|
42
59
|
- lib/view/formatters/human.rb
|
43
60
|
- lib/view/formatters/image.rb
|
44
61
|
- lib/view/formatters/link.rb
|
45
|
-
- lib/view/formatters/nil.rb
|
46
62
|
- lib/view/formatters/percentage.rb
|
47
63
|
- lib/view/formatters/phone.rb
|
48
64
|
- lib/view/formatters/precision.rb
|
@@ -56,15 +72,16 @@ files:
|
|
56
72
|
- init.rb
|
57
73
|
- README.rdoc
|
58
74
|
- spec/spec_helper.rb
|
75
|
+
- spec/view/formatter_spec.rb
|
59
76
|
- spec/view/formatters/auto_spec.rb
|
77
|
+
- spec/view/formatters/blank_spec.rb
|
60
78
|
- spec/view/formatters/boolean_spec.rb
|
61
79
|
- spec/view/formatters/date_spec.rb
|
62
80
|
- spec/view/formatters/datetime_spec.rb
|
63
|
-
- spec/view/formatters/
|
81
|
+
- spec/view/formatters/guess_spec.rb
|
64
82
|
- spec/view/formatters/self_spec.rb
|
65
83
|
- spec/view/formatters/sentence_spec.rb
|
66
84
|
- spec/view/helper_spec.rb
|
67
|
-
- spec/view/view_spec.rb
|
68
85
|
has_rdoc: true
|
69
86
|
homepage: http://github.com/iain/view
|
70
87
|
licenses: []
|
@@ -101,12 +118,13 @@ specification_version: 3
|
|
101
118
|
summary: Displaying objects automatically
|
102
119
|
test_files:
|
103
120
|
- spec/spec_helper.rb
|
121
|
+
- spec/view/formatter_spec.rb
|
104
122
|
- spec/view/formatters/auto_spec.rb
|
123
|
+
- spec/view/formatters/blank_spec.rb
|
105
124
|
- spec/view/formatters/boolean_spec.rb
|
106
125
|
- spec/view/formatters/date_spec.rb
|
107
126
|
- spec/view/formatters/datetime_spec.rb
|
108
|
-
- spec/view/formatters/
|
127
|
+
- spec/view/formatters/guess_spec.rb
|
109
128
|
- spec/view/formatters/self_spec.rb
|
110
129
|
- spec/view/formatters/sentence_spec.rb
|
111
130
|
- spec/view/helper_spec.rb
|
112
|
-
- spec/view/view_spec.rb
|
data/lib/view/formatters/nil.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "Nil formatter" do
|
4
|
-
|
5
|
-
it "formats nil" do
|
6
|
-
View.to_s(nil).should == ""
|
7
|
-
end
|
8
|
-
|
9
|
-
it "uses i18n for nil" do
|
10
|
-
with_translation :view => { :nil => "nothing" } do
|
11
|
-
View.to_s(nil).should == "nothing"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
data/spec/view/view_spec.rb
DELETED