spiderfw 0.5.10 → 0.5.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG +6 -0
  2. data/Rakefile +4 -1
  3. data/VERSION +1 -0
  4. data/apps/core/auth/controllers/login_controller.rb +10 -1
  5. data/apps/core/auth/controllers/mixins/auth_helper.rb +4 -2
  6. data/apps/core/auth/views/login.shtml +1 -1
  7. data/apps/core/components/_init.rb +1 -1
  8. data/apps/core/components/public/css/spider.css +0 -1
  9. data/apps/core/components/public/js/jquery/plugins/jquery.form.js +2 -1
  10. data/apps/core/components/public/js/list.js +14 -126
  11. data/apps/core/components/public/js/plugins/plugin.js +7 -0
  12. data/apps/core/components/public/js/plugins/sortable.js +124 -0
  13. data/apps/core/components/public/js/spider.js +212 -51
  14. data/apps/core/components/widgets/list/list.shtml +1 -0
  15. data/apps/core/components/widgets/table/table.rb +1 -1
  16. data/apps/core/components/widgets/table/table.shtml +3 -3
  17. data/apps/core/components/widgets/tabs/tabs.rb +70 -22
  18. data/apps/core/components/widgets/tabs/tabs.shtml +8 -2
  19. data/apps/core/forms/widgets/inputs/file_input/file_input.rb +4 -1
  20. data/data/locale/it/LC_MESSAGES/cms.mo +0 -0
  21. data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
  22. data/data/locale/it/LC_MESSAGES/spider_files.mo +0 -0
  23. data/data/locale/it/LC_MESSAGES/spider_images.mo +0 -0
  24. data/lib/spiderfw.rb +3 -1
  25. data/lib/spiderfw/config/configuration.rb +3 -1
  26. data/lib/spiderfw/controller/controller.rb +8 -0
  27. data/lib/spiderfw/controller/mixins/static_content.rb +14 -2
  28. data/lib/spiderfw/controller/mixins/visual.rb +25 -25
  29. data/lib/spiderfw/controller/page_controller.rb +3 -0
  30. data/lib/spiderfw/controller/request.rb +4 -1
  31. data/lib/spiderfw/controller/session.rb +7 -6
  32. data/lib/spiderfw/create.rb +10 -1
  33. data/lib/spiderfw/model/base_model.rb +104 -57
  34. data/lib/spiderfw/model/condition.rb +9 -1
  35. data/lib/spiderfw/model/data_type.rb +15 -0
  36. data/lib/spiderfw/model/datatypes/uuid.rb +5 -0
  37. data/lib/spiderfw/model/extended_models/managed.rb +2 -2
  38. data/lib/spiderfw/model/mappers/db_mapper.rb +46 -21
  39. data/lib/spiderfw/model/mappers/mapper.rb +34 -8
  40. data/lib/spiderfw/model/mixins/list.rb +2 -0
  41. data/lib/spiderfw/model/mixins/tree.rb +2 -1
  42. data/lib/spiderfw/model/mixins/versioned.rb +12 -9
  43. data/lib/spiderfw/model/model.rb +72 -0
  44. data/lib/spiderfw/model/query_set.rb +7 -0
  45. data/lib/spiderfw/model/storage/base_storage.rb +5 -1
  46. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +5 -2
  47. data/lib/spiderfw/model/storage/db/adapters/oci8.rb +9 -3
  48. data/lib/spiderfw/model/storage/db/db_storage.rb +8 -5
  49. data/lib/spiderfw/model/sync.rb +12 -6
  50. data/lib/spiderfw/requires.rb +1 -0
  51. data/lib/spiderfw/templates/blocks/parent_context.rb +26 -0
  52. data/lib/spiderfw/templates/blocks/widget.rb +17 -7
  53. data/lib/spiderfw/templates/layout.rb +11 -1
  54. data/lib/spiderfw/templates/template.rb +36 -3
  55. data/lib/spiderfw/templates/template_blocks.rb +36 -26
  56. data/lib/spiderfw/utils/annotations.rb +2 -1
  57. data/lib/spiderfw/utils/thread_out.rb +15 -0
  58. data/lib/spiderfw/widget/widget.rb +58 -16
  59. data/spider.gemspec +3 -0
  60. metadata +143 -48
