nitro 0.28.0 → 0.29.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 (73) hide show
  1. data/CHANGELOG +382 -0
  2. data/ProjectInfo +4 -4
  3. data/README +1 -1
  4. data/doc/AUTHORS +15 -15
  5. data/doc/MIGRATION +13 -0
  6. data/doc/RELEASES +102 -0
  7. data/lib/glue/sweeper.rb +1 -1
  8. data/lib/nitro.rb +38 -9
  9. data/lib/nitro/adapter/acgi.rb +1 -3
  10. data/lib/nitro/adapter/cgi.rb +1 -1
  11. data/lib/nitro/adapter/fastcgi.rb +1 -3
  12. data/lib/nitro/adapter/mongrel.rb +8 -6
  13. data/lib/nitro/adapter/webrick.rb +1 -2
  14. data/lib/nitro/cgi.rb +1 -1
  15. data/lib/nitro/compiler.rb +21 -40
  16. data/lib/nitro/compiler/elements.rb +72 -32
  17. data/lib/nitro/compiler/errors.rb +92 -42
  18. data/lib/nitro/compiler/include.rb +47 -17
  19. data/lib/nitro/compiler/morphing.rb +1 -3
  20. data/lib/nitro/compiler/script.rb +2 -2
  21. data/lib/nitro/context.rb +36 -0
  22. data/lib/nitro/controller.rb +140 -31
  23. data/lib/nitro/dispatcher.rb +27 -28
  24. data/lib/nitro/element.rb +52 -15
  25. data/lib/nitro/flash.rb +44 -0
  26. data/lib/nitro/helper/buffer.rb +0 -2
  27. data/lib/nitro/helper/form.rb +2 -2
  28. data/lib/nitro/helper/form/controls.rb +14 -3
  29. data/lib/nitro/helper/pager.rb +1 -1
  30. data/lib/nitro/helper/table.rb +4 -3
  31. data/lib/nitro/helper/xml.rb +1 -1
  32. data/lib/nitro/part.rb +20 -0
  33. data/lib/nitro/render.rb +44 -5
  34. data/lib/nitro/router.rb +81 -0
  35. data/lib/nitro/scaffolding.rb +24 -23
  36. data/lib/nitro/server.rb +12 -1
  37. data/lib/nitro/server/runner.rb +12 -0
  38. data/lib/nitro/session.rb +3 -12
  39. data/lib/nitro/session/drb.rb +2 -5
  40. data/lib/nitro/session/file.rb +2 -2
  41. data/lib/nitro/session/memcached.rb +14 -0
  42. data/lib/nitro/session/memory.rb +3 -26
  43. data/lib/nitro/session/og.rb +1 -1
  44. data/lib/nitro/test/assertions.rb +1 -1
  45. data/lib/nitro/test/context.rb +8 -2
  46. data/lib/nitro/test/testcase.rb +16 -7
  47. data/proto/public/error.xhtml +58 -21
  48. data/proto/public/js/controls.js +60 -15
  49. data/proto/public/js/dragdrop.js +105 -16
  50. data/proto/public/js/effects.js +19 -12
  51. data/proto/public/js/scriptaculous.js +1 -1
  52. data/proto/public/js/slider.js +2 -2
  53. data/proto/public/js/unittest.js +29 -20
  54. data/proto/public/scaffold/edit.xhtml +1 -1
  55. data/proto/public/scaffold/index.xhtml +2 -2
  56. data/proto/public/scaffold/list.xhtml +2 -2
  57. data/proto/public/scaffold/new.xhtml +1 -1
  58. data/proto/public/scaffold/search.xhtml +1 -1
  59. data/src/part/admin/controller.rb +5 -5
  60. data/src/part/admin/template/index.xhtml +2 -2
  61. data/test/nitro/compiler/tc_compiler.rb +23 -0
  62. data/test/nitro/helper/tc_table.rb +35 -0
  63. data/test/nitro/tc_cgi.rb +1 -1
  64. data/test/nitro/tc_controller.rb +3 -3
  65. data/test/nitro/tc_controller_aspect.rb +2 -0
  66. data/test/nitro/tc_dispatcher.rb +10 -1
  67. data/test/nitro/tc_flash.rb +14 -0
  68. data/test/nitro/tc_router.rb +58 -0
  69. data/test/nitro/tc_session.rb +26 -9
  70. metadata +13 -12
  71. data/lib/nitro/routing.rb +0 -41
  72. data/test/nitro/caching/tc_stores.rb +0 -17
  73. data/test/nitro/tc_table.rb +0 -66
