raw 0.49.0

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.
Files changed (148) hide show
  1. data/doc/CONTRIBUTORS +106 -0
  2. data/doc/LICENSE +32 -0
  3. data/doc/coding_conventions.txt +11 -0
  4. data/lib/raw.rb +42 -0
  5. data/lib/raw/adapter.rb +113 -0
  6. data/lib/raw/adapter/cgi.rb +41 -0
  7. data/lib/raw/adapter/fastcgi.rb +48 -0
  8. data/lib/raw/adapter/mongrel.rb +146 -0
  9. data/lib/raw/adapter/script.rb +94 -0
  10. data/lib/raw/adapter/webrick.rb +144 -0
  11. data/lib/raw/adapter/webrick/vcr.rb +91 -0
  12. data/lib/raw/cgi.rb +323 -0
  13. data/lib/raw/cgi/cookie.rb +47 -0
  14. data/lib/raw/cgi/http.rb +62 -0
  15. data/lib/raw/compiler.rb +138 -0
  16. data/lib/raw/compiler/filter/cleanup.rb +21 -0
  17. data/lib/raw/compiler/filter/elements.rb +166 -0
  18. data/lib/raw/compiler/filter/elements/element.rb +210 -0
  19. data/lib/raw/compiler/filter/localization.rb +23 -0
  20. data/lib/raw/compiler/filter/markup.rb +32 -0
  21. data/lib/raw/compiler/filter/morph.rb +123 -0
  22. data/lib/raw/compiler/filter/morph/each.rb +34 -0
  23. data/lib/raw/compiler/filter/morph/for.rb +11 -0
  24. data/lib/raw/compiler/filter/morph/if.rb +26 -0
  25. data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
  26. data/lib/raw/compiler/filter/morph/standard.rb +55 -0
  27. data/lib/raw/compiler/filter/morph/times.rb +27 -0
  28. data/lib/raw/compiler/filter/script.rb +116 -0
  29. data/lib/raw/compiler/filter/squeeze.rb +16 -0
  30. data/lib/raw/compiler/filter/static_include.rb +74 -0
  31. data/lib/raw/compiler/filter/template.rb +121 -0
  32. data/lib/raw/compiler/reloader.rb +96 -0
  33. data/lib/raw/context.rb +154 -0
  34. data/lib/raw/context/flash.rb +157 -0
  35. data/lib/raw/context/global.rb +88 -0
  36. data/lib/raw/context/request.rb +338 -0
  37. data/lib/raw/context/response.rb +57 -0
  38. data/lib/raw/context/session.rb +198 -0
  39. data/lib/raw/context/session/drb.rb +11 -0
  40. data/lib/raw/context/session/file.rb +15 -0
  41. data/lib/raw/context/session/memcached.rb +13 -0
  42. data/lib/raw/context/session/memory.rb +12 -0
  43. data/lib/raw/context/session/og.rb +15 -0
  44. data/lib/raw/context/session/pstore.rb +13 -0
  45. data/lib/raw/control.rb +18 -0
  46. data/lib/raw/control/attribute.rb +91 -0
  47. data/lib/raw/control/attribute/checkbox.rb +25 -0
  48. data/lib/raw/control/attribute/datetime.rb +21 -0
  49. data/lib/raw/control/attribute/file.rb +20 -0
  50. data/lib/raw/control/attribute/fixnum.rb +26 -0
  51. data/lib/raw/control/attribute/float.rb +26 -0
  52. data/lib/raw/control/attribute/options.rb +38 -0
  53. data/lib/raw/control/attribute/password.rb +16 -0
  54. data/lib/raw/control/attribute/text.rb +16 -0
  55. data/lib/raw/control/attribute/textarea.rb +16 -0
  56. data/lib/raw/control/none.rb +16 -0
  57. data/lib/raw/control/relation.rb +59 -0
  58. data/lib/raw/control/relation/belongs_to.rb +0 -0
  59. data/lib/raw/control/relation/has_many.rb +97 -0
  60. data/lib/raw/control/relation/joins_many.rb +0 -0
  61. data/lib/raw/control/relation/many_to_many.rb +0 -0
  62. data/lib/raw/control/relation/refers_to.rb +29 -0
  63. data/lib/raw/controller.rb +37 -0
  64. data/lib/raw/controller/publishable.rb +160 -0
  65. data/lib/raw/dispatcher.rb +209 -0
  66. data/lib/raw/dispatcher/format.rb +108 -0
  67. data/lib/raw/dispatcher/format/atom.rb +31 -0
  68. data/lib/raw/dispatcher/format/css.rb +0 -0
  69. data/lib/raw/dispatcher/format/html.rb +42 -0
  70. data/lib/raw/dispatcher/format/json.rb +31 -0
  71. data/lib/raw/dispatcher/format/rss.rb +33 -0
  72. data/lib/raw/dispatcher/format/xoxo.rb +31 -0
  73. data/lib/raw/dispatcher/mounter.rb +60 -0
  74. data/lib/raw/dispatcher/router.rb +111 -0
  75. data/lib/raw/errors.rb +19 -0
  76. data/lib/raw/helper.rb +86 -0
  77. data/lib/raw/helper/benchmark.rb +23 -0
  78. data/lib/raw/helper/buffer.rb +60 -0
  79. data/lib/raw/helper/cookie.rb +32 -0
  80. data/lib/raw/helper/debug.rb +28 -0
  81. data/lib/raw/helper/default.rb +16 -0
  82. data/lib/raw/helper/feed.rb +451 -0
  83. data/lib/raw/helper/form.rb +284 -0
  84. data/lib/raw/helper/javascript.rb +59 -0
  85. data/lib/raw/helper/layout.rb +40 -0
  86. data/lib/raw/helper/navigation.rb +87 -0
  87. data/lib/raw/helper/pager.rb +305 -0
  88. data/lib/raw/helper/table.rb +247 -0
  89. data/lib/raw/helper/xhtml.rb +218 -0
  90. data/lib/raw/helper/xml.rb +125 -0
  91. data/lib/raw/mixin/magick.rb +35 -0
  92. data/lib/raw/mixin/sweeper.rb +71 -0
  93. data/lib/raw/mixin/thumbnails.rb +1 -0
  94. data/lib/raw/mixin/webfile.rb +165 -0
  95. data/lib/raw/render.rb +271 -0
  96. data/lib/raw/render/builder.rb +26 -0
  97. data/lib/raw/render/caching.rb +81 -0
  98. data/lib/raw/render/call.rb +43 -0
  99. data/lib/raw/render/send_file.rb +46 -0
  100. data/lib/raw/render/stream.rb +39 -0
  101. data/lib/raw/scaffold.rb +13 -0
  102. data/lib/raw/scaffold/controller.rb +25 -0
  103. data/lib/raw/scaffold/model.rb +157 -0
  104. data/lib/raw/test.rb +5 -0
  105. data/lib/raw/test/assertions.rb +169 -0
  106. data/lib/raw/test/context.rb +55 -0
  107. data/lib/raw/test/testcase.rb +79 -0
  108. data/lib/raw/util/attr.rb +128 -0
  109. data/lib/raw/util/encode_uri.rb +149 -0
  110. data/lib/raw/util/html_filter.rb +538 -0
  111. data/lib/raw/util/markup.rb +130 -0
  112. data/test/glue/tc_webfile.rb +1 -0
  113. data/test/nitro/CONFIG.rb +3 -0
  114. data/test/nitro/adapter/raw_post1.bin +9 -0
  115. data/test/nitro/adapter/tc_webrick.rb +16 -0
  116. data/test/nitro/cgi/tc_cookie.rb +14 -0
  117. data/test/nitro/cgi/tc_request.rb +61 -0
  118. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  119. data/test/nitro/compiler/tc_compiler.rb +25 -0
  120. data/test/nitro/dispatcher/tc_mounter.rb +47 -0
  121. data/test/nitro/helper/tc_feed.rb +135 -0
  122. data/test/nitro/helper/tc_navbar.rb +74 -0
  123. data/test/nitro/helper/tc_pager.rb +35 -0
  124. data/test/nitro/helper/tc_table.rb +68 -0
  125. data/test/nitro/helper/tc_xhtml.rb +19 -0
  126. data/test/nitro/tc_caching.rb +19 -0
  127. data/test/nitro/tc_cgi.rb +222 -0
  128. data/test/nitro/tc_context.rb +17 -0
  129. data/test/nitro/tc_controller.rb +103 -0
  130. data/test/nitro/tc_controller_aspect.rb +32 -0
  131. data/test/nitro/tc_controller_params.rb +885 -0
  132. data/test/nitro/tc_dispatcher.rb +109 -0
  133. data/test/nitro/tc_element.rb +85 -0
  134. data/test/nitro/tc_flash.rb +59 -0
  135. data/test/nitro/tc_helper.rb +47 -0
  136. data/test/nitro/tc_render.rb +119 -0
  137. data/test/nitro/tc_router.rb +61 -0
  138. data/test/nitro/tc_server.rb +35 -0
  139. data/test/nitro/tc_session.rb +66 -0
  140. data/test/nitro/tc_template.rb +71 -0
  141. data/test/nitro/util/tc_encode_url.rb +87 -0
  142. data/test/nitro/util/tc_markup.rb +31 -0
  143. data/test/public/blog/another/very_litle/index.xhtml +1 -0
  144. data/test/public/blog/inc1.xhtml +2 -0
  145. data/test/public/blog/inc2.xhtml +1 -0
  146. data/test/public/blog/list.xhtml +9 -0
  147. data/test/public/dummy_mailer/registration.xhtml +5 -0
  148. metadata +244 -0