@@ -4,14 +4,9 @@ module Spider; module TemplateBlocks
4
4
 
5
5
  class Widget < Block
6
6
 
7
- def compile(options={})
8
- klass = Spider::Template.get_registered_class(@el.name)
7
+ def self.attributes_to_init_params(attributes)
9
8
  init_params = []
10
- id = @el.get_attribute('id')
11
- raise TemplateCompileError, "Widget #{@el.name} does not have an id" unless id
12
- template_attr = @el.get_attribute('template')
13
- @el.remove_attribute('template')
14
- @el.attributes.to_hash.each do |key, val|
9
+ attributes.each do |key, val|
15
10
  if (!val.empty? && val[0].chr == '@')
16
11
  sval = var_to_scene(val, 'scene')
17
12
  elsif (!val.empty? && val[0].chr == '$')
@@ -23,6 +18,21 @@ module Spider; module TemplateBlocks
23
18
  init_key = "\"#{init_key}\"" unless key =~ /^[\w\d]+$/
24
19
  init_params << ":#{init_key} => #{sval}"
25
20
  end
21
+ init_params
22
+ end
23
+
24
+ def compile(options={})
25
+ klass = Spider::Template.get_registered_class(@el.name)
26
+ init_params = []
27
+ id = @el.get_attribute('id')
28
+ raise TemplateCompileError, "Widget #{@el.name} does not have an id" unless id
29
+ template_attr = @el.get_attribute('template')
30
+ @el.remove_attribute('template')
31
+ if klass.respond_to?(:compile_block)
32
+ init, c = klass.compile_block(@el, id, @el.attributes.to_hash, options)
33
+ return CompiledBlock.new(init, c)
34
+ end
35
+ init_params = self.class.attributes_to_init_params(@el.attributes.to_hash)
26
36
 
27
37
  html = ""
28
38
  @el.each_child do |ch|
@@ -8,6 +8,15 @@ module Spider
8
8
  super
9
9
  @template = @template.is_a?(Template) ? @template : Template.new(@template)
10
10
  @template.init(scene) unless @template.init_done?
11
+
12
+ end
13
+
14
+ def render(*args)
15
+ prepare_assets unless @assets_prepared
16
+ super
17
+ end
18
+
19
+ def prepare_assets
11
20
  @template_assets = {:css => [], :js => []}
12
21
  seen = {}
13
22
  all_assets.each do |res|
@@ -17,7 +26,8 @@ module Spider
17
26
  @template_assets[res[:type].to_sym] << res[:src]
18
27
  end
19
28
  @content[:yield_to] = @template
20
- scene.assets = @template_assets
29
+ @scene.assets = @template_assets
30
+ @assets_prepared = true
21
31
  end
22
32
 
23
33
  @@named_layouts = {}
@@ -243,6 +243,7 @@ module Spider
243
243
  else
244
244
  owner_class = (@owner ? @owner.class : @owner_class )
245
245
  end
246
+ raise "Asset type not given for #{src}" unless type
246
247
  res = Spider.find_resource(type.to_sym, src, @path, [owner_class, @definer_class])
247
248
  controller = nil
248
249
  if (res && res.definer)
@@ -252,6 +253,10 @@ module Spider
252
253
  end
253
254
  ass[:path] = res.path if res
254
255
  if controller.respond_to?(:pub_url)
256
+ if src[0].chr == '/'
257
+ # strips the app path from the src. FIXME: should probably be done somewhere else
258
+ src = src[(2+controller.app.relative_path.length)..-1]
259
+ end
255
260
  ass[:src] = controller.pub_url + '/' + src
256
261
  else
257
262
  ass[:src] = src
@@ -274,6 +279,8 @@ module Spider
274
279
  doc = open(path){ |f| Hpricot.XML(f) }
275
280
  root = doc.root
276
281
  overrides = []
282
+ orig_overrides = @overrides
283
+ @overrides = []
277
284
  if root.children
278
285
  override_tags.each do |tag|
279
286
  overrides += root.children_of_type('tpl:'+tag)
@@ -282,7 +289,11 @@ module Spider
282
289
  overrides.each{ |o| o.set_attribute('class', 'to_delete') }
283
290
  root.search('.to_delete').remove
284
291
  add_overrides overrides