@@ -58,6 +58,50 @@ module Nitro
58
58
 
59
59
  (@dirty.keys - keys).each { |k| @dirty.delete k }
60
60
  end
61
+
62
+ # :section: Helpers
63
+
64
+ # Push a value in an array flash variable.
65
+ #
66
+ # === Example
67
+ #
68
+ # flash.push :errors, 'This is the first error'
69
+ # flash.push :errors, 'This is the second error'
70
+ #
71
+ # flash[:errors] # => []
72
+
73
+ def push(key, value)
74
+ if value.is_a? Array
75
+ (self[key] ||= []).concat(value)
76
+ else
77
+ (self[key] ||= []) << value
78
+ end
79
+ end
80
+
81
+ # Pop a value from an array flash variable.
82
+
83
+ def pop(key)
84
+ if arr = self[key]
85
+ if arr.is_a? Array
86
+ return arr.pop
87
+ else
88
+ return arr
89
+ end
90
+ end
91
+ return nil
92
+ end
93
+
94
+ # Join helper
95
+
96
+ def join(key, sep = ', ')
97
+ value = self[key]
98
+
99
+ if value.is_a? Array
100
+ return value.join(sep)
101
+ else
102
+ return value
103
+ end
104
+ end
61
105
 
62
106
  private
63
107
 
@@ -1,5 +1,3 @@
1
- require 'glue/attribute'
2
-
3
1
  module Nitro
4
2
 
5
3
  # The output buffering mixin. Provides php-style output
@@ -118,7 +118,7 @@ module FormHelper
118
118
  unless options[:all]
119
119
  next if prop.symbol == obj.class.primary_key.symbol or prop[:control] == :none or prop[:relation]
120
120
  end
121
- control = Control.fetch(obj, prop, options).render
121
+ control = Form::Control.fetch(obj, prop, options).render
122
122
  str << FormBuilder.element(prop, control)
123
123
  end
124
124
  end
@@ -130,7 +130,7 @@ module FormHelper
130
130
  unless options[:all]
131
131
  next if rel[:control] == :none
132
132
  end
133
- control = Control.fetch(obj, rel, options).render
133
+ control = Form::Control.fetch(obj, rel, options).render
134
134
  str << FormBuilder.element(rel, control)
135
135
  end
136
136
  end
@@ -4,6 +4,8 @@ module Nitro
4
4
 
5
5
  # :section: Property controls.
6
6
 
7
+ module Form
8
+
7
9
  # A Form control.
8
10
 
9
11
  class Control
@@ -174,7 +176,7 @@ class ArrayControl < Control
174
176
  else
175
177
  removable = values.size != 1 ? true : false
176
178
  values.each do |item|
177
- str << emit_array_element(:selected => item.pk)
179
+ str << emit_array_element()
178
180
  end
179
181
  end
180
182
  str << emit_container_end
@@ -182,7 +184,6 @@ class ArrayControl < Control
182
184
 
183
185
  def emit_array_element(options={})
184
186
  removable = options.fetch(:removable, true)
185
- selected = options.fetch(:selected, nil)
186
187
  %{
187
188
  <div>
188
189
  <input type="text" id="#{prop.symbol}_ctl" name="#{prop.symbol}[]" value="#{value}"#{emit_style}#{emit_disabled} />
@@ -192,6 +193,14 @@ class ArrayControl < Control
192
193
  }
193
194
  end
194
195
 
196
+ def emit_container_start
197
+ %{<div class="array_container">}
198
+ end
199
+
200
+ def emit_container_end
201
+ %{</div>}
202
+ end
203
+
195
204
  def emit_js
196
205
  %{
197
206
  <script type="text/javascript">
@@ -210,7 +219,7 @@ class ArrayControl < Control
210
219
  node.getElementsByTagName('input')[0].removeAttribute('disabled');
211
220
  if(container.lastChild==ctl) container.appendChild(node);
212
221
  else container.insertBefore(node, ctl.nextSibling);
213
- if(container.childNodes.length>1) container.getElementsByTagName('input')[0].disabled='';
222
+ if(container.childNodes.length>1) container.getElementsByTagName('input')[1].disabled='';
214
223
  }
