merb-helpers 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/LICENSE +20 -0
  2. data/README +180 -0
  3. data/Rakefile +77 -0
  4. data/TODO +5 -0
  5. data/lib/merb-helpers.rb +38 -0
  6. data/lib/merb-helpers/core_ext.rb +57 -0
  7. data/lib/merb-helpers/core_ext/numeric.rb +388 -0
  8. data/lib/merb-helpers/date_time_formatting.rb +127 -0
  9. data/lib/merb-helpers/date_time_helpers.rb +190 -0
  10. data/lib/merb-helpers/form/builder.rb +410 -0
  11. data/lib/merb-helpers/form/helpers.rb +448 -0
  12. data/lib/merb-helpers/form_helpers.rb +24 -0
  13. data/lib/merb-helpers/tag_helpers.rb +61 -0
  14. data/lib/merb-helpers/text_helpers.rb +61 -0
  15. data/lib/merb-helpers/time_dsl.rb +59 -0
  16. data/spec/core_ext_spec.rb +19 -0
  17. data/spec/fixture/app/controllers/application.rb +4 -0
  18. data/spec/fixture/app/controllers/bound_check_box.rb +2 -0
  19. data/spec/fixture/app/controllers/bound_file_field.rb +2 -0
  20. data/spec/fixture/app/controllers/bound_hidden_field.rb +2 -0
  21. data/spec/fixture/app/controllers/bound_option_tag.rb +2 -0
  22. data/spec/fixture/app/controllers/bound_password_field.rb +2 -0
  23. data/spec/fixture/app/controllers/bound_radio_button.rb +2 -0
  24. data/spec/fixture/app/controllers/bound_radio_group.rb +2 -0
  25. data/spec/fixture/app/controllers/bound_select.rb +2 -0
  26. data/spec/fixture/app/controllers/bound_text_area.rb +2 -0
  27. data/spec/fixture/app/controllers/bound_text_field.rb +2 -0
  28. data/spec/fixture/app/controllers/button.rb +2 -0
  29. data/spec/fixture/app/controllers/check_box.rb +2 -0
  30. data/spec/fixture/app/controllers/custom_builder.rb +2 -0
  31. data/spec/fixture/app/controllers/delete_button.rb +2 -0
  32. data/spec/fixture/app/controllers/exceptions.rb +25 -0
  33. data/spec/fixture/app/controllers/field_set.rb +2 -0
  34. data/spec/fixture/app/controllers/fields_for.rb +3 -0
  35. data/spec/fixture/app/controllers/file_field.rb +2 -0
  36. data/spec/fixture/app/controllers/foo.rb +23 -0
  37. data/spec/fixture/app/controllers/form.rb +2 -0
  38. data/spec/fixture/app/controllers/form_for.rb +2 -0
  39. data/spec/fixture/app/controllers/hidden_field.rb +2 -0
  40. data/spec/fixture/app/controllers/label.rb +3 -0
  41. data/spec/fixture/app/controllers/numeric_ext.rb +3 -0
  42. data/spec/fixture/app/controllers/option_tag.rb +2 -0
  43. data/spec/fixture/app/controllers/password_field.rb +2 -0
  44. data/spec/fixture/app/controllers/radio_button.rb +2 -0
  45. data/spec/fixture/app/controllers/radio_group.rb +2 -0
  46. data/spec/fixture/app/controllers/select.rb +2 -0
  47. data/spec/fixture/app/controllers/specs_controller.rb +11 -0
  48. data/spec/fixture/app/controllers/submit.rb +2 -0
  49. data/spec/fixture/app/controllers/tag_helper.rb +21 -0
  50. data/spec/fixture/app/controllers/text_area.rb +2 -0
  51. data/spec/fixture/app/controllers/text_field.rb +3 -0
  52. data/spec/fixture/app/helpers/global_helpers.rb +8 -0
  53. data/spec/fixture/app/models/fake_dm_model.rb +25 -0
  54. data/spec/fixture/app/models/first_generic_fake_model.rb +57 -0
  55. data/spec/fixture/app/models/second_generic_fake_model.rb +18 -0
  56. data/spec/fixture/app/models/third_generic_fake_model.rb +3 -0
  57. data/spec/fixture/app/views/bound_check_box_specs/basic.html.erb +4 -0
  58. data/spec/fixture/app/views/bound_check_box_specs/checked.html.erb +4 -0
  59. data/spec/fixture/app/views/bound_check_box_specs/errors.html.erb +4 -0
  60. data/spec/fixture/app/views/bound_check_box_specs/label.html.erb +3 -0
  61. data/spec/fixture/app/views/bound_check_box_specs/on_and_off.html.erb +3 -0
  62. data/spec/fixture/app/views/bound_check_box_specs/raise_value_error.html.erb +3 -0
  63. data/spec/fixture/app/views/bound_file_field_specs/additional_attributes.html.erb +3 -0
  64. data/spec/fixture/app/views/bound_file_field_specs/takes_string.html.erb +3 -0
  65. data/spec/fixture/app/views/bound_file_field_specs/with_label.html.erb +3 -0
  66. data/spec/fixture/app/views/bound_hidden_field_specs/basic.html.erb +3 -0
  67. data/spec/fixture/app/views/bound_hidden_field_specs/errors.html.erb +3 -0
  68. data/spec/fixture/app/views/bound_hidden_field_specs/hidden_error.html.erb +3 -0
  69. data/spec/fixture/app/views/bound_hidden_field_specs/label.html.erb +3 -0
  70. data/spec/fixture/app/views/bound_option_tag_specs/grouped.html.erb +3 -0
  71. data/spec/fixture/app/views/bound_option_tag_specs/nested.html.erb +3 -0
  72. data/spec/fixture/app/views/bound_option_tag_specs/text_and_value.html.erb +4 -0
  73. data/spec/fixture/app/views/bound_password_field_specs/attributes.html.erb +3 -0
  74. data/spec/fixture/app/views/bound_password_field_specs/basic.html.erb +3 -0
  75. data/spec/fixture/app/views/bound_password_field_specs/label.html.erb +3 -0
  76. data/spec/fixture/app/views/bound_radio_button_specs/basic.html.erb +3 -0
  77. data/spec/fixture/app/views/bound_radio_group_specs/basic.html.erb +3 -0
  78. data/spec/fixture/app/views/bound_radio_group_specs/hashes.html.erb +3 -0
  79. data/spec/fixture/app/views/bound_radio_group_specs/mixed.html.erb +4 -0
  80. data/spec/fixture/app/views/bound_radio_group_specs/override_id.html.erb +3 -0
  81. data/spec/fixture/app/views/bound_select_specs/basic.html.erb +3 -0
  82. data/spec/fixture/app/views/bound_select_specs/blank.html.erb +3 -0
  83. data/spec/fixture/app/views/bound_select_specs/multiple.html.erb +3 -0
  84. data/spec/fixture/app/views/bound_select_specs/prompt.html.erb +3 -0
  85. data/spec/fixture/app/views/bound_select_specs/with_options.html.erb +3 -0
  86. data/spec/fixture/app/views/bound_select_specs/with_options_with_blank.html.erb +3 -0
  87. data/spec/fixture/app/views/bound_text_area_specs/basic.html.erb +3 -0
  88. data/spec/fixture/app/views/bound_text_field_specs/basic.html.erb +3 -0
  89. data/spec/fixture/app/views/button_specs/button_with_label.html.erb +1 -0
  90. data/spec/fixture/app/views/button_specs/button_with_values.html.erb +1 -0
  91. data/spec/fixture/app/views/button_specs/disabled_button.html.erb +1 -0
  92. data/spec/fixture/app/views/check_box_specs/basic.html.erb +1 -0
  93. data/spec/fixture/app/views/check_box_specs/boolean.html.erb +1 -0
  94. data/spec/fixture/app/views/check_box_specs/disabled.html.erb +1 -0
  95. data/spec/fixture/app/views/check_box_specs/label.html.erb +1 -0
  96. data/spec/fixture/app/views/check_box_specs/on_off_is_boolean.html.erb +1 -0
  97. data/spec/fixture/app/views/check_box_specs/raise_unless_both_on_and_off.html.erb +2 -0
  98. data/spec/fixture/app/views/check_box_specs/raises_error_if_not_boolean.html.erb +1 -0
  99. data/spec/fixture/app/views/check_box_specs/raises_error_if_on_off_and_boolean_false.html.erb +1 -0
  100. data/spec/fixture/app/views/check_box_specs/simple.html.erb +1 -0
  101. data/spec/fixture/app/views/check_box_specs/to_string.html.erb +8 -0
  102. data/spec/fixture/app/views/check_box_specs/unchecked.html.erb +2 -0
  103. data/spec/fixture/app/views/custom_builder_specs/everything.html.erb +10 -0
  104. data/spec/fixture/app/views/delete_button_specs/delete_with_explicit_url.html.erb +1 -0
  105. data/spec/fixture/app/views/delete_button_specs/delete_with_extra_params.html.erb +1 -0
  106. data/spec/fixture/app/views/delete_button_specs/delete_with_label.html.erb +1 -0
  107. data/spec/fixture/app/views/delete_button_specs/simple_delete.html.erb +1 -0
  108. data/spec/fixture/app/views/exeptions/client_error.html.erb +37 -0
  109. data/spec/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
  110. data/spec/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
  111. data/spec/fixture/app/views/exeptions/not_found.html.erb +40 -0
  112. data/spec/fixture/app/views/fields_for_specs/basic.html.erb +3 -0
  113. data/spec/fixture/app/views/fields_for_specs/midstream.html.erb +7 -0
  114. data/spec/fixture/app/views/fields_for_specs/nil.html.erb +3 -0
  115. data/spec/fixture/app/views/fieldset_specs/legend.html.erb +3 -0
  116. data/spec/fixture/app/views/file_field_specs/disabled.html.erb +1 -0
  117. data/spec/fixture/app/views/file_field_specs/makes_multipart.html.erb +3 -0
  118. data/spec/fixture/app/views/file_field_specs/with_label.html.erb +1 -0
  119. data/spec/fixture/app/views/file_field_specs/with_values.html.erb +1 -0
  120. data/spec/fixture/app/views/foo/bar.html.erb +0 -0
  121. data/spec/fixture/app/views/form_for_specs/basic.html.erb +3 -0
  122. data/spec/fixture/app/views/form_specs/create_a_form.html.erb +3 -0
  123. data/spec/fixture/app/views/form_specs/create_a_multipart_form.html.erb +3 -0
  124. data/spec/fixture/app/views/form_specs/fake_delete_if_set.html.erb +3 -0
  125. data/spec/fixture/app/views/form_specs/fake_put_if_set.html.erb +3 -0
  126. data/spec/fixture/app/views/form_specs/get_if_set.html.erb +3 -0
  127. data/spec/fixture/app/views/form_specs/post_by_default.html.erb +3 -0
  128. data/spec/fixture/app/views/form_specs/resourceful_form.html.erb +3 -0
  129. data/spec/fixture/app/views/hidden_field_specs/basic.html.erb +1 -0
  130. data/spec/fixture/app/views/hidden_field_specs/disabled.html.erb +1 -0
  131. data/spec/fixture/app/views/hidden_field_specs/label.html.erb +1 -0
  132. data/spec/fixture/app/views/label_specs/basic.html.erb +1 -0
  133. data/spec/fixture/app/views/layout/application.html.erb +11 -0
  134. data/spec/fixture/app/views/numeric_ext_specs/minutes_to_hours.html.erb +1 -0
  135. data/spec/fixture/app/views/numeric_ext_specs/to_concurrency_default.html.erb +1 -0
  136. data/spec/fixture/app/views/numeric_ext_specs/two_digits.html.erb +1 -0
  137. data/spec/fixture/app/views/option_tag_specs/array.html.erb +1 -0
  138. data/spec/fixture/app/views/option_tag_specs/clean.html.erb +1 -0
  139. data/spec/fixture/app/views/option_tag_specs/collection.html.erb +1 -0
  140. data/spec/fixture/app/views/option_tag_specs/multiple_selects.html.erb +1 -0
  141. data/spec/fixture/app/views/option_tag_specs/no_extra_attributes.html.erb +1 -0
  142. data/spec/fixture/app/views/option_tag_specs/optgroups.html.erb +1 -0
  143. data/spec/fixture/app/views/option_tag_specs/selected.html.erb +1 -0
  144. data/spec/fixture/app/views/option_tag_specs/with_blank.html.erb +1 -0
  145. data/spec/fixture/app/views/option_tag_specs/with_prompt.html.erb +1 -0
  146. data/spec/fixture/app/views/password_field_specs/basic.html.erb +1 -0
  147. data/spec/fixture/app/views/password_field_specs/disabled.html.erb +1 -0
  148. data/spec/fixture/app/views/radio_button_specs/basic.html.erb +1 -0
  149. data/spec/fixture/app/views/radio_button_specs/disabled.html.erb +1 -0
  150. data/spec/fixture/app/views/radio_button_specs/label.html.erb +1 -0
  151. data/spec/fixture/app/views/radio_group_specs/attributes.html.erb +1 -0
  152. data/spec/fixture/app/views/radio_group_specs/basic.html.erb +1 -0
  153. data/spec/fixture/app/views/radio_group_specs/hash.html.erb +1 -0
  154. data/spec/fixture/app/views/radio_group_specs/specific_attributes.html.erb +1 -0
  155. data/spec/fixture/app/views/select_specs/blank.html.erb +1 -0
  156. data/spec/fixture/app/views/select_specs/multiple.html.erb +1 -0
  157. data/spec/fixture/app/views/submit_specs/disabled_submit.html.erb +1 -0
  158. data/spec/fixture/app/views/submit_specs/submit_with_label.html.erb +1 -0
  159. data/spec/fixture/app/views/submit_specs/submit_with_values.html.erb +1 -0
  160. data/spec/fixture/app/views/tag_helper/nested_tags.html.erb +5 -0
  161. data/spec/fixture/app/views/tag_helper/tag_with_attributes.html.erb +1 -0
  162. data/spec/fixture/app/views/tag_helper/tag_with_content.html.erb +1 -0
  163. data/spec/fixture/app/views/tag_helper/tag_with_content_in_the_block.html.erb +3 -0
  164. data/spec/fixture/app/views/text_area_specs/basic.html.erb +1 -0
  165. data/spec/fixture/app/views/text_area_specs/disabled.html.erb +1 -0
  166. data/spec/fixture/app/views/text_area_specs/label.html.erb +1 -0
  167. data/spec/fixture/app/views/text_area_specs/nil.html.erb +1 -0
  168. data/spec/fixture/app/views/text_field_specs/basic.html.erb +1 -0
  169. data/spec/fixture/app/views/text_field_specs/class.html.erb +1 -0
  170. data/spec/fixture/app/views/text_field_specs/disabled.html.erb +1 -0
  171. data/spec/fixture/app/views/text_field_specs/label.html.erb +1 -0
  172. data/spec/fixture/config/environments/development.rb +6 -0
  173. data/spec/fixture/config/environments/production.rb +5 -0
  174. data/spec/fixture/config/environments/test.rb +6 -0
  175. data/spec/fixture/config/init.rb +46 -0
  176. data/spec/fixture/config/rack.rb +11 -0
  177. data/spec/fixture/config/router.rb +36 -0
  178. data/spec/fixture/log/merb.main.pid +1 -0
  179. data/spec/fixture/log/merb_test.log +624 -0
  180. data/spec/fixture/public/images/merb.jpg +0 -0
  181. data/spec/fixture/public/merb.fcgi +4 -0
  182. data/spec/fixture/public/stylesheets/master.css +119 -0
  183. data/spec/merb_helpers_config_spec.rb +82 -0
  184. data/spec/merb_helpers_date_time_spec.rb +257 -0
  185. data/spec/merb_helpers_form_spec.rb +1266 -0
  186. data/spec/merb_helpers_tag_helper_spec.rb +46 -0
  187. data/spec/merb_helpers_text_spec.rb +67 -0
  188. data/spec/numeric_extlib_spec.rb +135 -0
  189. data/spec/ordinalize_spec.rb +51 -0
  190. data/spec/spec_helper.rb +149 -0
  191. data/spec/time_dsl_spec.rb +43 -0
  192. metadata +303 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 YOUR NAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,180 @@