292
+ @overrides += orig_overrides
285
293
  if (root.name == 'tpl:extend')
294
+
295
+ orig_overrides = @overrides
296
+ @overrides = []
286
297
  ext_src = root.get_attribute('src')
287
298
  ext_app = root.get_attribute('app')
288
299
  ext_widget = root.get_attribute('widget')
@@ -290,6 +301,7 @@ module Spider
290
301
  ext_widget = Spider::Template.get_registered_class(ext_widget)
291
302
  ext_src ||= ext_widget.default_template
292
303
  ext_owner = ext_widget
304
+ ext_app = ext_widget.app
293
305
  elsif ext_app
294
306
  ext_app = Spider.apps_by_path[ext_app]
295
307
  ext_owner = ext_widget
@@ -303,6 +315,13 @@ module Spider
303
315
  @dependencies << ext
304
316
  tpl = Template.new(ext)
305
317
  root = get_el(ext)
318
+ root.children_of_type('tpl:asset').each do |ass|
319
+ ass_src = ass.get_attribute('src')
320
+ unless ass_src[0].chr == '/'
321
+ ass.set_attribute('src', "/#{ext_app.relative_path}/#{ass_src}")
322
+ end
323
+ end
324
+ @overrides += orig_overrides
306
325
  if (assets && !assets.empty?)
307
326
  assets.each do |ass|
308
327
  root.innerHTML += ass.to_html
@@ -377,6 +396,7 @@ module Spider
377
396
  apply_widget_proc(widget, wp)
378
397
  end
379
398
  end
399
+ widget
380
400
  end
381
401
 
382
402
  def find_widget(path)
@@ -410,7 +430,7 @@ module Spider
410
430
  # Calls the run method on all widget instances.
411
431
  def run_widgets
412
432
  @widgets.each do |id, w|
413
- w.run unless w.did_run?
433
+ w.run if w.run? && !w.did_run?
414
434
  end
415
435
 
416
436
  end
@@ -450,12 +470,22 @@ module Spider
450
470
  # t.join
451
471
  # else
452
472
  scene.instance_eval("def __run_template\n"+@compiled.run_code+"end\n", @compiled.cache_path+'/run.rb', 0)
453
- scene.__run_template do |widget|
454
- @content[widget].render if @content[widget]
473
+ scene.__run_template do |yielded|
474
+ if yielded == :_parent
475
+ @owner.parent.template.run_block
476
+ else
477
+ @content[yielded].render if @content[yielded]
478
+ end
455
479
  end
456
480
  # end
457
481
  end
458
482
 
483
+ def run_block
484
+ @scene.__run_block do |yielded, block|
485
+ @content[yielded].render if @content[yielded]
486
+ end
487
+ end
488
+
459
489
  # Alias for #render.
460
490
  def run
461
491
  render(@scene)
@@ -506,6 +536,9 @@ module Spider
506
536
 
507
537
  # Applies an override to an (Hpricot) element.
508
538
  def apply_override(el, override)
539
+ if override.is_a?(Proc)
540
+ return override.call(el)
541
+ end
509
542
  search_string = override.get_attribute('search')
510
543
  override.name = 'tpl:override-content' if override.name == 'tpl:inline-override'
511
544
  if (search_string)
@@ -28,10 +28,12 @@ module Spider
28
28
  block = :Run
29
29
  elsif el.name == 'sp:yield'
30
30
  block = :Yield
31
- elsif el.name == 'sp:pass' || el.name == 'sp:template'
31
+ elsif el.name == 'sp:pass' || el.name == 'tpl:pass' || el.name == 'sp:template'
32
32
  block = :Pass
33
33
  elsif el.name == 'sp:debugger'
34
34
  block = :Debugger
35
+ elsif el.name == 'sp:parent-context'
36
+ block = :ParentContext
35
37
  elsif Spider::Template.registered?(el.name)
36
38
  klass = Spider::Template.get_registered_class(el.name)
37
39
  if klass < ::Spider::Widget
@@ -47,7 +49,34 @@ module Spider
47
49
  return block
48
50
  end
49
51
 