215
224
  </script>
216
225
  }
@@ -373,5 +382,7 @@ end
373
382
 
374
383
  end
375
384
 
385
+ end
386
+
376
387
  # * George Moschovitis <gm@navel.gr>
377
388
  # * Chris Farmiloe <chris.farmiloe@farmiloe.com>
@@ -233,7 +233,7 @@ private
233
233
 
234
234
  def target_uri(page)
235
235
  params = { @key => page }
236
- return UriUtils.update_query_string(@request.uri.to_s, params)
236
+ return Glue::UriUtils.update_query_string(@request.uri.to_s, params)
237
237
  end
238
238
 
239
239
  end
@@ -53,6 +53,7 @@ module TableHelper
53
53
  # A hash of options.
54
54
  #
55
55
  # :id = id of the component.
56
+ # :class = class of the component
56
57
  # :headers = an array of the header values
57
58
  # :values = an array of arrays.
58
59
  # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
@@ -62,6 +63,7 @@ module TableHelper
62
63
  def table(options)
63
64
  str = '<table'
64
65
  str << %| id="#{options[:id]}"| if options[:id]
66
+ str << %| class="#{options[:class]}"| if options[:class]
65
67
  str << '>'
66
68
 
67
69
  str << table_rows(options)
@@ -73,7 +75,6 @@ module TableHelper
73
75
  # [+options+]
74
76
  # A hash of options.
75
77
  #
76
- # :id = id of the component.
77
78
  # :headers = an array of the header values
78
79
  # :values = an array of arrays.
79
80
  # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
@@ -85,7 +86,7 @@ module TableHelper
85
86
  options[:values] = options[:values] || options[:items] || options[:rows]
86
87
 
87
88
  str = ''
88
- str << table_header(options)
89
+ str << table_header(options) if options[:headers]
89
90
  str << table_footer(options) if options[:footers]
90
91
 
91
92
  items = options[:values]
@@ -228,7 +229,7 @@ module TableHelper
228
229
  params = { TableHelper.order_by_key => order_by,
229
230
  TableHelper.order_direction_key => direction }
230
231
 
231
- return UriUtils.update_query_string(request.uri.to_s, params)
232
+ return Glue::UriUtils.update_query_string(request.uri.to_s, params)
232
233
  end
233
234
 
234
235
  def create_tbody?(options)
@@ -98,7 +98,7 @@ end
98
98
  # functionality. Utilizes duck typing to redirect
99
99
  # output to a target buffer.
100
100
 
101
- class XmlBuilder
101
+ class Glue::XmlBuilder
102
102
  include XmlHelper
103
103
 
104
104
  # The target receives the generated xml,
@@ -0,0 +1,20 @@
1
+ module Nitro
2
+
3
+ # A part is a module of reusable functionality encapsulated as
4
+ # a mini site/app. You can require (include) multiple parts in
5
+ # your application. A part is in essence a high level component.
6
+
7
+ class Part
8
+
9
+ # Require (include) a part in the current application.
10
+
11
+ def self.require(name)
12
+ Logger.debug "Requiring part '#{name}'."
13
+ Kernel.require "part/#{name}/run.rb"
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
20
+ # * George Moschovitis <gm@navel.gr>
@@ -7,7 +7,6 @@ require 'facet/string/blank'
7
7
  require 'glue/attribute'
8
8
  require 'glue/settings'
9
9
  require 'glue/template'
10
- require 'glue/builder'
11
10
  require 'glue/builder/xml'
12
11
 
13
12
  require 'nitro/helper/xhtml'
@@ -157,6 +156,8 @@ private
157
156
  @out.flush if @out.is_a?(IO)
158
157
  end
159
158
 
159
+ # :section: Redirection methods.
160
+
160
161
  # Send a redirect response.
161
162
  #
162
163
  # If the url starts with '/' it is considered absolute, else
@@ -184,6 +185,8 @@ private
184
185
  redirect("#{@context.referer}#{postfix}", status)
185
186
  end
