tennpipes-helper 3.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.rdoc +239 -0
  4. data/Rakefile +1 -0
  5. data/lib/tennpipes-helper.rb +62 -0
  6. data/lib/tennpipes-helper/asset_tag_helpers.rb +394 -0
  7. data/lib/tennpipes-helper/form_builder/abstract_form_builder.rb +279 -0
  8. data/lib/tennpipes-helper/form_builder/standard_form_builder.rb +40 -0
  9. data/lib/tennpipes-helper/form_helpers.rb +639 -0
  10. data/lib/tennpipes-helper/form_helpers/errors.rb +138 -0
  11. data/lib/tennpipes-helper/form_helpers/options.rb +98 -0
  12. data/lib/tennpipes-helper/form_helpers/security.rb +70 -0
  13. data/lib/tennpipes-helper/format_helpers.rb +372 -0
  14. data/lib/tennpipes-helper/locale/cs.yml +103 -0
  15. data/lib/tennpipes-helper/locale/da.yml +91 -0
  16. data/lib/tennpipes-helper/locale/de.yml +81 -0
  17. data/lib/tennpipes-helper/locale/en.yml +103 -0
  18. data/lib/tennpipes-helper/locale/es.yml +103 -0
  19. data/lib/tennpipes-helper/locale/fr.yml +79 -0
  20. data/lib/tennpipes-helper/locale/hu.yml +103 -0
  21. data/lib/tennpipes-helper/locale/it.yml +89 -0
  22. data/lib/tennpipes-helper/locale/ja.yml +103 -0
  23. data/lib/tennpipes-helper/locale/lv.yml +103 -0
  24. data/lib/tennpipes-helper/locale/nl.yml +82 -0
  25. data/lib/tennpipes-helper/locale/no.yml +91 -0
  26. data/lib/tennpipes-helper/locale/pl.yml +95 -0
  27. data/lib/tennpipes-helper/locale/pt_br.yml +103 -0
  28. data/lib/tennpipes-helper/locale/ro.yml +103 -0
  29. data/lib/tennpipes-helper/locale/ru.yml +103 -0
  30. data/lib/tennpipes-helper/locale/sv.yml +103 -0
  31. data/lib/tennpipes-helper/locale/tr.yml +103 -0
  32. data/lib/tennpipes-helper/locale/uk.yml +103 -0
  33. data/lib/tennpipes-helper/locale/zh_cn.yml +103 -0
  34. data/lib/tennpipes-helper/locale/zh_tw.yml +103 -0
  35. data/lib/tennpipes-helper/number_helpers.rb +283 -0
  36. data/lib/tennpipes-helper/output_helpers.rb +226 -0
  37. data/lib/tennpipes-helper/output_helpers/abstract_handler.rb +61 -0
  38. data/lib/tennpipes-helper/output_helpers/erb_handler.rb +27 -0
  39. data/lib/tennpipes-helper/output_helpers/haml_handler.rb +25 -0
  40. data/lib/tennpipes-helper/output_helpers/slim_handler.rb +18 -0
  41. data/lib/tennpipes-helper/render_helpers.rb +63 -0
  42. data/lib/tennpipes-helper/tag_helpers.rb +294 -0
  43. data/lib/tennpipes-helper/translation_helpers.rb +36 -0
  44. data/lib/tennpipes/rendering.rb +369 -0
  45. data/lib/tennpipes/rendering/erb_template.rb +40 -0
  46. data/lib/tennpipes/rendering/erubis_template.rb +66 -0
  47. data/lib/tennpipes/rendering/haml_template.rb +26 -0
  48. data/lib/tennpipes/rendering/slim_template.rb +20 -0
  49. data/test/fixtures/apps/render.rb +25 -0
  50. data/test/fixtures/apps/views/article/comment/show.slim +1 -0
  51. data/test/fixtures/apps/views/blog/post.erb +1 -0
  52. data/test/fixtures/apps/views/layouts/specific.erb +1 -0
  53. data/test/fixtures/apps/views/test/post.erb +1 -0
  54. data/test/fixtures/layouts/layout.erb +1 -0
  55. data/test/fixtures/markup_app/app.rb +87 -0
  56. data/test/fixtures/markup_app/views/button_to.erb +8 -0
  57. data/test/fixtures/markup_app/views/button_to.haml +5 -0
  58. data/test/fixtures/markup_app/views/button_to.slim +6 -0
  59. data/test/fixtures/markup_app/views/capture_concat.erb +14 -0
  60. data/test/fixtures/markup_app/views/capture_concat.haml +12 -0
  61. data/test/fixtures/markup_app/views/capture_concat.slim +12 -0
  62. data/test/fixtures/markup_app/views/content_for.erb +23 -0
  63. data/test/fixtures/markup_app/views/content_for.haml +19 -0
  64. data/test/fixtures/markup_app/views/content_for.slim +19 -0
  65. data/test/fixtures/markup_app/views/content_tag.erb +13 -0
  66. data/test/fixtures/markup_app/views/content_tag.haml +11 -0
  67. data/test/fixtures/markup_app/views/content_tag.slim +11 -0
  68. data/test/fixtures/markup_app/views/current_engine.erb +5 -0
  69. data/test/fixtures/markup_app/views/current_engine.haml +5 -0
  70. data/test/fixtures/markup_app/views/current_engine.slim +5 -0
  71. data/test/fixtures/markup_app/views/fields_for.erb +20 -0
  72. data/test/fixtures/markup_app/views/fields_for.haml +15 -0
  73. data/test/fixtures/markup_app/views/fields_for.slim +15 -0
  74. data/test/fixtures/markup_app/views/form_for.erb +72 -0
  75. data/test/fixtures/markup_app/views/form_for.haml +59 -0
  76. data/test/fixtures/markup_app/views/form_for.slim +59 -0
  77. data/test/fixtures/markup_app/views/form_tag.erb +95 -0
  78. data/test/fixtures/markup_app/views/form_tag.haml +78 -0
  79. data/test/fixtures/markup_app/views/form_tag.slim +79 -0
  80. data/test/fixtures/markup_app/views/link_to.erb +5 -0
  81. data/test/fixtures/markup_app/views/link_to.haml +4 -0
  82. data/test/fixtures/markup_app/views/link_to.slim +4 -0
  83. data/test/fixtures/markup_app/views/mail_to.erb +3 -0
  84. data/test/fixtures/markup_app/views/mail_to.haml +3 -0
  85. data/test/fixtures/markup_app/views/mail_to.slim +3 -0
  86. data/test/fixtures/markup_app/views/meta_tag.erb +3 -0
  87. data/test/fixtures/markup_app/views/meta_tag.haml +3 -0
  88. data/test/fixtures/markup_app/views/meta_tag.slim +3 -0
  89. data/test/fixtures/markup_app/views/partials/_erb.erb +1 -0
  90. data/test/fixtures/markup_app/views/partials/_haml.haml +1 -0
  91. data/test/fixtures/markup_app/views/partials/_slim.slim +1 -0
  92. data/test/fixtures/markup_app/views/simple_partial.erb +1 -0
  93. data/test/fixtures/markup_app/views/simple_partial.haml +1 -0
  94. data/test/fixtures/markup_app/views/simple_partial.slim +1 -0
  95. data/test/fixtures/render_app/app.rb +110 -0
  96. data/test/fixtures/render_app/views/_deep.erb +3 -0
  97. data/test/fixtures/render_app/views/_deep.haml +2 -0
  98. data/test/fixtures/render_app/views/_deep.slim +2 -0
  99. data/test/fixtures/render_app/views/_partial_block_erb.erb +10 -0
  100. data/test/fixtures/render_app/views/_partial_block_haml.haml +7 -0
  101. data/test/fixtures/render_app/views/_partial_block_slim.slim +7 -0
  102. data/test/fixtures/render_app/views/_unsafe.html.builder +2 -0
  103. data/test/fixtures/render_app/views/_unsafe_object.html.builder +2 -0
  104. data/test/fixtures/render_app/views/current_engine.haml +5 -0
  105. data/test/fixtures/render_app/views/current_engines/_erb.erb +1 -0
  106. data/test/fixtures/render_app/views/current_engines/_haml.haml +1 -0
  107. data/test/fixtures/render_app/views/current_engines/_slim.slim +1 -0
  108. data/test/fixtures/render_app/views/dive_inner_erb.erb +3 -0
  109. data/test/fixtures/render_app/views/dive_inner_haml.haml +2 -0
  110. data/test/fixtures/render_app/views/dive_inner_slim.slim +2 -0
  111. data/test/fixtures/render_app/views/dive_outer_erb.erb +3 -0
  112. data/test/fixtures/render_app/views/dive_outer_haml.haml +2 -0
  113. data/test/fixtures/render_app/views/dive_outer_slim.slim +2 -0
  114. data/test/fixtures/render_app/views/double_capture_erb.erb +3 -0
  115. data/test/fixtures/render_app/views/double_capture_haml.haml +2 -0
  116. data/test/fixtures/render_app/views/double_capture_slim.slim +2 -0
  117. data/test/fixtures/render_app/views/erb/test.erb +1 -0
  118. data/test/fixtures/render_app/views/explicit_engine.haml +5 -0
  119. data/test/fixtures/render_app/views/haml/test.haml +1 -0
  120. data/test/fixtures/render_app/views/render_block_erb.erb +5 -0
  121. data/test/fixtures/render_app/views/render_block_haml.haml +4 -0
  122. data/test/fixtures/render_app/views/render_block_slim.slim +4 -0
  123. data/test/fixtures/render_app/views/ruby_block_capture_erb.erb +1 -0
  124. data/test/fixtures/render_app/views/ruby_block_capture_haml.haml +1 -0
  125. data/test/fixtures/render_app/views/ruby_block_capture_slim.slim +1 -0
  126. data/test/fixtures/render_app/views/template/_user.haml +7 -0
  127. data/test/fixtures/render_app/views/template/haml_template.haml +1 -0
  128. data/test/fixtures/render_app/views/template/some_template.haml +2 -0
  129. data/test/fixtures/render_app/views/wrong_capture_erb.erb +3 -0
  130. data/test/fixtures/render_app/views/wrong_capture_haml.haml +2 -0
  131. data/test/fixtures/render_app/views/wrong_capture_slim.slim +2 -0
  132. data/test/helper.rb +88 -0
  133. data/test/test_asset_tag_helpers.rb +401 -0
  134. data/test/test_form_builder.rb +1216 -0
  135. data/test/test_form_helpers.rb +1056 -0
  136. data/test/test_format_helpers.rb +251 -0
  137. data/test/test_helpers.rb +10 -0
  138. data/test/test_locale.rb +20 -0
  139. data/test/test_number_helpers.rb +142 -0
  140. data/test/test_output_helpers.rb +157 -0
  141. data/test/test_render_helpers.rb +225 -0
  142. data/test/test_rendering.rb +706 -0
  143. data/test/test_rendering_extensions.rb +14 -0
  144. data/test/test_tag_helpers.rb +131 -0
  145. metadata +299 -0