1
+ merb-helpers
2
+ =================
3
+
4
+ A plugin for the Merb Web framework that provides different view helpers.
5
+
6
+ To use this plugin in merb in your app
7
+
8
+ config/dependencies.rb
9
+
10
+ #...
11
+
12
+ dependency "merb-helpers"
13
+
14
+ #...
15
+
16
+ # TODO: describe date_time_helpers, form_helpers, tag_helpers
17
+
18
+
19
+ form_helpers
20
+ ------------
21
+
22
+ * +delete_button+. If you want to delete an object, you should call the delete method on the object's controller.
23
+ You should not use a simple link to your action, instead you should make a DELETE request.
24
+ To help you doing that, you can use the delete_button method as follows:
25
+
26
+ <%= delete_button(@comment) %>
27
+
28
+ The delete_button helper has many options, first thing, you can pass an object or an url:
29
+
30
+ <%= delete_button(url(:comment, @comment)) %>
31
+
32
+ This helper creates a form with a submit button.
33
+ You can pass many arguments to the delete_button helper. The first thing you might want to do is to change the
34
+ default button text.
35
+
36
+ <%= delete_button(@comment), "Remove this comment by #{@comment.author.name}" %>
37
+
38
+ You can also pass the usual helper params to specify a class to use for instance:
39
+
40
+ <%= delete_button(@comment, nil, :class => 'custom-class') %>
41
+
42
+ See usage in specs: spec/fixture/app/views/delete_button_specs
43
+
44
+ numeric helpers
45
+ ---------------
46
+
47
+ Numeric helpers extend numeric instances, in lay terms: numbers.
48
+
49
+ * +minutes_to_hours+ converts a +numeric+ value representing minutes into a string representing an hour value
50
+
51
+ 315.minutes_to_hours # => "05:15"
52
+
53
+ * +two_digits+ formats a +number+ into a two digit string. Basically it prepends an integer to a 2 digits string.
54
+
55
+ 3.two_digits # => "03"
56
+
57
+ * +with_delimiter+, this method formats a number with grouped thousands
58
+
59
+ 12345678.with_delimiter # => "12,345,678"
60
+
61
+
62
+ * +with_precison+, this method formats a number with a level of precision
63
+
64
+ 111.2345.with_precision # => "111.235"
65
+
66
+ * +to_currency, this method formats a number into a currency value using a delimited and a set precision
67
+
68
+ 1234567890.506.to_currency # => "$1,234,567,890.51"
69
+
70
+ (For usage example look at spec/numeric_exlib.rb)
71
+
72
+
73
+ Overwriting the default formating options:
74
+
75
+ One can overwrite the default settings by passing the name or of the format used and a hash representing the settings to overwrite.
76
+
77
+ Each method mentioned above has some format settings you can overwrite:
78
+
79
+ * +with_delimiter+
80
+ * :delimiter - Overwrites the thousands delimiter.
81
+ * :separator - Overwrites the separator between the units.
82
+
83
+ * +with_precision+
84
+ * :precision - Overwrites the level of precision
85
+ * :separator - Overwrites the separator between the units
86
+ * :delimiter - Overwrites the thousands delimiter
87
+
88
+ * +with_currency+
89
+ * :precision - Sets the level of precision
90
+ * :unit - Sets the denomination of the currency
91
+ * :format - Sets the format of the output string (defaults to "%u%n"). The field types are:
92
+ * %u The currency unit
93
+ * %n The number
94
+
95
+ Usage example:
96
+
97
+ 1234567890.506.to_currency(:default, :unit => '£') # => "£1,234,567,890.51"
98
+
99
+ merb_helpers comes with a very limited set of formats you can use, here is an example:
100
+
101
+ 1234567890.50.to_currency(:uk) # => "&pound;1,234,567,890.50"
102
+
103
+ Formats are just a hash of settings used by the plugin, here is the default format:
104
+
105
+ :us => {
106
+ :number => {
107
+ :precision => 3,
108
+ :delimiter => ',',
109
+ :separator => '.'
110
+ },
111
+ :currency => {
112
+ :unit => '$',
113
+ :format => '%u%n',
114
+ :precision => 2
115
+ }
116
+ }
117
+
118
+ If you wish to add a new format you can easily do that as follows:
119
+
120
+ custom_format_to_add = { :custom_name => {
121
+ :number => {
122
+ :precision => 3,
123
+ :delimiter => ',',
124
+ :separator => '.'
125
+ },
126
+ :currency => {
127
+ :unit => 'Merbollars',
128
+ :format => '%n %u',
129
+ :precision => 2
130
+ }
131
+ }
132
+ }
133
+
134
+ Numeric::Transformer.add_format(custom_format_to_add)
135
+
136
+ You can then call the format like that:
137
+
138
+ 1234567890.to_currency(:custom_name) # => "1,234,567,890.00 Merbollars"
139
+
140
+ After adding a custom format, you can set it as the default format:
141
+
142
+ Numeric::Transformer.change_default_format(:custom_name)
143
+
144
+ You can set this things up in your before/after app load block in the config/init.rb file.
145
+
146
+
147
+ Formating a Date or Time instance
148
+ ---------------
149
+
150
+ Usage examples: spec/merb_helpers_date_time_spec.rb
151
+
152
+ Time.now.formatted(:db) # => "2008-09-21 02:07:31"
153
+ Time.now.formatted(:long) # => "September 21, 2008 02:08"
154
+
155
+ You can also add your own format:
156
+
157
+ Date.add_format(:matt, "%H:%M:%S %Y-%m-%d")
158
+
159
+ And use is as a default format:
160
+
161
+ Time.now.formatted(:matt) # => "02:09:18 2008-09-21"
162
+
163
+
164
+
165
+ Representation of time difference
166
+ -------------------
167
+
168
+ Usage examples: spec/merb_helpers_date_time_spec.rb
169
+
170
+ * Relative time:
171
+
172
+ Let's imagine that we are the June 1st 2007 at 11am UTC
173
+
174
+
175
+ relative_date(Time.now.utc) # => "today"
176
+ relative_date(1.day.ago.utc) # => 'yesterday'
177
+ relative_date(1.day.from_now.utc) # => 'tomorrow'
178
+ relative_date(Time.utc(2005, 11, 15)) # => 'Nov 15th, 2005' (date with the year since it's not this year)
179
+ relative_date(Time.utc(2007, 11, 15)) # => 'Nov 15th' (date without the year this the passed date is this year)
180
+
@@ -0,0 +1,77 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require "extlib"
4
+ require 'merb-core/tasks/merb_rake_helper'
5
+ require "spec/rake/spectask"
6
+
7
+ ##############################################################################
8
+ # Package && release
9
+ ##############################################################################
10
+ RUBY_FORGE_PROJECT = "merb"
11
+ PROJECT_URL = "http://merbivore.com"
12
+ PROJECT_SUMMARY = "Helper support for Merb"
13
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY
14
+
15
+ GEM_AUTHOR = "Michael D. Ivey"
16
+ GEM_EMAIL = "ivey@gweezlebur.com"
17
+
18
+ GEM_NAME = "merb-helpers"
19
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
20
+ GEM_VERSION = (Merb::MORE_VERSION rescue "0.9.8") + PKG_BUILD
21
+
22
+ RELEASE_NAME = "REL #{GEM_VERSION}"
23
+
24
+ require "extlib/tasks/release"
25
+
26
+ spec = Gem::Specification.new do |s|
27
+ s.rubyforge_project = RUBY_FORGE_PROJECT
28
+ s.name = GEM_NAME
29
+ s.version = GEM_VERSION
30
+ s.platform = Gem::Platform::RUBY
31
+ s.has_rdoc = true
32
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
33
+ s.summary = PROJECT_SUMMARY
34
+ s.description = PROJECT_DESCRIPTION
35
+ s.author = GEM_AUTHOR
36
+ s.email = GEM_EMAIL
37
+ s.homepage = PROJECT_URL
38
+ s.add_dependency('merb-core', '>= 0.9.8')
39
+ s.require_path = 'lib'
40
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
41
+ end
42
+
43
+ Rake::GemPackageTask.new(spec) do |pkg|
44
+ pkg.gem_spec = spec
45
+ end
46
+
47
+ desc "Install the gem"
48
+ task :install do
49
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
50
+ end
51
+
52
+ desc "Uninstall the gem"
53
+ task :uninstall do
54
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
55
+ end
56
+
57
+ desc "Create a gemspec file"
58
+ task :gemspec do
59
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
60
+ file.puts spec.to_ruby
61
+ end
62
+ end
63
+
64
+ desc "Run all examples (or a specific spec with TASK=xxxx)"
65
+ Spec::Rake::SpecTask.new('spec') do |t|
66
+ t.spec_opts = ["-cfs"]
67
+ t.spec_files = begin
68
+ if ENV["TASK"]
69
+ ENV["TASK"].split(',').map { |task| "spec/**/#{task}_spec.rb" }
70
+ else
71
+ FileList['spec/**/*_spec.rb']
72
+ end
73
+ end
74
+ end
75
+
76
+ desc 'Default: run spec examples'
77
+ task :default => 'spec'
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/merb-haml.rb
5
+ Add your Merb rake tasks to lib/merb-haml/merbtasks.rb
@@ -0,0 +1,38 @@
1
+ module Merb
2
+
3
+ module Helpers
4
+
5
+ @@helpers_dir = File.dirname(__FILE__) / 'merb-helpers'
6
+ @@helpers_files = Dir["#{@@helpers_dir}/*_helpers.rb"].collect {|h| h.match(/\/(\w+)\.rb/)[1]}
7
+
8
+ def self.load
9
+ require @@helpers_dir + '/time_dsl'
10
+ require @@helpers_dir + '/core_ext'
11
+ require @@helpers_dir + '/core_ext/numeric'
12
+
13
+ if Merb::Plugins.config[:merb_helpers]
14
+ config = Merb::Plugins.config[:merb_helpers]
15
+
16
+ if config[:include] && !config[:include].empty?
17
+ load_helpers(config[:include])
18
+ else
19
+ # This is in case someone defines an entry in the config,
20
+ # but doesn't put in a with or without option
21
+ load_helpers
22
+ end
23
+
24
+ else
25
+ load_helpers
26
+ end
27
+ end
28
+
29
+ # Load only specific helpers instead of loading all the helpers
30
+ def self.load_helpers(helpers = @@helpers_files)
31
+ helpers.each {|helper| Kernel.load(File.join(@@helpers_dir, "#{helper}.rb") )} # using load here allows specs to work
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ Merb::Helpers.load
@@ -0,0 +1,57 @@
1
+ require "date"
2
+ require File.dirname(__FILE__) + '/date_time_formatting'
3
+ class Date
4
+ include DateAndTimeFormatting
5
+
6
+ # Converts a Date instance to a Time, where the time is set to the beginning of the day.
7
+ # The timezone can be either :local or :utc (default :utc).
8
+ #
9
+ # ==== Examples:
10
+ # date = Date.new(2007, 11, 10)
11
+ # date.to_s # => 2007-11-10
12
+ #
13
+ # date.to_time # => Sat Nov 10 00:00:00 UTC 2007
14
+ # date.to_time(:utc) # => Sat Nov 10 00:00:00 UTC 2007
15
+ # date.to_time(:local) # => Sat Nov 10 00:00:00 -0800 2007
16
+ #
17
+ def to_time(form = :utc)
18
+ ::Time.send("#{form}", year, month, day)
19
+ end
20
+
21
+ def to_date; self; end
22
+
23
+ def formatted(format=:default)
24
+ format = Date.formats[format]
25
+ if format.nil?
26
+ self.to_s
27
+ else
28
+ self.strftime(format)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ class Time
35
+ include DateAndTimeFormatting
36
+
37
+ # Ruby 1.8-cvs and 1.9 define private Time#to_date
38
+ %w(to_date to_datetime).each do |method|
39
+ public method if private_instance_methods.include?(method)
40
+ end
41
+
42
+ def to_time; self; end
43
+ public :to_date
44
+ end
45
+
46
+ # Truncates a string to the given length and appends the given suffix if the string is, in fact, truncated.
47
+ #
48
+ # ==== Examples:
49
+ # "This is a long string right here".truncate(10, "...") #=> "This is..."
50
+
51
+ class String
52
+ def truncate(length = 30, truncate_string = "...")
53
+ return self unless self.length > length
54
+ length = length - truncate_string.split(//).length
55
+ self[0...length] + truncate_string
56
+ end
57
+ end
@@ -0,0 +1,388 @@
1
+ class Numeric
2
+ module Transformer
3
+
4
+ # known formats to use with the app
5
+ # users can add their own formats by using Numeric::Transformer.add_format(:format_name => {})
6
+
7
+ @formats ={
8
+ :us => {
9
+ :number => {
10
+ :precision => 3,
11
+ :delimiter => ',',
12
+ :separator => '.'
13
+ },
14
+ :currency => {
15
+ :unit => '$',
16
+ :format => '%u%n',
17
+ :precision => 2
18
+ }
19
+ },
20
+ :uk => {
21
+ :number => {
22
+ :precision => 3,
23
+ :delimiter => ',',
24
+ :separator => '.'
25
+ },
26
+ :currency => {
27
+ :unit => '&pound;',
28
+ :format => '%u%n',
29
+ :precision => 2
30
+ }
31
+ },
32
+ :au => {
33
+ :number => {
34
+ :precision => 3,
35
+ :delimiter => ',',
36
+ :separator => '.'
37
+ },
38
+ :currency => {
39
+ :unit => '$;',
40
+ :format => '%u%n',
41
+ :precision => 2
42
+ }
43
+ },
44
+ :fr => {
45
+ :number => {
46
+ :precision => 3,
47
+ :delimiter => ' ',
48
+ :separator => ','
49
+ },
50
+ :currency => {
51
+ :unit => '€',
52
+ :format => '%n%u',
53
+ :precision => 2
54
+ }
55
+ },
56
+ :ru => {
57
+ :number => {
58
+ :precision => 2,
59
+ :delimiter => ' ',
60
+ :separator => ','
61
+ },
62
+ :currency => {
63
+ :unit => 'р.',
64
+ :format => '%n %u',
65
+ :precision => 2
66
+ }
67
+ }
68
+ }
69
+
70
+ # accessor for @formats
71
+ #---
72
+ # @private
73
+ def self.formats
74
+ @formats
75
+ end
76
+
77
+ @default_format = @formats[:us]
78
+
79
+
80
+ # Accessor for the default format in use
81
+ #
82
+ #---
83
+ # @public
84
+ def self.default_format
85
+ @default_format
86
+ end
87
+
88
+
89
+ # Changes the default format to use when transforming a +Numeric+ instance
90
+ #
91
+ # ==== Parameters
92
+ # format_code <Symbol>:: format name to use as the new default format
93
+ #
94
+ # ==== Returns
95
+ # Hash:: a hash representing the default format
96
+ #
97
+ #---
98
+ # @public
99
+ def self.change_default_format(format_code)
100
+ @default_format = (formats[format_code] || default_format)
101
+ end
102
+
103
+
104
+ # Adds a new format to the existing transforming formats
105
+ #
106
+ # ==== Parameters
107
+ # format <Hash>:: format defining how to transform numeric values
108
+ #
109
+ # ==== Examples
110
+ #
111
+ #
112
+ #---
113
+ # @public
114
+ def self.add_format(format)
115
+ formats.merge!(format)
116
+ formats[format]
117
+ end
118
+
119
+
120
+ # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
121
+ # pass another format to format the number differently.
122
+ #
123
+ #
124
+ # ==== Parameters
125
+ # format_name<Symbol>:: name of the format to use
126
+ # options<Hash>:: options which will overwrite the used format
127
+ #
128
+ # ==== Returns
129
+ # String:: a string representing the delimited number
130
+ #
131
+ # ==== Options
132
+ # :delimiter - Overwrites the thousands delimiter.
133
+ # :separator - Overwrites the separator between the units.
134
+ #
135
+ # ==== Examples
136
+ # with_delimiter(12345678) # => 12,345,678
137
+ # with_delimiter(12345678.05) # => 12,345,678.05
138
+ # with_delimiter(12345678, :FR) # => 12.345.678
139
+ # with_delimiter(12345678, :US) # => 12,345,678
140
+ #
141
+ #---
142
+ # @private
143
+ def self.with_delimiter(number, format_name = nil, options = {})
144
+
145
+ format = (formats[format_name] || default_format)[:number].merge(options)
146
+
147
+ begin
148
+ parts = number.to_s.split('.')
149
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{format[:delimiter]}")
150
+ parts.join(format[:separator])
151
+ rescue
152
+ number
153
+ end
154
+ end
155
+
156
+ # Formats a +number+ with a level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
157
+ # You can pass another format to use and even overwrite the format's options.
158
+ #
159
+ #
160
+ # ==== Parameters
161
+ # format_name<Symbol>:: name of the format to use
162
+ # options<Hash>:: options which will overwrite the used format
163
+ #
164
+ # ==== Returns
165
+ # String:: a string representing the delimited number
166
+ #
167
+ # ==== Options
168
+ # :precision - Overwrites the level of precision
169
+ # :separator - Overwrites the separator between the units
170
+ # :delimiter - Overwrites the thousands delimiter
171
+ #
172
+ # ==== Examples
173
+ # with_precision(111.2345) # => 111.235
174
+ # with_precision(111.2345, :UK, :precision => 1) # => "111.2"
175
+ # with_precision(1234.567, :US, :precision => 1, :separator => ',', :delimiter => '-') # => "1-234,6"
176
+ #
177
+ #---
178
+ # @private
179
+ def self.with_precision(number, format_name = nil, options={})
180
+
181
+ format = (formats[format_name] || default_format)[:number].merge(options)
182
+
183
+ begin
184
+ rounded_number = (Float(number) * (10 ** format[:precision])).round.to_f / 10 ** format[:precision]
185
+ with_delimiter("%01.#{format[:precision]}f" % rounded_number, format_name, :delimiter => format[:delimiter], :separator => format[:separator])
186
+ rescue
187
+ number
188
+ end
189
+ end
190
+
191
+
192
+ # Formats a +number+ into a currency string (e.g., $13.65). You can specify a format to use
193
+ # and even overwrite some of the format options.
194
+ #
195
+ # ==== Parameters
196
+ # number<Numeric>:: Numeric value to convert
197
+ # format_name<Symbol>:: name of the format to use
198
+ # options<Hash>:: options which will overwrite the used format
199
+ #
200
+ # ==== Returns
201
+ # String:: a string representing the number converted in currency
202
+ #
203
+ # ==== Options
204
+ # :precision - Sets the level of precision
205
+ # :unit - Sets the denomination of the currency
206
+ # :format - Sets the format of the output string (defaults to "%u%n"). The field types are:
207
+ #
208
+ # %u The currency unit
209
+ # %n The number
210
+ #
211
+ # ==== Examples
212
+ # to_currency(1234567890.506, :US, :precision => 1) # => "$1,234,567,890.5"
213
+ # to_currency(1234567890.516, :FR) # =>"1 234 567 890,52€"
214
+ # to_currency(1234567890.516, :US, :unit => "€") # =>"€1,234,567,890.52"
215
+ # to_currency(1234567890.506, :US, :precision => 3, :unit => "€") # => "€1,234,567,890.506"
216
+ # to_currency(1234567890.506, :AU, :unit => "$AUD", :format => '%n %u') # => "1,234,567,890.51 $AUD"
217
+ #
218
+ #---
219
+ # @private
220
+ def self.to_currency(number, format_name = nil, options = {})
221
+
222
+ format = (formats[format_name] || default_format)[:currency].merge(options)
223
+
224
+ begin
225
+ format[:format].gsub(/%n/, with_precision(number,
226
+ format_name, :precision => format[:precision]) ).gsub(/%u/, format[:unit])
227
+ rescue
228
+ number
229
+ end
230
+ end
231
+
232
+
233
+ # Formats a +number+ into a two digit string. Basically it prepends an integer to a 2 digits string.
234
+ #
235
+ # ==== Parameters
236
+ # number<Numeric>:: Numeric value to convert
237
+ #
238
+ # ==== Returns
239
+ # String:: a string representing the number converted into a 2 digits string.
240
+ #
241
+ # ==== Examples
242
+ # two_digits(5-3) # => "02"
243
+ #
244
+ #---
245
+ # @private
246
+ def self.two_digits(number)
247
+ (0..9).include?(number) ? "0#{number}" : number.to_s
248
+ end
249
+
250
+ # Converts a +numeric+ value representing minutes into a string representing an hour value
251
+ #
252
+ # ==== Parameters
253
+ # number<Numeric>:: Numeric value representing minutes to convert in hours
254
+ #
255
+ # ==== Returns
256
+ # String:: a string representing the numeric value converted in hours
257
+ #
258
+ # ==== Examples
259
+ # minutes_to_hours(315) => "05:15"
260
+ #
261
+ #---
262
+ # @private
263
+ def self.minutes_to_hours(minutes)
264
+ hours = (minutes/60).ceil
265
+ minutes = (minutes - (hours * 60)).to_i
266
+ "#{two_digits(hours)}:#{two_digits(minutes)}"
267
+ end
268
+
269
+ end #of Numeric::Transformer
270
+
271
+ # Formats with with grouped thousands using +delimiter+ (e.g., 12,324). You can
272
+ # pass another format to format the number differently.
273
+ #
274
+ #
275
+ # ==== Parameters
276
+ # format_name<Symbol>:: name of the format to use
277
+ # options<Hash>:: options which will overwrite the used format
278
+ #
279
+ # ==== Returns
280
+ # String:: a string representing the delimited number
281
+ #
282
+ # ==== Options
283
+ # :delimiter - Overwrites the thousands delimiter.
284
+ # :separator - Overwrites the separator between the units.
285
+ #
286
+ # ==== Examples
287
+ # 12345678.with_delimiter # => 12,345,678
288
+ # 12345678.05.with_delimiter # => 12,345,678.05
289
+ # 12345678.with_delimiter(:FR) # => 12.345.678
290
+ # 12345678.with_delimiter(:US) # => 12,345,678
291
+ #
292
+ #---
293
+ # @public
294
+ def with_delimiter(format_name = nil, options = {})
295
+ Transformer.with_delimiter(self, format_name, options)
296
+ end
297
+
298
+ # Formats with a level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
299
+ # You can pass another format to use and even overwrite the format's options.
300
+ #
301
+ #
302
+ # ==== Parameters
303
+ # format_name<Symbol>:: name of the format to use
304
+ # options<Hash>:: options which will overwrite the used format
305
+ #
306
+ # ==== Returns
307
+ # String:: a string representing the delimited number
308
+ #
309
+ # ==== Options
310
+ # :precision - Overwrites the level of precision
311
+ # :separator - Overwrites the separator between the units
312
+ # :delimiter - Overwrites the thousands delimiter
313
+ #
314
+ # ==== Examples
315
+ # 111.2345.with_precision # => 111.235
316
+ # 111.2345.with_precision(:UK, :precision => 1) # => "111.2"
317
+ # 1234.567.with_precision(:US, :precision => 1, :separator => ',', :delimiter => '-') # => "1-234,6"
318
+ #
319
+ #---
320
+ # @public
321
+ def with_precision(format_name = nil, options = {})
322
+ Transformer.with_precision(self, format_name, options)
323
+ end
324
+
325
+ # Formats into a currency string (e.g., $13.65). You can specify a format to use
326
+ # and even overwrite some of the format options.
327
+ #
328
+ # ==== Parameters
329
+ # format_name<Symbol>:: name of the format to use
330
+ # options<Hash>:: options which will overwrite the used format
331
+ #
332
+ # ==== Returns
333
+ # String:: a string representing the number converted in currency
334
+ #
335
+ # ==== Options
336
+ # :precision - Sets the level of precision
337
+ # :unit - Sets the denomination of the currency
338
+ # :format - Sets the format of the output string (defaults to "%u%n"). The field types are:
339
+ #
340
+ # %u The currency unit
341
+ # %n The number
342
+ #
343
+ # ==== Examples
344
+ # 1234567890.506.to_currency(:US) # => "$1,234,567,890.51"
345
+ # 1234567890.506.to_currency(:US, :precision => 1) # => "$1,234,567,890.5"
346
+ # 1234567890.516.to_currency(:FR) # =>"1 234 567 890,52€"
347
+ # 1234567890.516.to_currency(:US, :unit => "€") # =>"€1,234,567,890.52"
348
+ # 1234567890.506.to_currency(:US, :precision => 3, :unit => "€") # => "€1,234,567,890.506"
349
+ # 1234567890.506.to_currency(:AU, :unit => "$AUD", :format => '%n %u') # => "1,234,567,890.51 $AUD"
350
+ #---
351
+ # @public
352
+ def to_currency(format_name = nil, options = {})
353
+ Transformer.to_currency(self, format_name, options)
354
+ end
355
+
356
+ # Formats a +number+ into a two digit string. Basically it prepends an integer to a 2 digits string.
357
+ #
358
+ # ==== Returns
359
+ # String:: a string representing the number converted into a 2 digits string.
360
+ #
361
+ # ==== Examples
362
+ # (5-3).two_digits # => "02"
363
+ #
364
+ #---
365
+ # @public
366
+ def two_digits
367
+ Transformer.two_digits(self)
368
+ end
369
+
370
+ # Converts a +numeric+ value representing minutes into a string representing an hour value
371
+ #
372
+ # ==== Parameters
373
+ # number<Numeric>:: Numeric value representing minutes to convert in hours
374
+ #
375
+ # ==== Returns
376
+ # String:: a string representing the numeric value converted in hours
377
+ #
378
+ # ==== Examples
379
+ # 315.minutes_to_hours => "05:15"
380
+ #
381
+ #---
382
+ # @public
383
+ def minutes_to_hours
384
+ Transformer.minutes_to_hours(self)
385
+ end
386
+
387
+
388
+ end