186
187
  alias_method :redirect_to_referer, :redirect_referer
188
+ alias_method :redirect_referrer, :redirect_referer
189
+ alias_method :redirect_to_referrer, :redirect_referer
187
190
 
188
191
  # Redirect to home.
189
192
 
@@ -192,6 +195,42 @@ private
192
195
  end
193
196
  alias_method :redirect_to_home, :redirect_home
194
197
 
198
+ # :section: Seaside style call/answer methods.
199
+
200
+ # Call redirects to the given url but push the original
201
+ # url in a callstack, so that the target can return by
202
+ # executing answer.
203
+ #
204
+ # === Example
205
+ #
206
+ # caller:
207
+ # color, type = call('utils/select_color')
208
+ #
209
+ # target:
210
+ # answer(color, type)
211
+ #--
212
+ # FIXME: dont use yet, you have to encode the branch to
213
+ # make this safe for use.
214
+ #++
215
+
216
+ def call(url, status = 303)
217
+ (session[:CALL_STACK] ||= {}) << request.uri
218
+ redirect(url, status)
219
+ end
220
+
221
+ # Returns from a call by poping the callstack.
222
+ #--
223
+ # FIXME: don't use yet.
224
+ #++
225
+
226
+ def answer(index = 0, status = 303)
227
+ if stack = session[:CALL_STACK] and not stack.empty?
228
+ redirect(stack.pop, status)
229
+ else
230
+ raise 'Cannot answer, call stack is empty'
231
+ end
232
+ end
233
+
195
234
  # Log a rendering error.
196
235
 
197
236
  def log_error(error, path, full = true)
@@ -226,16 +265,16 @@ private
226
265
  def render_template(filename)
227
266
  filename = "#{filename}.xhtml" unless filename =~ /\.xhtml$/
228
267
  template = File.read("#{template_root}/#{filename}")
229
- Template.process_template(template, '@out', binding)
268
+ Glue::Template.process_template(template, '@out', binding)
230
269
  end
231
270
 
232
271
  # Access the programmatic renderer (builder).
233
272
 
234
273
  def build(&block)
235
274
  if block.arity == 1
236
- yield XmlBuilder.new(@out)
275
+ yield Glue::XmlBuilder.new(@out)
237
276
  else
238
- XmlBuilder.new(@out).instance_eval(&block)
277
+ Glue::XmlBuilder.new(@out).instance_eval(&block)
239
278
  end
240
279
  end
241
280
 
@@ -243,7 +282,7 @@ private
243
282
  # output buffer.
244
283
 
245
284
  def builder
246
- XmlBuilder.new(@out)
285
+ Glue::XmlBuilder.new(@out)
247
286
  end
248
287
 
249
288
  # A Helper class to access rendering mixins. Useful to avoid
