sinatra-support 1.0.1

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/HISTORY.md ADDED
@@ -0,0 +1,53 @@
1
+ v1.0.1 - Mar 27, 2011
2
+ ---------------------
3
+
4
+ ### Added:
5
+ * Implement Sinatra::I18nSupport
6
+
7
+ ### Misc:
8
+ * Update README with URLs
9
+ * Correct the wrong gem name in the documentation
10
+
11
+ v1.0.0 - Mar 27, 2011
12
+ ---------------------
13
+
14
+ Massive 1.0 refactor and massive documentation update. Now sporting a
15
+ completely new API and breaks compatibility with 0.2.0.
16
+
17
+ ### Added:
18
+ * CssSupport
19
+ * JsSupport
20
+ * IfHelpers
21
+
22
+ v0.2.0
23
+ ------
24
+
25
+ ### Fixed:
26
+ * documentation for private objects / methods
27
+
28
+ ### Added:
29
+ * currency helpers with tests and documentation
30
+ * day_choices
31
+ * full docs to all helper methods
32
+ * link to docs
33
+
34
+ ### Removed:
35
+ * old sinatra-helpers files
36
+
37
+ ### Changed:
38
+ * Allow descending year_choices
39
+ * change how tag works for self_closing
40
+ * Initial renamed sprint from sinatra-helpers
41
+ * Tweak documentation for Methods.rb and load order
42
+ * select option tweaks
43
+
44
+ v0.1.1
45
+ ------
46
+
47
+ ### Changed:
48
+ * some tweaks for ruby1.8.6 compat
49
+
50
+ v0.1.0
51
+ ------
52
+
53
+ Initial version.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ task(:test) {
2
+ Dir['./test/**/test_*.rb'].each { |f| load f }
3
+ }
4
+
5
+ task(:update_doc) {
6
+ system "yard && cd doc && git add . && git add -u && git commit -m . && git push"
7
+ }
@@ -0,0 +1,30 @@
1
+ # Taken from ohm
2
+
3
+ unless "".respond_to?(:lines)
4
+ # @private 1.8.6 compatibility only
5
+ class String
6
+ # @private
7
+ # This version of String#lines is almost fully compatible with that
8
+ # of Ruby 1.9. If a zero-length record separator is supplied in Ruby
9
+ # 1.9, the string is split into paragraphs delimited by multiple
10
+ # successive newlines. This replacement ignores that feature in
11
+ # favor of code simplicity.
12
+ def lines(separator = $/)
13
+ result = split(separator).map { |part| "#{part}#{separator}" }
14
+ result.each { |r| yield r } if block_given?
15
+ result
16
+ end
17
+ end
18
+ end
19
+
20
+ unless respond_to?(:tap)
21
+ # @private 1.8.6 compatibility only
22
+ class Object
23
+ # @private no need to explain. Standard ruby 1.9 stuff.
24
+ # @see http://ruby-doc.org/ruby-1.9/classes/Object.html#M000239
25
+ def tap
26
+ yield(self)
27
+ self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,300 @@
1
+ # encoding: UTF-8
2
+
3
+ # A simple module containing all countries as of 2010.
4
+ #
5
+ module Sinatra::Country
6
+ @all = {
7
+ :AF => "Afghanistan",
8
+ :AX => "Åland Islands",
9
+ :AL => "Albania",
10
+ :DZ => "Algeria",
11
+ :AS => "American Samoa",
12
+ :AD => "Andorra",
13
+ :AO => "Angola",
14
+ :AI => "Anguilla",
15
+ :AQ => "Antarctica",
16
+ :AG => "Antigua and Barbuda",
17
+ :AR => "Argentina",
18
+ :AM => "Armenia",
19
+ :AW => "Aruba",
20
+ :AU => "Australia",
21
+ :AT => "Austria",
22
+ :AZ => "Azerbaijan",
23
+ :BS => "Bahamas",
24
+ :BH => "Bahrain",
25
+ :BD => "Bangladesh",
26
+ :BB => "Barbados",
27
+ :BY => "Belarus",
28
+ :BE => "Belgium",
29
+ :BZ => "Belize",
30
+ :BJ => "Benin",
31
+ :BM => "Bermuda",
32
+ :BT => "Bhutan",
33
+ :BO => "Bolivia, Plurinational State of",
34
+ :BA => "Bosnia and Herzegovina",
35
+ :BW => "Botswana",
36
+ :BV => "Bouvet Island",
37
+ :BR => "Brazil",
38
+ :IO => "British Indian Ocean Territory",
39
+ :BN => "Brunei Darussalam",
40
+ :BG => "Bulgaria",
41
+ :BF => "Burkina Faso",
42
+ :BI => "Burundi",
43
+ :KH => "Cambodia",
44
+ :CM => "Cameroon",
45
+ :CA => "Canada",
46
+ :CV => "Cape Verde",
47
+ :KY => "Cayman Islands",
48
+ :CF => "Central African Republic",
49
+ :TD => "Chad",
50
+ :CL => "Chile",
51
+ :CN => "China",
52
+ :CX => "Christmas Island",
53
+ :CC => "Cocos (Keeling) Islands",
54
+ :CO => "Colombia",
55
+ :KM => "Comoros",
56
+ :CG => "Congo",
57
+ :CD => "Congo, the Democratic Republic of the",
58
+ :CK => "Cook Islands",
59
+ :CR => "Costa Rica",
60
+ :CI => "CÔte D'ivoire",
61
+ :HR => "Croatia",
62
+ :CU => "Cuba",
63
+ :CY => "Cyprus",
64
+ :CZ => "Czech Republic",
65
+ :DK => "Denmark",
66
+ :DJ => "Djibouti",
67
+ :DM => "Dominica",
68
+ :DO => "Dominican Republic",
69
+ :EC => "Ecuador",
70
+ :EG => "Egypt",
71
+ :SV => "El Salvador",
72
+ :GQ => "Equatorial Guinea",
73
+ :ER => "Eritrea",
74
+ :EE => "Estonia",
75
+ :ET => "Ethiopia",
76
+ :FK => "Falkland Islands (Malvinas)",
77
+ :FO => "Faroe Islands",
78
+ :FJ => "Fiji",
79
+ :FI => "Finland",
80
+ :FR => "France",
81
+ :GF => "French Guiana",
82
+ :PF => "French Polynesia",
83
+ :TF => "French Southern Territories",
84
+ :GA => "Gabon",
85
+ :GM => "Gambia",
86
+ :GE => "Georgia",
87
+ :DE => "Germany",
88
+ :GH => "Ghana",
89
+ :GI => "Gibraltar",
90
+ :GR => "Greece",
91
+ :GL => "Greenland",
92
+ :GD => "Grenada",
93
+ :GP => "Guadeloupe",
94
+ :GU => "Guam",
95
+ :GT => "Guatemala",
96
+ :GG => "Guernsey",
97
+ :GN => "Guinea",
98
+ :GW => "Guinea-bissau",
99
+ :GY => "Guyana",
100
+ :HT => "Haiti",
101
+ :HM => "Heard Island and Mcdonald Islands",
102
+ :VA => "Holy See (Vatican City State)",
103
+ :HN => "Honduras",
104
+ :HK => "Hong Kong",
105
+ :HU => "Hungary",
106
+ :IS => "Iceland",
107
+ :IN => "India",
108
+ :ID => "Indonesia",
109
+ :IR => "Iran, Islamic Republic of",
110
+ :IQ => "Iraq",
111
+ :IE => "Ireland",
112
+ :IM => "Isle of Man",
113
+ :IL => "Israel",
114
+ :IT => "Italy",
115
+ :JM => "Jamaica",
116
+ :JP => "Japan",
117
+ :JE => "Jersey",
118
+ :JO => "Jordan",
119
+ :KZ => "Kazakhstan",
120
+ :KE => "Kenya",
121
+ :KI => "Kiribati",
122
+ :KP => "Korea, Democratic People's Republic of",
123
+ :KR => "Korea, Republic of",
124
+ :KW => "Kuwait",
125
+ :KG => "Kyrgyzstan",
126
+ :LA => "Lao People's Democratic Republic",
127
+ :LV => "Latvia",
128
+ :LB => "Lebanon",
129
+ :LS => "Lesotho",
130
+ :LR => "Liberia",
131
+ :LY => "Libyan Arab Jamahiriya",
132
+ :LI => "Liechtenstein",
133
+ :LT => "Lithuania",
134
+ :LU => "Luxembourg",
135
+ :MO => "Macao",
136
+ :MK => "Macedonia, the Former Yugoslav Republic of",
137
+ :MG => "Madagascar",
138
+ :MW => "Malawi",
139
+ :MY => "Malaysia",
140
+ :MV => "Maldives",
141
+ :ML => "Mali",
142
+ :MT => "Malta",
143
+ :MH => "Marshall Islands",
144
+ :MQ => "Martinique",
145
+ :MR => "Mauritania",
146
+ :MU => "Mauritius",
147
+ :YT => "Mayotte",
148
+ :MX => "Mexico",
149
+ :FM => "Micronesia, Federated States of",
150
+ :MD => "Moldova, Republic of",
151
+ :MC => "Monaco",
152
+ :MN => "Mongolia",
153
+ :ME => "Montenegro",
154
+ :MS => "Montserrat",
155
+ :MA => "Morocco",
156
+ :MZ => "Mozambique",
157
+ :MM => "Myanmar",
158
+ :NA => "Namibia",
159
+ :NR => "Nauru",
160
+ :NP => "Nepal",
161
+ :NL => "Netherlands",
162
+ :AN => "Netherlands Antilles",
163
+ :NC => "New Caledonia",
164
+ :NZ => "New Zealand",
165
+ :NI => "Nicaragua",
166
+ :NE => "Niger",
167
+ :NG => "Nigeria",
168
+ :NU => "Niue",
169
+ :NF => "Norfolk Island",
170
+ :MP => "Northern Mariana Islands",
171
+ :NO => "Norway",
172
+ :OM => "Oman",
173
+ :PK => "Pakistan",
174
+ :PW => "Palau",
175
+ :PS => "Palestinian Territory, Occupied",
176
+ :PA => "Panama",
177
+ :PG => "Papua New Guinea",
178
+ :PY => "Paraguay",
179
+ :PE => "Peru",
180
+ :PH => "Philippines",
181
+ :PN => "Pitcairn",
182
+ :PL => "Poland",
183
+ :PT => "Portugal",
184
+ :PR => "Puerto Rico",
185
+ :QA => "Qatar",
186
+ :RE => "RÉunion",
187
+ :RO => "Romania",
188
+ :RU => "Russian Federation",
189
+ :RW => "Rwanda",
190
+ :BL => "Saint BarthÉlemy",
191
+ :SH => "Saint Helena, Ascension and Tristan Da Cunha",
192
+ :KN => "Saint Kitts and Nevis",
193
+ :LC => "Saint Lucia",
194
+ :MF => "Saint Martin",
195
+ :PM => "Saint Pierre and Miquelon",
196
+ :VC => "Saint Vincent and the Grenadines",
197
+ :WS => "Samoa",
198
+ :SM => "San Marino",
199
+ :ST => "Sao Tome and Principe",
200
+ :SA => "Saudi Arabia",
201
+ :SN => "Senegal",
202
+ :RS => "Serbia",
203
+ :SC => "Seychelles",
204
+ :SL => "Sierra Leone",
205
+ :SG => "Singapore",
206
+ :SK => "Slovakia",
207
+ :SI => "Slovenia",
208
+ :SB => "Solomon Islands",
209
+ :SO => "Somalia",
210
+ :ZA => "South Africa",
211
+ :GS => "South Georgia and the South Sandwich Islands",
212
+ :ES => "Spain",
213
+ :LK => "Sri Lanka",
214
+ :SD => "Sudan",
215
+ :SR => "Suriname",
216
+ :SJ => "Svalbard and Jan Mayen",
217
+ :SZ => "Swaziland",
218
+ :SE => "Sweden",
219
+ :CH => "Switzerland",
220
+ :SY => "Syrian Arab Republic",
221
+ :TW => "Taiwan, Province of China",
222
+ :TJ => "Tajikistan",
223
+ :TZ => "Tanzania, United Republic of",
224
+ :TH => "Thailand",
225
+ :TL => "Timor-leste",
226
+ :TG => "Togo",
227
+ :TK => "Tokelau",
228
+ :TO => "Tonga",
229
+ :TT => "Trinidad and Tobago",
230
+ :TN => "Tunisia",
231
+ :TR => "Turkey",
232
+ :TM => "Turkmenistan",
233
+ :TC => "Turks and Caicos Islands",
234
+ :TV => "Tuvalu",
235
+ :UG => "Uganda",
236
+ :UA => "Ukraine",
237
+ :AE => "United Arab Emirates",
238
+ :GB => "United Kingdom",
239
+ :US => "United States",
240
+ :UM => "United States Minor Outlying Islands",
241
+ :UY => "Uruguay",
242
+ :UZ => "Uzbekistan",
243
+ :VU => "Vanuatu",
244
+ :VA => "Vatican City State",
245
+ :VE => "Venezuela, Bolivarian Republic of",
246
+ :VN => "Viet Nam",
247
+ :VG => "Virgin Islands, British",
248
+ :VI => "Virgin Islands, U.S.",
249
+ :WF => "Wallis and Futuna",
250
+ :EH => "Western Sahara",
251
+ :YE => "Yemen",
252
+ :ZM => "Zambia",
253
+ :ZW => "Zimbabwe"
254
+ }
255
+
256
+ # @example
257
+ #
258
+ # p Country.to_select
259
+ # [["Afghanistan", "AF"], ["Åland Islands", "AX"], ["Albania", "AL"],
260
+ # ["Algeria", "DZ"], ["American Samoa", "AS"], ... ["Zimbabwe", "ZW"]]
261
+ #
262
+ # @return [Array] a collection of pairs with the first element being
263
+ # country name and the last element being the code.
264
+ #
265
+ # @see Sinatra#country_choices
266
+ def to_select
267
+ all.map { |code, name| [name, code.to_s] }
268
+ end
269
+
270
+ # Retrieves the country name given a country code.
271
+ # @example
272
+ #
273
+ # Sinatra::Country["US"] == "United States"
274
+ # # => true
275
+ #
276
+ # Sinatra::Country[:US] == "United States"
277
+ # # => true
278
+ #
279
+ # @param [#to_sym] code The country code in 2 letter all caps format.
280
+ # @return [String] The corresponding country name given the code.
281
+ # @return [nil] nil if no matching country code.
282
+ def [](code)
283
+ all[code.to_sym] if not code.to_s.empty?
284
+ end
285
+
286
+ # For use with seeding dummy data.
287
+ # @return [Symbol] a randomized country code.
288
+ def random
289
+ all.keys.shuffle.first
290
+ end
291
+
292
+ # Gives all countries in a Hash.
293
+ #
294
+ # @return [Hash] the code => name pairs of all countries.
295
+ def all
296
+ @all
297
+ end
298
+
299
+ module_function :all, :to_select, :[], :random
300
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../country', __FILE__)
2
+
3
+ # Country helpers.
4
+ #
5
+ # require 'sinatra/support/countryhelpers'
6
+ # require 'sinatra/support/htmlhelpers'
7
+ #
8
+ # class Main < Sinatra::Base
9
+ # helpers Sinatra::HtmlHelpers
10
+ # helpers Sinatra::CountryHelpers
11
+ # end
12
+ #
13
+ # == Helpers
14
+ #
15
+ # Provides the following helpers:
16
+ #
17
+ # === {#country_choices country_choices} - Country choices for select_options.
18
+ #
19
+ # <!-- A dropdown box of countries. -->
20
+ # <select name="country">
21
+ # <%= select_options country_choices %>
22
+ # </select>
23
+ #
24
+ module Sinatra::CountryHelpers
25
+ def country_choices
26
+ Sinatra::Country.to_select
27
+ end
28
+ end
@@ -0,0 +1,58 @@
1
+ # Support for Sass/SCSS/Less.
2
+ #
3
+ # == Usage
4
+ #
5
+ # require 'sinatra/support/csssupport'
6
+ #
7
+ # Use {#serve_css} in the Sinatra DSL to serve up files.
8
+ #
9
+ # register Sinatra::CssSupport
10
+ # serve_css '/styles', from: './app/css'
11
+ #
12
+ # Assuming you have a +app/css/print.scss+ file, you will
13
+ # then be able to access it from the given URL prefix.
14
+ #
15
+ # $ curl "http://localhost:4567/styles/print.css"
16
+ #
17
+ # This plugin supports Sass, Less and SCSS and guesses by the
18
+ # file name.
19
+ #
20
+ # == Caveats
21
+ #
22
+ # Note that you will need to set your Sass/SCSS +load_path+ settings.
23
+ #
24
+ # Main.configure do |m|
25
+ # m.set :scss, {
26
+ # :load_paths => [ 'app/css' ]
27
+ # }
28
+ # m.set :scss, self.scss.merge(:style => :compressed) if m.production?
29
+ # end
30
+ #
31
+ module Sinatra::CssSupport
32
+ def self.registered(app)
33
+ app.set :css_max_age, app.development? ? 0 : 86400*30
34
+ end
35
+
36
+ def serve_css(url_prefix, options={})
37
+ path = File.join(url_prefix, '*.css')
38
+ prefix = options[:from]
39
+
40
+ get path do |name|
41
+ fname = Dir[File.join(prefix, "#{name}.{css,scss,less}")].first or pass
42
+
43
+ content_type :css, :charset => 'utf-8'
44
+ last_modified File.mtime(fname)
45
+ cache_control :public, :must_revalidate, :max_age => settings.css_max_age
46
+
47
+ if fname =~ /\.scss$/
48
+ scss File.read(fname)
49
+ elsif fname =~ /\.scss$/
50
+ sass File.read(fname)
51
+ elsif fname =~ /\.less$/
52
+ less File.read(fname)
53
+ else
54
+ send_file fname
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,145 @@
1
+ require File.expand_path('../compat-1.8.6.rb', __FILE__)
2
+
3
+ # Date helpers.
4
+ #
5
+ # require 'sinatra/support/dateforms'
6
+ #
7
+ # class Main < Sinatra::Base
8
+ # register Sinatra::DateForms
9
+ # end
10
+ #
11
+ # == Helpers
12
+ #
13
+ # This plugin provides the following helpers:
14
+ #
15
+ # === {Helpers#month_choices month_choices} - Provides month choices for dropdowns.
16
+ #
17
+ # <select name="birthday[month]">
18
+ # <%= month_choices %>
19
+ # </select>
20
+ #
21
+ # === {Helpers#day_choices day_choices} - Day choices.
22
+ #
23
+ # <select name="birthday[day]">
24
+ # <%= day_choices %>
25
+ # </select>
26
+ #
27
+ # === {Helpers#year_choices year_choices} - Year dropdown.
28
+ #
29
+ # <select name="birthday[year]">
30
+ # <%= year_choices %>
31
+ # </select>
32
+ #
33
+ # == Settings
34
+ #
35
+ # Provides the following settings in your application:
36
+ #
37
+ # [+default_year_loffset+] (Numeric) How many years back to display.
38
+ # Defaults to +-60+.
39
+ # [+default_year_loffset+] (Numeric) How many years forward. Defaults
40
+ # to +0+.
41
+ # [+default_month_names+] (Array) The names of the months. Defaults
42
+ # To +Date::MONTHNAMES+.
43
+ #
44
+ # You may change them like this:
45
+ #
46
+ # Main.configure do |m|
47
+ # m.set :default_year_loffset, -60
48
+ # m.set :default_year_uoffset, 0
49
+ # m.set :default_month_names, Date::MONTHNAMES
50
+ # end
51
+ #
52
+ module Sinatra::DateForms
53
+ def self.registered(app)
54
+ app.set :default_year_loffset, -60
55
+ app.set :default_year_uoffset, 0
56
+ app.set :default_month_names, Date::MONTHNAMES
57
+
58
+ app.helpers Helpers
59
+ end
60
+
61
+ module Helpers
62
+ # Returns an array of date pairs. Best used with
63
+ # {Sinatra::HtmlHelpers#select_options}.
64
+ #
65
+ # @return [Array] the array of day, day pairs.
66
+ #
67
+ # @example This is perfect for @select_options@.
68
+ #
69
+ # <select name="date">
70
+ # <%= select_options day_choices %>
71
+ #
72
+ # An example output looks like:
73
+ #
74
+ # - [1, 1]
75
+ # - [2, 2]
76
+ # - ...
77
+ # - [31, 31]
78
+ #
79
+ def day_choices(max=31)
80
+ days = (1..max).to_a
81
+ days.zip(days)
82
+ end
83
+
84
+ # Returns an array of pairs.
85
+ #
86
+ # You may pass in @Date::ABBR_MONTHNAMES@ if you want the shortened month
87
+ # names.
88
+ #
89
+ # @example output
90
+ #
91
+ # - ['January', 1]
92
+ # - ['February', 2]
93
+ # - ...
94
+ # - ['December', 12]
95
+ #
96
+ # @param [Array] month_names (defaults to Date::MONTHNAMES) an array with the
97
+ # first element being nil, element 1 being January, etc.
98
+ # @return [Array] the array of month name, month pairs.
99
+ def month_choices(month_names = settings.default_month_names)
100
+ month_names.map.
101
+ with_index { |month, idx| [month, idx] }.
102
+ tap { |arr| arr.shift }
103
+ end
104
+
105
+ # Returns an array of pairs.
106
+ #
107
+ # @example Output
108
+ #
109
+ # - [2005, 2005]
110
+ # - [2006, 2006]
111
+ # - ...
112
+ # - [2010, 2010]
113
+ #
114
+ # @example
115
+ #
116
+ # year_choices # assuming it's now 2010
117
+ # # => [[1950, 1950], ..., [2010, 2010]]
118
+ #
119
+ # # we can pass in options
120
+ # year_choices(0, 6) # like for credit card options
121
+ # # => [[2010, 2010], ..., [2016, 2016]]
122
+ #
123
+ # # also we can override settings at the app level
124
+ # set :default_year_loffset, 0
125
+ # set :default_year_uoffset, 6
126
+ # year_choices
127
+ # # => [[2010, 2010], ..., [2016, 2016]]
128
+ #
129
+ # @param [Fixnum] loffset (defaults to -60) The lower offset relative to the current year.
130
+ # If it's 2010 now, passing in -5 here will start the year
131
+ # list at 2005 for example.
132
+ # @param [Fixnum] uoffset (defaults to 0) The upper offset relative to the
133
+ # current year. If it's 2010 now, passing in 5 or +5 here
134
+ # will end the year list at 2015 for example.
135
+ # @return [Array] the array of year, year pairs.
136
+ #
137
+ def year_choices(loffset = settings.default_year_loffset, uoffset = settings.default_year_uoffset)
138
+ start = loffset + Date.today.year
139
+ finish = uoffset + Date.today.year
140
+
141
+ enum = start < finish ? start.upto(finish) : start.downto(finish)
142
+ enum.map { |e| [e, e] }
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,62 @@
1
+ # Ohm error helpers.
2
+ #
3
+ # == Usage
4
+ #
5
+ # # Only for those who use Ohm and HAML
6
+ # require 'ohm'
7
+ # require 'haml'
8
+ #
9
+ # require 'sinatra/support/ohmerrorhelpers'
10
+ #
11
+ # class Main < Sinatra::Base
12
+ # helpers Sinatra::OhmErrorHelpers
13
+ # end
14
+ #
15
+ # == Common usage
16
+ #
17
+ # - errors_on @user do |e|
18
+ # - e.on [:email, :not_present], "We need your email address."
19
+ # - e.on [:password, :not_present], "You must specify a password."
20
+ #
21
+ # # produces the following:
22
+ # # <div class="errors">
23
+ # # <ul>
24
+ # # <li>We need your email address</li>
25
+ # # <li>You must specify a password.</li>
26
+ # # </ul>
27
+ # # </div>
28
+ #
29
+ module Sinatra::OhmErrorHelpers
30
+ # Presents errors on your form. Takes the explicit approach and assumes
31
+ # that for every form you have, the copy for the errors are important,
32
+ # instead of producing canned responses.
33
+ #
34
+ # @param [#errors] object An object responding to #errors. This validation
35
+ # also checks for the presence of a #full_messages method
36
+ # in the errors object for compatibility with
37
+ # ActiveRecord style objects.
38
+ # @param [Hash] options a hash of HTML attributes to place on the
39
+ # containing div.
40
+ # @option options [#to_s] :class (defaults to errors) The css class to put
41
+ # in the div.
42
+ #
43
+ # @yield [Sinatra::Support::HamlErrorPresenter] an object responding to #on.
44
+ #
45
+ def errors_on(object, options = { :class => 'errors' }, &block)
46
+ return if object.errors.empty?
47
+
48
+ lines = if object.errors.respond_to?(:full_messages)
49
+ object.errors.full_messages
50
+ else
51
+ HamlErrorPresenter.new(object.errors).present(self, &block)
52
+ end
53
+
54
+ haml_tag(:div, options) do
55
+ haml_tag(:ul) do
56
+ lines.each do |error|
57
+ haml_tag(:li, error)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end