52
+ def self.parse_content(el, allowed_blocks=nil, template=nil)
53
+ content_blocks = []
54
+ last_block = nil
55
+ el.each_child do |ch|
56
+ #Spider.logger.debug "TRAVERSING CHILD #{ch}"
57
+ # Gives the preceding block the chance to "eat" the next elements
58
+ next if (last_block && last_block.get_following(ch))
59
+ last_block = TemplateBlocks.parse_element(ch, allowed_blocks, template)
60
+ content_blocks << last_block if (last_block)
61
+ end
62
+ return content_blocks
63
+ end
64
+
65
+ def self.compile_content(el, c='', init='', options={})
66
+ c ||= ""
67
+ init ||= ""
68
+ blocks = self.parse_content(el, options[:allowed_blocks], options[:template])
69
+ blocks.each do |block|
70
+ compiled = block.compile(options)
71
+ next unless compiled
72
+ c += compiled.run_code if (compiled.run_code)
73
+ init += compiled.init_code if (compiled.init_code)
74
+ end
75
+ return [c, init]
76
+ end
77
+
50
78
  class Block
79
+ attr_reader :el, :template, :allowed_blocks
51
80
 
52
81
  def initialize(el, template=nil, allowed_blocks=nil)
53
82
  @el = el
@@ -57,34 +86,13 @@ module Spider
57
86
  end
58
87
 
59
88
  def parse_content(el)
60
- content_blocks = []
61
- last_block = nil
62
- el.each_child do |ch|
63
- #Spider.logger.debug "TRAVERSING CHILD #{ch}"
64
- # Gives the preceding block the chance to "eat" the next elements
65
- next if (last_block && last_block.get_following(ch))
66
- last_block = TemplateBlocks.parse_element(ch, @allowed_blocks, @template)
67
- content_blocks << last_block if (last_block)
68
- end
69
- return content_blocks
89
+ TemplateBlocks.parse_content(el, @allowed_blocks, @template)
70
90
  end
71
91
 
72
92
  def compile_content(c='', init='', options={})
73
- c ||= ""
74
- init ||= ""
75
- blocks = parse_content(@el)
76
- blocks.each do |block|
77
- compiled = block.compile(options)
78
- next unless compiled
79
- # if (compiled.run_code =~ /nil/)
80
- # Spider::Logger.debug("NIL BLOCK")
81
- # Spider::Logger.debug(block)
82
- # Spider::Logger.debug(compiled.run_code)
83
- # end
84
- c += compiled.run_code if (compiled.run_code)
85
- init += compiled.init_code if (compiled.init_code)
86
- end
87
- return [c, init]
93
+ options[:allowed_blocks] ||= @allowed_blocks
94
+ options[:template] ||= @template
95
+ TemplateBlocks.compile_content(@el, c, init, options)
88
96
  end
89
97
 
90
98
  def get_following(el)
@@ -206,3 +214,5 @@ require 'spiderfw/templates/blocks/tag'
206
214
  require 'spiderfw/templates/blocks/widget'
207
215
  require 'spiderfw/templates/blocks/run'
208
216
  require 'spiderfw/templates/blocks/debugger'
217
+ require 'spiderfw/templates/blocks/parent_context'
218
+
@@ -109,6 +109,7 @@ module Annotations
109
109
  if (@annotations)
110
110
  @annotations.each do |method, vals|
111
111
  vals.each do |k, args|
112
+ args = [args] unless args.is_a?(Array)
112
113
  subclass.annotate(method, k, *args)
113
114
  end
114
115
  end
@@ -161,7 +162,7 @@ module Annotations
161
162
  end
162
163
  end
163
164
 
164
- # Defines an annotation. The given block will be called whenever the name annotation
165
+ # Defines an annotation. The given block will be called whenever the "name" annotation
165
166
  # is encountered; it will be passed the current Class, the annotated Method, and the annotation arguments.
166
167
  def define_annotation(name, &proc)
167
168
  @defined_annotations ||= {}
@@ -21,4 +21,19 @@ module ThreadOut #:nodoc:
21
21
  self.write(stuff)
22
22
  end
23
23
 
24
+ def self.output_to(io)
25
+ if block_given?
26
+ prev_out = Thread.current[:stdout]
27
+ Thread.current[:stdout] = io
28
+ yield
29
+ Thread.current[:stdout] = prev_out
30
+ else
31
+ Thread.current[:stdout] = io
32
+ end
33
+ end
34
+
35
+ def output_to(io, &proc)
36
+ self.class.output_to(io, &proc)
37
+ end
38
+
24
39
  end