@@ -0,0 +1,81 @@
1
+ module Nitro
2
+
3
+ # Router mixin. Typically used to generate 'nice' urls.
4
+ # Nice urls apart from looking more beautiful are considered (?)
5
+ # more Search Engine friendly.
6
+ #
7
+ # However, due to the power of Nitro's intelligent dispatching
8
+ # mechanism, routing is almost never used! It is only needed
9
+ # for really special urls.
10
+ #
11
+ # === Example
12
+ #
13
+ # r.add_route(%r{rewritten/url/(.*)}, :controller => IdController, :action => :register, :param => :name)
14
+ # r.add_route(%r{another/zelo/(.*)/(.*)}, :controller => AdminController, :action => :kick, :params => [:name, :age])
15
+ # r.add_route(%r{cool/(.*)_(.*).html}, :controller => AdminController, :action => :long, :params => [:name, :age])
16
+
17
+ module Router
18
+
19
+ # Strip the beginning of the path, used by cgi adapter.
20
+
21
+ setting :strip_path, :default => nil, :doc => 'Strip the beginning of the path, used by cgi adapter'
22
+
23
+ # The route table maps 'nice URLs' to real URLs that
24
+ # can be handled by the Dispatcher.
25
+
26
+ attr_accessor :routes
27
+
28
+ # Decodes a url to a [controller, action, params] tupple.
29
+ # Returns false if no decoding is possible.
30
+
31
+ def decode_route(url)
32
+ for rule, options in @routes
33
+ if md = url.match(rule)
34
+ params = nil
35
+ if param_names = options[:params] || options[:param]
36
+ param_names = [ param_names ] unless param_names.is_a?(Array)
37
+ params = {}
38
+ md.captures.each_with_index do |val, idx|
39
+ params[param_names[idx].to_s] = val
40
+ end
41
+ end
42
+ return options[:controller], options[:action], params
43
+ end
44
+ end
45
+ return false
46
+ end
47
+ alias_method :route, :decode_route
48
+
49
+ # Encodes a [controller, action, params] tupple into a url.
50
+ # Returns false if no encoding is possible.
51
+
52
+ def encode_route(controller, action, *params)
53
+ if route = @routes.find { |r| (r.last[:controller] == controller) and (r.last[:action] == action) }
54
+ rule, options = *route
55
+ url = rule.source
56
+
57
+ (params.size / 2).times do |i|
58
+ val = params[i + i + 1]
59
+ url.sub!(/\(.*?\)/, val.to_s)
60
+ end
61
+
62
+ return url
63
+ end
64
+ return false
65
+ end
66
+
67
+ # Add a route to the routing table.
68
+
69
+ def add_route(rule, options)
70
+ (@routes ||= []) << [rule, options]
71
+ end
72
+ alias_method :<<, :add_route
73
+
74
+ def add_routes
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ # * George Moschovitis <gm@navel.gr>
@@ -33,12 +33,16 @@ module Scaffolding
33
33
  base.extend(ClassMethods)
34
34
  end
35
35
 
36
- def self.class_to_name(klass)
37
- klass.to_s.demodulize.underscore.downcase
36
+ def self.class_to_method(klass)
37
+ klass.name.underscore.gsub('::','__').downcase
38
38
  end
39
39
 
40
40
  def self.class_to_list(klass)
41
- klass.to_s.demodulize.underscore.downcase.plural
41
+ class_to_method(klass).plural
42
+ end
43
+
44
+ def self.class_to_path(klass)
45
+ klass.name.underscore.gsub('::','/').downcase
42
46
  end
43
47
 
44
48
  #--
@@ -66,10 +70,6 @@ module Scaffolding
66
70
  @base__ = "#{@base}__" if @base
67
71
  end
68
72
 
69
- def class_to_name(klass)
70
- klass.to_s.demodulize.underscore.downcase
71
- end
72
-
73
73
  #--
74
74
  # A helper that defines a class method.
75
75
  #++
@@ -160,28 +160,28 @@ module Scaffolding
160
160
 
161
161
  def scaffold_controller
162
162
  define_controller_action 'index', %{
163
- #{Aspects.gen_advice_code(:scaffold_index, @controller.advices, :pre)}
163
+ #{Glue::Aspects.gen_advice_code(:scaffold_index, @controller.advices, :pre)}
164
164
  @list, @pager = paginate(@klass, :per_page => Scaffolding.per_page)
165
165
  }
166
166
 
167
167
  define_controller_action 'list', %{
168
- #{Aspects.gen_advice_code(:scaffold_list, @controller.advices, :pre)}
168
+ #{Glue::Aspects.gen_advice_code(:scaffold_list, @controller.advices, :pre)}
169
169
  @list, @pager = paginate(@klass, :per_page => Scaffolding.per_page)
170
170
  }
171
171
 
172
172
  define_controller_action 'view(oid)', %{
173
- #{Aspects.gen_advice_code(:scaffold_view, @controller.advices, :pre)}
173
+ #{Glue::Aspects.gen_advice_code(:scaffold_view, @controller.advices, :pre)}
174
174
  @obj = @klass[oid]
175
175
  }
176
176
 
177
177
  define_controller_action 'new(all = false)', %{
178
- #{Aspects.gen_advice_code(:scaffold_new, @controller.advices, :pre)}
178
+ #{Glue::Aspects.gen_advice_code(:scaffold_new, @controller.advices, :pre)}
179
179
  @obj = @klass.new
180
180
  @all = all
181
181
  }
182
182
 
183
183
  define_controller_action 'edit(oid = nil, all = false)', %{
184
- #{Aspects.gen_advice_code(:scaffold_edit, @controller.advices, :pre)}
184
+ #{Glue::Aspects.gen_advice_code(:scaffold_edit, @controller.advices, :pre)}
185
185
  @obj = @klass[oid]
186
186
  @all = all
187
187
  }