@@ -0,0 +1,103 @@
1
+ zh_tw:
2
+ number:
3
+ # Used in number_with_delimiter().
4
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'.
5
+ format:
6
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5).
7
+ separator: "."
8
+ # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three).
9
+ delimiter: ","
10
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00).
11
+ precision: 3
12
+
13
+ # Used in number_to_currency().
14
+ currency:
15
+ format:
16
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00).
17
+ format: "%u %n"
18
+ unit: "NT$"
19
+ # These three are to override number.format and are optional.
20
+ separator: "."
21
+ delimiter: ","
22
+ precision: 2
23
+
24
+ # Used in number_to_percentage().
25
+ percentage:
26
+ format:
27
+ # These three are to override number.format and are optional.
28
+ # separator:
29
+ delimiter: ""
30
+ # precision:
31
+
32
+ # Used in number_to_precision().
33
+ precision:
34
+ format:
35
+ # These three are to override number.format and are optional.
36
+ # separator:
37
+ delimiter: ""
38
+ # precision:
39
+
40
+ # Used in number_to_human_size().
41
+ human:
42
+ format:
43
+ # These three are to override number.format and are optional.
44
+ # separator:
45
+ delimiter: ""
46
+ precision: 1
47
+ storage_units:
48
+ # Storage units output formatting.
49
+ # %u is the storage unit, %n is the number (default: 2 MB).
50
+ format: "%n %u"
51
+ units:
52
+ byte:
53
+ one: "Byte"
54
+ other: "Bytes"
55
+ kb: "KB"
56
+ mb: "MB"
57
+ gb: "GB"
58
+ tb: "TB"
59
+
60
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words().
61
+ datetime:
62
+ distance_in_words:
63
+ half_a_minute: "半分鐘"
64
+ less_than_x_seconds:
65
+ one: "不到一秒"
66
+ other: "不到 %{count} 秒"
67
+ x_seconds:
68
+ one: "一秒"
69
+ other: "%{count} 秒"
70
+ less_than_x_minutes:
71
+ one: "不到一分鐘"
72
+ other: "不到 %{count} 分鐘"
73
+ x_minutes:
74
+ one: "一分鐘"
75
+ other: "%{count} 分鐘"
76
+ about_x_hours:
77
+ one: "大約一小時"
78
+ other: "大約 %{count} 小時"
79
+ x_days:
80
+ one: "一天"
81
+ other: "%{count} 天"
82
+ about_x_months:
83
+ one: "大約一個月"
84
+ other: "大約 %{count} 個月"
85
+ x_months:
86
+ one: "一個月"
87
+ other: "%{count} 個月"
88
+ about_x_years:
89
+ one: "大約一年"
90
+ other: "大約 %{count} 年"
91
+ over_x_years:
92
+ one: "一年多"
93
+ other: "%{count} 年多"
94
+ almost_x_years:
95
+ one: "接近一年"
96
+ other: "接近 %{count} 年"
97
+ models:
98
+ errors:
99
+ template:
100
+ header:
101
+ one: "發生了 1 個錯誤使得「%{model}」無法被儲存。"
102
+ other: "發生了 %{count} 個錯誤使得「%{model}」無法被儲存。"
103
+ body: "以下欄位發生問題:"
@@ -0,0 +1,283 @@
1
+ module Tennpipes
2
+ module Helpers
3
+ ##
4
+ # Provides methods for converting numbers into formatted strings.
5
+ # Methods are provided for phone numbers, currency, percentage,
6
+ # precision, positional notation, and file size.
7
+ #
8
+ # Adapted from Rails Number Helpers.
9
+ #
10
+ module NumberHelpers
11
+ ##
12
+ # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
13
+ # in the +options+ hash.
14
+ #
15
+ # @param [Float] number
16
+ # Currency value to format.
17
+ # @param [Hash] options
18
+ # Options for currency conversion.
19
+ # @option options [Fixnum] :precision (2)
20
+ # Sets the level of precision.
21
+ # @option options [String] :unit ("$")
22
+ # Sets the denomination of the currency.
23
+ # @option options [String] :separator (".")
24
+ # Sets the separator between the units.
25
+ # @option options [String] :delimiter (",")
26
+ # Sets the thousands delimiter.
27
+ # @option options [String] :format ("%u%n")
28
+ # Sets the format of the output string. The field types are:
29
+ # %u The currency unit
30
+ # %n The number
31
+ #
32
+ # @return [String] The formatted representation of the currency.
33
+ #
34
+ # @example
35
+ # number_to_currency(1234567890.50) # => $1,234,567,890.50
36
+ # number_to_currency(1234567890.506) # => $1,234,567,890.51
37
+ # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
38
+ # number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
39
+ # # => £1234567890,50
40
+ # number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
41
+ # # => 1234567890,50 £
42
+ #
43
+ def number_to_currency(number, options = {})
44
+ options.symbolize_keys!
45
+
46
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
47
+ currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
48
+ defaults = defaults.merge(currency)
49
+
50
+ precision = options[:precision] || defaults[:precision]
51
+ unit = options[:unit] || defaults[:unit]
52
+ separator = options[:separator] || defaults[:separator]
53
+ delimiter = options[:delimiter] || defaults[:delimiter]
54
+ format = options[:format] || defaults[:format]
55
+ separator = '' if precision == 0
56
+
57
+ begin
58
+ format.gsub(/%n/, number_with_precision(number,
59
+ :precision => precision,
60
+ :delimiter => delimiter,
61
+ :separator => separator)
62
+ ).gsub(/%u/, unit)
63
+ rescue
64
+ number
65
+ end
66
+ end
67
+
68
+ ##
69
+ # Formats a +number+ as a percentage string (e.g., 65%). You can customize the
70
+ # format in the +options+ hash.
71
+ #
72
+ # @param [Fixnum, Float] number
73
+ # Percentage value to format.
74
+ # @param [Hash] options
75
+ # Options for percentage conversion.
76
+ # @option options [Fixnum] :precision (3)
77
+ # Sets the level of precision.
78
+ # @option options [String] :separator (".")
79
+ # Sets the separator between the units.
80
+ # @option options [String] :delimiter ("")
81
+ # Sets the thousands delimiter.
82
+ #
83
+ # @return [String] The formatted representation of the percentage
84
+ #
85
+ # @example
86
+ # number_to_percentage(100) # => 100.000%
87
+ # number_to_percentage(100, :precision => 0) # => 100%
88
+ # number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
89
+ # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
90
+ #
91
+ def number_to_percentage(number, options = {})
92
+ options.symbolize_keys!
93
+
94
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
95
+ percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :raise => true) rescue {}
96
+ defaults = defaults.merge(percentage)
97
+
98
+ precision = options[:precision] || defaults[:precision]
99
+ separator = options[:separator] || defaults[:separator]
100
+ delimiter = options[:delimiter] || defaults[:delimiter]
101
+
102
+ begin
103
+ number_with_precision(number,
104
+ :precision => precision,
105
+ :separator => separator,
106
+ :delimiter => delimiter) + "%"
107
+ rescue
108
+ number
109
+ end
110
+ end
111
+
112
+ ##
113
+ # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
114
+ # customize the format in the +options+ hash.
115
+ #
116
+ # @overload number_with_delimiter(number, options={})
117
+ # @param [Fixnum, Float] number
118
+ # Number value to format.
119
+ # @param [Hash] options
120
+ # Options for formatter.
121
+ # @option options [String] :delimiter (", ")
122
+ # Sets the thousands delimiter.
123
+ # @option options [String] :separator (".")
124
+ # Sets the separator between the units.
125
+ #
126
+ # @return [String] The formatted representation of the number.
127
+ #
128
+ # @example
129
+ # number_with_delimiter(12345678) # => 12,345,678
130
+ # number_with_delimiter(12345678.05) # => 12,345,678.05
131
+ # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
132
+ # number_with_delimiter(12345678, :separator => ",") # => 12,345,678
133
+ # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
134
+ # # => 98 765 432,98
135
+ #
136
+ def number_with_delimiter(number, *args)
137
+ options = args.extract_options!
138
+ options.symbolize_keys!
139
+
140
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
141
+
142
+ delimiter ||= (options[:delimiter] || defaults[:delimiter])
143
+ separator ||= (options[:separator] || defaults[:separator])
144
+
145
+ begin
146
+ parts = number.to_s.split('.')
147
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
148
+ parts.join(separator)
149
+ rescue
150
+ number
151
+ end
152
+ end
153
+
154
+ ##
155
+ # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
156
+ # You can customize the format in the +options+ hash.
157
+ #
158
+ # @overload number_with_precision(number, options={})
159
+ # @param [Fixnum, Float] number
160
+ # Number value to format.
161
+ # @param [Hash] options
162
+ # Options for formatter.
163
+ # @option options [Fixnum] :precision (3)
164
+ # Sets the level of precision.
165
+ # @option options [String] :separator (".")
166
+ # Sets the separator between the units.
167
+ # @option options [String] :delimiter ("")
168
+ # Sets the thousands delimiter.
169
+ #
170
+ # @return [String] The formatted representation of the number.
171
+ #
172
+ # @example
173
+ # number_with_precision(111.2345) # => 111.235
174
+ # number_with_precision(111.2345, :precision => 2) # => 111.23
175
+ # number_with_precision(13, :precision => 5) # => 13.00000
176
+ # number_with_precision(389.32314, :precision => 0) # => 389
177
+ # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
178
+ # # => 1.111,23
179
+ #
180
+ def number_with_precision(number, *args)
181
+ options = args.extract_options!
182
+ options.symbolize_keys!
183
+
184
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
185
+ precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale],
186
+ :raise => true) rescue {}
187
+ defaults = defaults.merge(precision_defaults)
188
+
189
+ precision ||= (options[:precision] || defaults[:precision])
190
+ separator ||= (options[:separator] || defaults[:separator])
191
+ delimiter ||= (options[:delimiter] || defaults[:delimiter])
192
+
193
+ begin
194
+ rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision
195
+ number_with_delimiter("%01.#{precision}f" % rounded_number,
196
+ :separator => separator,
197
+ :delimiter => delimiter)
198
+ rescue
199
+ number
200
+ end
201
+ end
202
+
203
+ # The units available for storage formatting.
204
+ STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
205
+
206
+ ##
207
+ # Formats the bytes in +size+ into a more understandable representation
208
+ # (e.g., giving it 1500 yields 1.5 KB). This method is useful for
209
+ # reporting file sizes to users. This method returns nil if
210
+ # +size+ cannot be converted into a number. You can customize the
211
+ # format in the +options+ hash.
212
+ #
213
+ #
214
+ # @overload number_to_human_size(number, options={})
215
+ # @param [Fixnum] number
216
+ # Number value to format.
217
+ # @param [Hash] options
218
+ # Options for formatter.
219
+ # @option options [Fixnum] :precision (1)
220
+ # Sets the level of precision.
221
+ # @option options [String] :separator (".")
222
+ # Sets the separator between the units.
223
+ # @option options [String] :delimiter ("")
224
+ # Sets the thousands delimiter.
225
+ #
226
+ # @return [String] The formatted representation of bytes
227
+ #
228
+ # @example
229
+ # number_to_human_size(123) # => 123 Bytes
230
+ # number_to_human_size(1234) # => 1.2 KB
231
+ # number_to_human_size(12345) # => 12.1 KB
232
+ # number_to_human_size(1234567) # => 1.2 MB
233
+ # number_to_human_size(1234567890) # => 1.1 GB
234
+ # number_to_human_size(1234567890123) # => 1.1 TB
235
+ # number_to_human_size(1234567, :precision => 2) # => 1.18 MB
236
+ # number_to_human_size(483989, :precision => 0) # => 473 KB
237
+ # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB
238
+ #
239
+ def number_to_human_size(number, *args)
240
+ return nil if number.nil?
241
+
242
+ options = args.extract_options!
243
+ options.symbolize_keys!
244
+
245
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
246
+ human = I18n.translate(:'number.human.format', :locale => options[:locale], :raise => true) rescue {}
247
+ defaults = defaults.merge(human)
248
+
249
+ precision ||= (options[:precision] || defaults[:precision])
250
+ separator ||= (options[:separator] || defaults[:separator])
251
+ delimiter ||= (options[:delimiter] || defaults[:delimiter])
252
+
253
+ storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
254
+
255
+ if number.to_i < 1024
256
+ unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
257
+ storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit)
258
+ else
259
+ max_exp = STORAGE_UNITS.size - 1
260
+ number = Float(number)
261
+ exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
262
+ exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
263
+ number /= 1024 ** exponent
264
+
265
+ unit_key = STORAGE_UNITS[exponent]
266
+ unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
267
+
268
+ begin
269
+ escaped_separator = Regexp.escape(separator)
270
+ formatted_number = number_with_precision(number,
271
+ :precision => precision,
272
+ :separator => separator,
273
+ :delimiter => delimiter
274
+ ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
275
+ storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
276
+ rescue
277
+ number
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,226 @@
1
+ module Tennpipes
2
+ module Helpers
3
+ ##
4
+ # Helpers related to buffer output for various template engines.
5
+ #
6
+ module OutputHelpers
7
+ def self.included(base)
8
+ base.send(:include, SinatraCurrentEngine) unless base.method_defined?(:current_engine)
9
+ end
10
+
11
+ ##
12
+ # Returns the list of all available template handlers.
13
+ #
14
+ def self.handlers
15
+ @_template_handlers ||= {}
16
+ end
17
+
18
+ ##
19
+ # Registers a new handler as available to the output helpers.
20
+ #
21
+ def self.register(engine, handler)
22
+ handlers[engine] = handler
23
+ end
24
+
25
+ ##
26
+ # Module used to detect the current engine in vanilla Sinatra apps.
27
+ #
28
+ module SinatraCurrentEngine
29
+ attr_reader :current_engine
30
+
31
+ def render(engine, *)
32
+ @current_engine, engine_was = engine, @current_engine
33
+ output = super
34
+ @current_engine = engine_was
35
+ output
36
+ end
37
+ end
38
+
39
+ ##
40
+ # Captures the html from a block of template code for any available handler.
41
+ #
42
+ # Be aware that trusting the html is up to the caller.
43
+ #
44
+ # @param [Object] *args
45
+ # Objects yield to the captured block.
46
+ # @param [Proc] &block
47
+ # Template code to capture as HTML.
48
+ #
49
+ # @return [String] Captured HTML resulting from the block.
50
+ #
51
+ # @example
52
+ # capture_html(&block) => "...html..."
53
+ # capture_html(object_for_block, &block) => "...html..."
54
+ #
55
+ # @example
56
+ # ActiveSupport::SafeBuffer.new + capture_html { "<foo>" }
57
+ # # => "&lt;foo&gt;"
58
+ # ActiveSupport::SafeBuffer.new.safe_concat(capture_html { "<foo>" })
59
+ # # => "<foo>"
60
+ #
61
+ def capture_html(*args, &block)
62
+ if handler = find_proper_handler
63
+ handler.capture_from_template(*args, &block)
64
+ else
65
+ yield(*args)
66
+ end
67
+ end
68
+ alias :capture :capture_html
69
+
70
+ ##
71
+ # Outputs the given text to the templates buffer directly.
72
+ #
73
+ # The output might be subject to escaping, if it is not marked as safe.
74
+ #
75
+ # @param [String, SafeBuffer] text
76
+ # Text to concatenate to the buffer.
77
+ #
78
+ # @example
79
+ # concat_content("This will be output to the template buffer")
80
+ #
81
+ def concat_content(text="")
82
+ if handler = find_proper_handler
83
+ handler.concat_to_template(text)
84
+ else
85
+ text
86
+ end
87
+ end
88
+ alias :concat :concat_content
89
+
90
+ ##
91
+ # Outputs the given text to the templates buffer directly,
92
+ # assuming that it is safe.
93
+ #
94
+ # @param [String] text
95
+ # Text to concatenate to the buffer.
96
+ #
97
+ # @example
98
+ # concat_safe_content("This will be output to the template buffer")
99
+ #
100
+ def concat_safe_content(text="")
101
+ concat_content text.html_safe
102
+ end
103
+
104
+ ##
105
+ # Returns true if the block is from a supported template type; false otherwise.
106
+ # Used to determine if html should be returned or concatenated to the view.
107
+ #
108
+ # @param [Block] block
109
+ # Determine if this block is a view template.
110
+ #
111
+ # @example
112
+ # block_is_template?(block) => true
113
+ #
114
+ # @return [Boolean] True if the block is a template; false otherwise.
115
+ #
116
+ def block_is_template?(block)
117
+ handler = find_proper_handler
118
+ block && handler && handler.engine_matches?(block)
119
+ end
120
+
121
+ ##
122
+ # Capture a block or text of content to be rendered at a later time.
123
+ # Your blocks can also receive values, which are passed to them by <tt>yield_content</tt>.
124
+ #
125
+ # @overload content_for(key, content)
126
+ # @param [Symbol] key Name of your key for the content yield.
127
+ # @param [String] content Text to be stored for this key.
128
+ # @param [Hash] options Options associated with this method.
129
+ # @overload content_for(key, &block)
130
+ # @param [Symbol] key Name of your key for the content yield.
131
+ # @param [Proc] block Block to be stored as content for this key.
132
+ # @param [Hash] options Options associated with this method.
133
+ #
134
+ # @option options [Boolean] :flush
135
+ # Specifies whether to replace the content.
136
+ #
137
+ # @example
138
+ # content_for(:name) { ...content... }
139
+ # content_for(:name) { |name| ...content... }
140
+ # content_for(:name, "I'm Jeff")
141
+ # content_for(:name, :flush => true) { ...new content... }
142
+ #
143
+ def content_for(key, content = nil, options = {}, &block)
144
+ options = content if content.is_a?(Hash)
145
+ content_blocks[key.to_sym].clear if options[:flush]
146
+ content_blocks[key.to_sym] << (block_given? ? block : Proc.new { content })
147
+ end
148
+
149
+ ##
150
+ # Is there a content block for a given key?
151
+ #
152
+ # @param [Symbol] key
153
+ # Name of content to yield.
154
+ #
155
+ # @return [TrueClass,FalseClass] Result html for the given +key+
156
+ #
157
+ # @example
158
+ # content_for? :header => true
159
+ #
160
+ def content_for?(key)
161
+ !content_blocks[key.to_sym].empty?
162
+ end
163
+
164
+ ##
165
+ # Render the captured content blocks for a given key.
166
+ # You can also pass values to the content blocks by passing them
167
+ # as arguments after the key.
168
+ #
169
+ # @param [Symbol] key
170
+ # Name of content to yield.
171
+ # @param *args
172
+ # Values to pass to the content block.
173
+ #
174
+ # @return [String] Result HTML for the given +key+.
175
+ #
176
+ # @example
177
+ # yield_content :include
178
+ # yield_content :head, "param1", "param2"
179
+ # yield_content(:title) || "My page title"
180
+ #
181
+ def yield_content(key, *args)
182
+ blocks = content_blocks[key.to_sym]
183
+ return nil if blocks.empty?
184
+ blocks.inject(ActiveSupport::SafeBuffer.new){ |all,content| all << capture_html(*args, &content) }
185
+ end
186
+
187
+ protected
188
+ ##
189
+ # Retrieves content_blocks stored by content_for or within yield_content.
190
+ #
191
+ # @example
192
+ # content_blocks[:name] => ['...', '...']
193
+ #
194
+ def content_blocks
195
+ @content_blocks ||= Hash.new { |h,k| h[k] = [] }
196
+ end
197
+
198
+ ##
199
+ # Retrieves the template handler for the given output context.
200
+ # Can handle any output related to capturing or concatenating in a given template.
201
+ #
202
+ # @example
203
+ # find_proper_handler => <OutputHelpers::HamlHandler>
204
+ #
205
+ def find_proper_handler
206
+ handler_class = OutputHelpers.handlers[current_engine]
207
+ handler_class && handler_class.new(self)
208
+ end
209
+
210
+ ##
211
+ # Marks a String or a collection of Strings as safe. `nil` is accepted
212
+ # but ignored.
213
+ #
214
+ # @param [String, Array<String>] the values to be marked safe.
215
+ #
216
+ # @return [ActiveSupport::SafeBuffer, Array<ActiveSupport::SafeBuffer>]
217
+ def mark_safe(value)
218
+ if value.respond_to? :map!
219
+ value.map!{|v| v.html_safe if v }
220
+ else
221
+ value.html_safe if value
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end