@@ -26,6 +26,7 @@ module Spider
26
26
  def inherited(subclass)
27
27
  subclass.instance_variable_set(:@attributes, attributes.clone)
28
28
  subclass.instance_variable_set(:@scene_attributes, @scene_attributes.clone) if @scene_attributes
29
+ super
29
30
  end
30
31
 
31
32
  def attribute(name, params={})
@@ -56,6 +57,11 @@ module Spider
56
57
  attr_reader(name)
57
58
  end
58
59
 
60
+ def s_attribute(name, params={})
61
+ attribute(name, params)
62
+ attr_to_scene(name)
63
+ end
64
+
59
65
  def i_attr_accessor(name, params={})
60
66
  params[:instance_attr] = true
61
67
  i_attribute(name, params)
@@ -209,9 +215,14 @@ module Spider
209
215
  locale = @request.locale.language
210
216
  include_js = [
211
217
  '/js/jquery/jquery-1.4.2.js', '/js/inheritance.js', '/js/spider.js', '/js/jquery/plugins/jquery.query-2.1.6.js',
212
- '/js/jquery/jquery-ui/development-bundle/ui/jquery-ui-1.7.2.custom.js', #'/js/jquery/jquery-ui/development-bundle/ui/jquery-ui-1.7.2.custom.min.js'
213
- "/js/jquery/jquery-ui/development-bundle/ui/i18n/ui.datepicker-#{locale}.js", '/js/jquery/plugins/jquery.form.js'
218
+ '/js/jquery/plugins/jquery.form.js',
219
+ '/js/plugins/plugin.js'
214
220
  ]
221
+ # include_js << [
222
+ # '/js/jquery/jquery-ui/development-bundle/ui/jquery-ui-1.7.2.custom.js',
223
+ # #'/js/jquery/jquery-ui/development-bundle/ui/jquery-ui-1.7.2.custom.min.js',
224
+ # "/js/jquery/jquery-ui/development-bundle/ui/i18n/ui.datepicker-#{locale}.js"
225
+ # ]
215
226
  include_css = [
216
227
  '/css/spider.css', '/js/jquery/jquery-ui/css/smoothness/jquery-ui-1.7.2.custom.css',
217
228
  ]
@@ -264,19 +275,27 @@ module Spider
264
275
  end
265
276
 
266
277
  def widget_before(action='')
267
- return unless active?
268
278
  Spider.logger.debug("Widget #{self} widget_before(#{action})")
269
279
  widget_init(action)
270
280
  prepare
281
+ prepare_scene(@scene)
271
282
  @before_done = true
272
283
  end
273
284
 
274
285
 
275
286
  def active?
287
+
276
288
  return @active unless @active.nil?
289
+ return @active = true if @is_target
290
+ return @active = false if attributes[:"sp:target-only"] == "true"
277
291
  @active = (!@request.params['_wt'] || @target_mode)
278
292
  end
279
293
 
294
+ def active=(val)
295
+
296
+ @active = val
297
+ end
298
+
280
299
  def before_done?
281
300
  @before_done
282
301
  end
@@ -332,7 +351,7 @@ module Spider
332
351
  end
333
352
 
334
353
  # Instantiates this widget's own subwidgets.
335
- def init_widgets
354
+ def init_widgets(template=@template)
336
355
  if (self.class.scene_attributes)
337
356
  self.class.scene_attributes.each do |name|
338
357
  @scene[name] = instance_variable_get("@#{name}")
@@ -340,8 +359,8 @@ module Spider
340
359
  end
341
360
  template.request = @request
342
361
  template.response = @response
343
- @template.init(@scene)
344
- @template.widgets.each do |name, w|
362
+ template.init(@scene)
363
+ template.widgets.each do |name, w|
345
364
  add_widget(w)
346
365
  end
347
366
  @widgets.each do |id, w|
@@ -383,7 +402,7 @@ module Spider
383
402
 
384
403
  def run(action='')
385
404
  @widgets.each do |wname, w|
386
- w.run
405
+ w.run if w.run?
387
406
  end
388
407
  if (@parent)