@@ -195,18 +195,19 @@ module Scaffolding
195
195
  else
196
196
  obj = request.fill(@klass.create, :assign_relations => true, :preprocess => true)
197
197
  end
198
- #{Aspects.gen_advice_code(:scaffold_save, @controller.advices, :pre)}
198
+ #{Glue::Aspects.gen_advice_code(:scaffold_save, @controller.advices, :pre)}
199
199
  unless obj.valid?
200
200
  flash[:ERRORS] = obj.errors
201
201
  redirect_to_referer
202
202
  end
203
203
  obj.save
204
- #{Aspects.gen_advice_code(:scaffold_save, @controller.advices, :post)}
204
+ oid = obj.pk
205
+ #{Glue::Aspects.gen_advice_code(:scaffold_save, @controller.advices, :post)}
205
206
  redirect '#{action_path(:list)}'
206
207
  }
207
208
 
208
209
  define_controller_action 'search(query)', %{
209
- #{Aspects.gen_advice_code(:scaffold_search, @controller.advices, :pre)}
210
+ #{Glue::Aspects.gen_advice_code(:scaffold_search, @controller.advices, :pre)}
210
211
  @query = query
211
212
  if @klass.respond_to? :search
212
213
  @list = #@klass.search(query)
@@ -214,9 +215,9 @@ module Scaffolding
214
215
  }
215
216
 
216
217
  define_controller_action 'delete(oid)', %{
217
- #{Aspects.gen_advice_code(:scaffold_delete, @controller.advices, :pre)}
218
+ #{Glue::Aspects.gen_advice_code(:scaffold_delete, @controller.advices, :pre)}
218
219
  @klass.delete(oid)
219
- #{Aspects.gen_advice_code(:scaffold_delete, @controller.advices, :post)}
220
+ #{Glue::Aspects.gen_advice_code(:scaffold_delete, @controller.advices, :post)}
220
221
  redirect_to_referer
221
222
  }
222
223
 
@@ -225,18 +226,18 @@ module Scaffolding
225
226
  for rel in @klass.relations
226
227
  define_controller_action "remove_#{rel.target_singular_name}(oid, rid)", %{
227
228
  obj = @klass[oid]
228
- #{Aspects.gen_advice_code(:scaffold_remove_relation, @controller.advices, :pre)}
229
+ #{Glue::Aspects.gen_advice_code(:scaffold_remove_relation, @controller.advices, :pre)}
229
230
  rob = #{rel.target_class}[rid]
230
231
  obj.#{rel.name}.remove(rob)
231
- #{Aspects.gen_advice_code(:scaffold_remove_relation, @controller.advices, :post)}
232
+ #{Glue::Aspects.gen_advice_code(:scaffold_remove_relation, @controller.advices, :post)}
232
233
  redirect_to_referer
233
234
  }
234
235
  define_controller_action "delete_#{rel.target_singular_name}(oid, rid)", %{
235
- #{Aspects.gen_advice_code(:scaffold_delete_relation, @controller.advices, :pre)}
236
+ #{Glue::Aspects.gen_advice_code(:scaffold_delete_relation, @controller.advices, :pre)}
236
237
  obj = @klass[oid]
237
238
  rob = #{rel.target_class}[rid]
238
239
  obj.#{rel.name}.delete(rob)
239
- #{Aspects.gen_advice_code(:scaffold_delete_relation, @controller.advices, :post)}
240
+ #{Glue::Aspects.gen_advice_code(:scaffold_delete_relation, @controller.advices, :post)}
240
241
  redirect_to_referer
241
242
  }
242
243
  end
@@ -298,9 +299,9 @@ module Scaffolding
298
299
  #++
299
300
 
300
301
  def scaffold(klass, options = {})
301
- o = {
302
+ o = scaffolding_classes[klass] || {
302
303
  :pk => 'oid',
303
- :name => Scaffolding.class_to_name(klass),
304
+ :name => Scaffolding.class_to_method(klass),
304
305
  :plural_name => Scaffolding.class_to_list(klass),
305
306
  :mount => true
306
307
  }