@@ -0,0 +1,305 @@
1
+ require 'facets/more/settings'
2
+
3
+ require 'og/collection'
4
+
5
+ module Raw
6
+
7
+ # Displays a collection of entitities in multiple pages.
8
+ #
9
+ # === Design
10
+ #
11
+ # This pager is carefully designed for scaleability. It stores
12
+ # only the items for one page. The key parameter is needed,
13
+ # multiple pagers can coexist in a single page. The pager
14
+ # leverages the SQL LIMIT option to optimize database
15
+ # interaction.
16
+
17
+ class Pager
18
+ # Items per page.
19
+
20
+ setting :per_page, :default => 10, :doc => 'Items per page'
21
+
22
+ # The request key.
23
+
24
+ setting :key, :default => '_page', :doc => 'The request key'
25
+
26
+ # The current page.
27
+
28
+ attr_accessor :page
29
+
30
+ # Items per page.
31
+
32
+ attr_accessor :per_page
33
+
34
+ # The total number of pages.
35
+
36
+ attr_accessor :page_count
37
+
38
+ # Total count of items.
39
+
40
+ attr_accessor :total_count
41
+
42
+ def initialize(request, per_page, total_count, key = Pager.key)
43
+ raise 'per_page should be > 0' unless per_page > 0
44
+
45
+ @request, @key = request, key
46
+ @page = (request.query[key] || 1).to_i
47
+ @per_page = per_page
48
+ set_count(total_count)
49
+ @start_idx = (@page - 1) * per_page
50
+ end
51
+
52
+ def set_count(total_count)
53
+ @total_count = total_count
54
+ @page_count = (@total_count.to_f / @per_page).ceil
55
+ end
56
+
57
+ # Return the first page index.
58
+
59
+ def first_page
60
+ return 1
61
+ end
62
+
63
+ # Is the first page displayed?
64
+
65
+ def first_page?
66
+ @page == 1
67
+ end
68
+
69
+ # Return the last page index.
70
+
71
+ def last_page
72
+ return @page_count
73
+ end
74
+
75
+ # Is the last page displayed?
76
+
77
+ def last_page?
78
+ @page == @page_count
79
+ end
80
+
81
+ # Return the index of the previous page.
82
+
83
+ def previous_page
84
+ return [@page - 1, 1].max()
85
+ end
86
+
87
+ # Return the index of the next page.
88
+
89
+ def next_page
90
+ return [@page + 1, @page_count].min()
91
+ end
92
+
93
+ # A set of helpers to create links to common pages.
94
+
95
+ for target in [:first, :last, :previous, :next]
96
+ eval %{
97
+ def link_#{target}_page
98
+ target_uri(#{target}_page)
99
+ end
100
+ alias_method :#{target}_page_uri, :link_#{target}_page
101
+ alias_method :#{target}_page_href, :link_#{target}_page
102
+ }
103
+ end
104
+
105
+ # Iterator
106
+
107
+ def each(&block)
108
+ @page_items.each(&block)
109
+ end
110
+
111
+ # Iterator
112
+ # Returns 1-based index.
113
+
114
+ def each_with_index
115
+ idx = @start_idx
116
+ for item in @page_items
117
+ yield(idx + 1, item)
118
+ idx += 1
119
+ end
120
+ end
121
+
122
+ # Is the pager empty, ie has one page only?
123
+
124
+ def empty?
125
+ return @page_count < 1
126
+ end
127
+
128
+ # The items count.
129
+
130
+ def size
131
+ return @total_count
132
+ end
133
+
134
+ # Returns the range of the current page.
135
+
136
+ def page_range
137
+ s = @idx
138
+ e = [@idx + @items_per_page - 1, all_total_count].min
139
+
140
+ return [s, e]
141
+ end
142
+
143
+ # Override if needed.
144
+
145
+ def nav_range
146
+ # effective range = 10 pages.
147
+ s = [@page - 5, 1].max()
148
+ e = [@page + 9, @page_count].min()
149
+
150
+ d = 9 - (e - s)
151
+ e += d if d < 0
152
+
153
+ return (s..e)
154
+ end
155
+
156
+ # To be used with Og queries.
157
+
158
+ def limit
159
+ if @start_idx > 0
160
+ { :limit => @per_page, :offset => @start_idx }
161
+ else
162
+ { :limit => @per_page }
163
+ end
164
+ end
165
+
166
+ def offset
167
+ @start_idx
168
+ end
169
+
170
+ # Create an appropriate SQL limit clause.
171
+ # Returns postgres/mysql compatible limit.
172
+
173
+ def to_sql
174
+ if @start_idx > 0
175
+ return "LIMIT #{@per_page} OFFSET #{@start_idx}"
176
+ else
177
+ # gmosx: perhaps this is optimized ? naaaaaah...
178
+ return "LIMIT #{@per_page}"
179
+ end
180
+ end
181
+
182
+ # Override this method in your application if needed.
183
+ #--
184
+ # TODO: better markup.
185
+ #++
186
+
187
+ def navigation
188
+ nav = ""
189
+
190
+ unless first_page?
191
+ nav << %{
192
+ <div class="first"><a href="#{first_page_href}">First</a></div>
193
+ <div class="previous"><a href="#{previous_page_href}">Previous</a></div>
194
+ }
195
+ end
196
+
197
+ unless last_page?
198
+ nav << %{
199
+ <div class="last"><a href="#{last_page_href}">Last</a></div>
200
+ <div class="next"><a href="#{next_page_href}">Next</a></div>
201
+ }
202
+ end
203
+
204
+ nav << %{<ul>}
205
+
206
+ for i in nav_range()
207
+ if i == @page
208
+ nav << %{
209
+ <li class="active">#{i}</li>
210
+ }
211
+ else
212
+ nav << %{
213
+ <li><a href="#{target_uri(i)}">#{i}</a></li>
214
+ }
215
+ end
216
+ end
217
+
218
+ nav << %{</ul>}
219
+
220
+ return nav
221
+ end
222
+ alias_method :links, :navigation
223
+
224
+ def navigation_needed?
225
+ @page_count > 1
226
+ end
227
+ alias_method :navigation?, :navigation_needed?
228
+
229
+ private
230
+
231
+ # Generate the target URI.
232
+
233
+ def target_uri(page)
234
+ uri = @request.uri.to_s
235
+
236
+ if uri =~ /[?;]#{@key}=(\d*)/
237
+ return uri.gsub(/([?;]#{@key}=)\d*/) { |m| "#$1#{page}" }
238
+ elsif uri =~ /\?/
239
+ return "#{uri};#{@key}=#{page}"
240
+ else
241
+ return "#{uri}?#{@key}=#{page}"
242
+ end
243
+ end
244
+
245
+ end
246
+
247
+ # Pager related helper methods.
248
+
249
+ module PagerHelper
250
+
251
+ private
252
+
253
+ # Helper method that generates a collection of items and the
254
+ # associated pager object.
255
+ #
256
+ # === Example
257
+ #
258
+ # entries, pager = paginate(Article, :condition => 'title LIKE %Ab%', :per_page => 10)
259
+ #
260
+ # or
261
+ #
262
+ # items = [ 'item1', 'item2', ... ]
263
+ # entries, pager = paginate(items, :per_page => 10)
264
+ #
265
+ # or
266
+ #
267
+ # entries, pager = paginate(article.comments, :per_page => 10)
268
+ #
269
+ # <ul>
270
+ # <?r for entry in entries ?>
271
+ # <li>#{entry.to_link}</li>
272
+ # <?r end ?>
273
+ # </ul>
274
+ # #{pager.links}
275
+
276
+ def paginate(items, options = {})
277
+ per_page = options.delete(:per_page) || options[:limit] || Pager.per_page
278
+ pager_key = options.delete(:pager_key) || Pager.key
279
+
280
+ case items
281
+ when Array
282
+ items = items.dup
283
+ pager = Pager.new(request, per_page, items.size, pager_key)
284
+ items = items.slice(pager.offset, pager.per_page) || []
285
+ return items, pager
286
+
287
+ when Og::Collection
288
+ collection = items
289
+ pager = Pager.new(request, per_page, collection.count, pager_key)
290
+ options.update(pager.limit)
291
+ items = collection.reload(options)
292
+ return items, pager
293
+
294
+ when Class
295
+ klass = items
296
+ pager = Pager.new(request, per_page, klass.count(options), pager_key)
297
+ options.update(pager.limit)
298
+ items = klass.all(options)
299
+ return items, pager
300
+ end
301
+ end
302
+
303
+ end
304
+
305
+ end
@@ -0,0 +1,247 @@
1
+ require "facets/more/settings"
2
+
3
+ require "glue/uri"
4
+
5
+ module Raw
6
+
7
+ # The TableBuilder is a helper class that automates the creation
8
+ # of tables from collections of objects. The resulting html
9
+ # can be styled using css.
10
+ #
11
+ # === Example
12
+ #
13
+ # <?r
14
+ # users = User.all.map { |u| [u.name, u.first_name, u.last_name, u.email] }
15
+ # headers = ['Username', 'First name', 'Last name', 'Email']
16
+ # ?>
17
+ #
18
+ # <div class="custom-table-class">
19
+ # #{table :values => users, :headers => header}
20
+ # </div>
21
+ #
22
+ #
23
+ # === Extended Example
24
+ #
25
+ # <?r
26
+ # users = User.all.map { |u| [u.name, u.first_name, u.last_name, u.email] }
27
+ # headers = ['Username', 'First name', 'Last name', 'Email']
28
+ # order_opts = { :right => true, # right align the order controls
29
+ # :values => [nil, 'first_name', 'last_name'], # column names from DB
30
+ # :asc_pic => "/images/asc.png",
31
+ # :desc_pic => "/images/desc.png" }
32
+ # ?>
33
+ #
34
+ # <div class="custom-table-class">
35
+ # #{table :values => users, :headers => header,
36
+ # :order => order_opts, :alternating_rows => true }
37
+ # </div>
38
+ #
39
+ #--
40
+ # TODO: legend, verbose... ?
41
+ # TODO, gmosx: Remove crappy, bloatware additions.
42
+ #++
43
+
44
+ module TableHelper
45
+
46
+ # The order by key.
47
+
48
+ setting :order_by_key, :default => '_order_by', :doc => 'The order key'
49
+
50
+ # The order by key.
51
+
52
+ setting :order_direction_key, :default => '_order_direction', :doc => 'The order direction key'
53
+
54
+ # [+options+]
55
+ # A hash of options.
56
+ #
57
+ # :id = id of the component.
58
+ # :class = class of the component
59
+ # :headers = an array of the header values
60
+ # :values = an array of arrays.
61
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
62
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
63
+ # :footers = an array of tfooter values
64
+
65
+ def table(options)
66
+ str = '<table'
67
+ str << %| id="#{options[:id]}"| if options[:id]
68
+ str << %| class="#{options[:class]}"| if options[:class]
69
+ str << '>'
70
+
71
+ str << table_rows(options)
72
+
73
+ str << '</table>'
74
+ end
75
+ alias_method :build_table, :table
76
+
77
+ # [+options+]
78
+ # A hash of options.
79
+ #
80
+ # :headers = an array of the header values
81
+ # :values = an array of arrays.
82
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
83
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
84
+ # :footers = an array of tfooter values
85
+
86
+ def table_rows(options)
87
+ # also accept :items, :rows
88
+ options[:values] = options[:values] || options[:items] || options[:rows]
89
+
90
+ str = ''
91
+ str << table_header(options) if options[:headers]
92
+ str << table_footer(options) if options[:footers]
93
+
94
+ items = options[:values]
95
+
96
+ row_state = 'odd' if options[:alternating_rows]
97
+
98
+ # when items is an array of arrays of arrays (meaning, several
99
+ # arrays deviding the table into several table parts (tbodys))
100
+
101
+ if create_tbody?(options)
102
+ for body in items
103
+ str << '<tbody>'
104
+
105
+ for row in body
106
+ str << '<tr'
107
+
108
+ if options[:alternating_rows]
109
+ str << %| class="row_#{row_state}"|
110
+ row_state = (row_state == "odd" ? "even" : "odd")
111
+ end
112
+
113
+ str << '>'
114
+
115
+ for value in row
116
+ str << %|<td>#{value}</td>|
117
+ end
118
+
119
+ str << '</tr>'
120
+ end
121
+
122
+ str << '</tbody>'
123
+ end
124
+ else
125
+ for row in items
126
+ str << '<tr'
127
+
128
+ if options[:alternating_rows]
129
+ str << %| class="row_#{row_state}"|
130
+ row_state = (row_state == "odd" ? "even" : "odd")
131
+ end
132
+
133
+ str << '>'
134
+
135
+ for value in row
136
+ str << %|<td>#{value}</td>|
137
+ end
138
+
139
+ str << '</tr>'
140
+ end
141
+ end
142
+
143
+ return str
144
+ end
145
+
146
+ private
147
+
148
+ # [+options+]
149
+ # A hash of options.
150
+ #
151
+ # :id = id of the component.
152
+ # :headers = an array of the header values
153
+ # :values = an array of arrays.
154
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
155
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
156
+ # :footers = an array of tfooter values
157
+
158
+ def table_header(options)
159
+ str = ''
160
+ str << '<thead>' if create_tbody?(options) || options[:footers]
161
+ str << '<tr>'
162
+
163
+ options[:headers].each_with_index do |header, index|
164
+ if (options[:order] && options[:order][:values] &&
165
+ options[:order][:values][index])
166
+ order_by = options[:order][:values][index]
167
+
168
+ asc_val = if options[:order][:asc_pic]
169
+ %|<img src="#{options[:order][:asc_pic]}" alt="asc" />|
170
+ else
171
+ '^'
172
+ end
173
+ desc_val = if options[:order][:desc_pic]
174
+ %|<img src="#{options[:order][:desc_pic]}" alt="desc" />|
175
+ else
176
+ 'v'
177
+ end
178
+
179
+ order_asc = "<a href='#{target_uri(order_by, 'ASC')}'>#{asc_val}</a>"
180
+ order_desc = "<a href='#{target_uri(order_by, 'DESC')}'>#{desc_val}</a>"
181
+
182
+ str << '<th><table width="100%" cellspacing="0" cellpadding="0"><tr>'
183
+
184
+ if options[:order][:left] || !options[:order][:right]
185
+ str << "<th>#{order_asc}<br />#{order_desc}</th>"
186
+ end
187
+
188
+ str << %|<th>#{header}</th>|
189
+
190
+ if options[:order][:right]
191
+ str << "<th>#{order_asc}<br />#{order_desc}</th>"
192
+ end
193
+
194
+ str << '</tr></table></th>'
195
+ else
196
+ str << %|<th>#{header}</th>|
197
+ end
198
+ end
199
+
200
+ str << '</tr>'
201
+ str << '</thead>' if create_tbody?(options) || options[:footers]
202
+
203
+ return str
204
+ end
205
+
206
+ # [+options+]
207
+ # A hash of options.
208
+ #
209
+ # :id = id of the component.
210
+ # :headers = an array of the header values
211
+ # :values = an array of arrays.
212
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
213
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
214
+ # :footers = an array of tfooter values
215
+
216
+ def table_footer(options)
217
+ str = '<tfoot><tr>'
218
+
219
+ for footer in options[:footers]
220
+ str << %|<td>#{footer}</td>|
221
+ end
222
+
223
+ str << '</tr></tfoot>'
224
+
225
+ return str
226
+ end
227
+
228
+ # Generate the target URI.
229
+
230
+ def target_uri(order_by, direction)
231
+ params = { TableHelper.order_by_key => order_by,
232
+ TableHelper.order_direction_key => direction }
233
+
234
+ return Glue::UriUtils.update_query_string(request.uri.to_s, params)
235
+ end
236
+
237
+ #--
238
+ # gmosx: Arrgh!! dangerous method, who added this?
239
+ #++
240
+
241
+ def create_tbody?(options)
242
+ options[:values][0][0].respond_to?(:to_ary)
243
+ end
244
+
245
+ end
246
+
247
+ end