389
408
  @parent.after_widget(@id.to_sym)
@@ -396,7 +415,7 @@ module Spider
396
415
  end
397
416
 
398
417
  def run?
399
- @is_target || (!@target_mode && !attributes[:"sp:target_only"])
418
+ @is_target || (!@target_mode && !attributes[:"sp:target-only"])
400
419
  end
401
420
 
402
421
  def init_widget_done?
@@ -410,6 +429,7 @@ module Spider
410
429
 
411
430
  def render
412
431
  prepare_scene(@scene)
432
+ set_scene_vars(@scene)
413
433
  @template.render(@scene) unless @target_mode && !@is_target
414
434
  end
415
435
 
@@ -455,6 +475,10 @@ module Spider
455
475
  return p
456
476
  end
457
477
 
478
+ def has_params?
479
+ !params.empty?
480
+ end
481
+
458
482
  def session(container=@request.session, klass=Hash)
459
483
  s = (container['_w'] ||= klass.new)
460
484
  @id_path[0..-2].each{ |id| s = (s[id] ||= klass.new) }
@@ -481,7 +505,7 @@ module Spider
481
505
  def add_widget(widget)
482
506
  widget.id_path = @id_path + [widget.id]
483
507
  widget.parent = self
484
- widget.active = true if @is_target || @active
508
+ # widget.active = true if @is_target || @active
485
509
  @widgets[widget.id.to_sym] = widget
486
510
  if (@widgets_runtime_content[widget.id.to_sym])
487
511
  @widgets_runtime_content[widget.id.to_sym].each do |content|
@@ -514,7 +538,9 @@ module Spider
514
538
 
515
539
 
516
540
  def parse_runtime_content_xml(xml, src_path=nil)
517
- parse_runtime_content(Hpricot(xml), src_path)
541
+ return if xml.empty?
542
+ doc = Hpricot(xml)
543
+ parse_runtime_content(doc, src_path) if doc.children && doc.root && doc.root.children
518
544
  end
519
545
 
520
546
  def parse_runtime_content(doc, src_path=nil)
@@ -613,11 +639,7 @@ module Spider
613
639
 
614
640
  def prepare_scene(scene)
615
641
  scene = super
616
- if (self.class.scene_attributes) # Repeat for new instance variables
617
- self.class.scene_attributes.each do |name|
618
- @scene[name] = instance_variable_get("@#{name}")
619
- end
620
- end
642
+
621
643
  # FIXME: owner_controller should be (almost) always defined
622
644
  scene.controller[:request_path] = owner_controller.request_path if owner_controller
623
645
  scene.widget[:request_path] = widget_request_path
@@ -631,6 +653,14 @@ module Spider
631
653
  return scene
632
654
  end
633
655
 
656
+ def set_scene_vars(scene)
657
+ if (self.class.scene_attributes) # Repeat for new instance variables
658
+ self.class.scene_attributes.each do |name|
659
+ @scene[name] = instance_variable_get("@#{name}")
660
+ end
661
+ end
662
+ end
663
+
634
664
  def css_class
635
665
  return @css_class if @css_class
636
666
  supers = self.class.ancestors.select{ |c| c != Spider::Widget && c.subclass_of?(Spider::Widget)}
@@ -665,8 +695,20 @@ module Spider
665
695
 
666
696
  module WidgetScene
667
697
 
698
+ def widget_target
699
+ "#{self[:request][:path]}?_wt=#{self[:widget][:id_path].join('/')}"
700
+ end
701
+
668
702
  def widget_action(name, *params)
669
- "#{self[:request][:path]}?_wt=#{self[:widget][:id_path].join('/')}&_we=#{name}"+(params.map{|p| "&_wp[]=#{p}"}).join('')
703
+ "#{self.widget_target}&_we=#{name}"+(params.map{|p| "&_wp[]=#{p}"}).join('')
704
+ end
705
+
706
+ def widget_params(params)
707
+ "#{self[:request][:path]}?"+params.map{ |k, v| "_w#{self[:widget][:param]}[#{k}]=#{v}"}.join('&')
708
+ end
709
+
710
+ def widget_param(name)
711
+ "_w#{self[:widget][:param]}[#{name}]"
670
712
  end
671
713
 
672
714
  end