spiderfw 0.5.10 → 0.5.11

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 (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
@@ -3,6 +3,7 @@
3
3
  <tpl:asset type="js" src="js/jquery/plugins/treeview/jquery.treeview.sortable.js" />
4
4
  <tpl:asset type="css" src="js/jquery/plugins/treeview/jquery.treeview.css" />
5
5
  <tpl:asset type="css" src="css/list.css" />
6
+ <tpl:asset type="js" src="js/plugins/sortable.js" />
6
7
  <tpl:asset type="js" src="js/list.js" />
7
8
  <div sp:if="@searchable" class="search_box">
8
9
  <form action="{ @request[:path] }" method="get">
@@ -78,7 +78,7 @@ module Spider; module Components
78
78
  def run
79
79
  @elements ||= choose_elements
80
80
  @scene.sortable = {}
81
- @model.elements_array.each{ |el| @scene.sortable[el.name] = @model.mapper.mapped?(el) ? true : false }
81
+ @model.elements_array.each{ |el| @scene.sortable[el.name] = @model.mapper.sortable?(el) ? true : false }
82
82
  @scene.labels = {}
83
83
  @elements.each do |el|
84
84
  @scene.labels[el] = @model.elements[el].label
@@ -1,9 +1,6 @@
1
1
  <div class="{ @widget[:css_class] }">
2
2
  <tpl:asset type="css" src="css/table.css" />
3
3
  <tpl:asset type="js" src="widgets/table.js" />
4
- <div sp:if="!@rows || @rows.length < 1" class="no_result">
5
- Nessun elemento
6
- </div>
7
4
  <table sp:if="@rows && @rows.length > 0" class="{ @widget[:css_class] }">
8
5
  <thead>
9
6
  <tr class="heading_row">
@@ -44,4 +41,7 @@
44
41
  </tr>
45
42
  </tfoot>
46
43
  </table>
44
+ <div sp:if="!@rows || @rows.length < 1" class="no_result">
45
+ _(No element)
46
+ </div>
47
47
  </div>
@@ -2,35 +2,83 @@ require 'apps/core/components/widgets/menu/menu'
2
2
 
3
3
  module Spider; module Components
4
4
 
5
- class Tabs < Spider::Components::Switcher
5
+ class Tabs < Spider::Widget
6
6
  tag 'tabs'
7
7
 
8
- def parse_runtime_content(doc)
9
- doc = super
8
+ def init
9
+ @tabs = []
10
+ @tabs_labels = {}
11
+ end
12
+
13
+ def add_tab(id, label)
14
+ @tabs << id
15
+ @tabs_labels[id] = label
16
+ end
17
+
18
+ def prepare
19
+ super
20
+ @active_tab ||= @tabs.first
21
+ @scene << {
22
+ :active_tab => @active_tab,
23
+ :tabs => @tabs,
24
+ :tabs_labels => @tabs_labels
25
+ }
26
+ end
27
+
28
+ def self.parse_content(doc)
29
+ content, overrides = super
30
+ doc = Hpricot(content)
31
+ tabs = []
32
+ tabs_override = '<tpl:override search="#tabs_content">'
10
33
  doc.search('tab').each do |tab|
11
- t = nil
12
- if (tab.attributes['src'])
13
- t = {:src => tab.attributes['src']}
14
- elsif (tab.attributes['widget'])
15
- t = {:widget => tab.attributes[:widget]}
16
- end
17
- add
18
- mods << const_get_full(mod.innerText)
34
+ tab_id = tab.get_attribute('id')
35
+ tabs_override += '<div sp:if="@active_tab == \''+tab_id+'\'>'
36
+ tabs_override += '<sp:parent-context>'
37
+ tabs_override += tab.innerHTML
38
+ tabs_override += '</sp:parent-context>'
39
+ tabs_override += '</div>'
40
+ tab.innerHTML = ''
19
41
  end
20
- doc.search('admin:app').each do |app_tag|
21
- except = []
22
- if (app_tag.attributes['except'])
23
- except = app_tag.attributes['except'].split(',').map{ |e| e.strip }
24
- end
25
- app = const_get_full(app_tag.innerText.strip)
26
- mods += app.models.select{ |m|
27
- !m.attributes[:sub_model] && m.mapper.class.write? && !except.include?(m.name.split('::')[-1])
28
- }.sort{ |a, b| a.name <=> b.name }
42
+ tabs_override += '</tpl:override>'
43
+ debugger
44
+ overrides << Hpricot(tabs_override).root
45
+ return doc.to_s, overrides
46
+ end
47
+
48
+ def parse_runtime_content(doc, src_path='')
49
+ doc = super
50
+ return doc if !doc.children || doc.children.empty?
51
+ doc.search('tab').each do |tab|
52
+ tab_id = tab.get_attribute('id')
53
+ label = tab.get_attribute('label')
54
+ add_tab(tab_id, label)
29
55
  end
30
- @models ||= []
31
- @models += mods
32
56
  return doc
33
57
  end
58
+
59
+
60
+ # def self.compile_block(el, id, attributes, options)
61
+ # init_params = Spider::TemplateBlocks::Widget.attributes_to_init_params(attributes)
62
+ # init = "w = add_widget('#{id}', #{self}.new(@request, @response), {#{init_params.join(', ')}}, '', nil)\n"
63
+ # c = "yield :#{id}\n"
64
+ # tabs_content = []
65
+ # el.search('tab').each do |tab|
66
+ # tab_id = tab.get_attribute('id')
67
+ # label = tab.get_attribute('label')
68
+ # init += "w.add_tab('#{tab_id}', '#{label}')\n"
69
+ # raise TemplateCompileError, "Tabs widget #{id} has a tab without a label attribute" unless label
70
+ # tab_c, tab_init = Spider::TemplateBlocks.compile_content(tab, c, init, options)
71
+ # init += "if scene[:active_tab] == '#{tab_id}'\n"
72
+ # init += tab_init
73
+ # init += "end\n"
74
+ # c += "debugger\n"
75
+ # c += "if self[:active_tab] == '#{tab_id}'\n"
76
+ # c += tab_c
77
+ # c += "end\n"
78
+ #
79
+ # end
80
+ # return [init, c]
81
+ # end
34
82
 
35
83
 
36
84
  end
@@ -1,2 +1,8 @@
1
- <tpl:extend src="SPIDER/apps/core/components/widgets/menu/menu.shtml">
2
- </tpl:extend>
1
+ <div class="tabs">
2
+ <ul>
3
+ <li sp:each="@tabs |tab_id|">
4
+ <a href="#aaa">{ @tabs_labels[tab_id] }</a>
5
+ </li>
6
+ </ul>
7
+ <div id="tabs_content"></div>
8
+ </div>
@@ -1,4 +1,7 @@
1
- require 'ftools'
1
+ begin
2
+ require 'ftools'
3
+ rescue LoadError
4
+ end
2
5
 
3
6
  module Spider; module Forms
4
7
 
Binary file
Binary file
data/lib/spiderfw.rb CHANGED
@@ -380,7 +380,8 @@ module Spider
380
380
  if (path[0].chr == '/')
381
381
  first_part = path[1..-1].split('/')[0]
382
382
  Spider.apps_by_path.each do |p, a|
383
- if first_part == p
383
+ if path.index(p) == 1 # FIXME: breaks something
384
+ #if first_part == p
384
385
  app = a
385
386
  path = path[p.length+2..-1]
386
387
  break
@@ -392,6 +393,7 @@ module Spider
392
393
  app = owner_class.app if (owner_class && owner_class.app)
393
394
  end
394
395
  return Resource.new(cur_path+'/'+path, owner_class) if cur_path && File.exist?(cur_path+'/'+path) # !app
396
+ raise "Can't find owner app for resource #{path}" unless app
395
397
  search_locations = [["#{Spider.paths[:root]}/#{resource_rel_path}/#{app.relative_path}", @home]]
396
398
  if app.respond_to?("#{resource_type}_path")
397
399
  search_locations << [app.send("#{resource_type}_path"), app]
@@ -219,6 +219,7 @@ module Spider
219
219
  self[key]
220
220
  end
221
221
  end
222
+
222
223
 
223
224
  # FIXME: temporarely allows old behaviour
224
225
  def config(key=nil)
@@ -273,7 +274,8 @@ module Spider
273
274
 
274
275
  def to_hash
275
276
  h = {}
276
- @values.each do |k, v|
277
+ self.options.each do |k|
278
+ v = self[k]
277
279
  if v.is_a?(self.class)
278
280
  v = v.to_hash
279
281
  next if v.empty?
@@ -113,6 +113,14 @@ module Spider
113
113
  return res ? res.path : nil
114
114
  end
115
115
 
116
+ def url=(url)
117
+ @url = url
118
+ end
119
+
120
+ def url
121
+ @url || ''
122
+ end
123
+
116
124
 
117
125
  end
118
126
 
@@ -9,8 +9,8 @@ module Spider; module ControllerMixins
9
9
 
10
10
  def self.included(klass)
11
11
  klass.extend(ClassMethods)
12
- klass.route('public/', :serve_static)
13
- klass.route('w/', :serve_widget_static)
12
+ klass.route('public/', :serve_static, :do => lambda{ @serving_static = true })
13
+ klass.route('w/', :serve_widget_static, :do => lambda{ @serving_static = true })
14
14
  if (klass < Visual)
15
15
  klass.no_layout('public')
16
16
  klass.no_layout('serve_static')
@@ -75,6 +75,14 @@ module Spider; module ControllerMixins
75
75
  mode = Spider.conf.get('static_content.mode')
76
76
  raise Spider::Controller::NotFound.new(full_path) unless File.exist?(full_path)
77
77
  stat = File.lstat(full_path)
78
+ if @request.env['HTTP_IF_MODIFIED_SINCE']
79
+ if_modified = Time.httpdate(@request.env['HTTP_IF_MODIFIED_SINCE'])
80
+ if stat.mtime <= if_modified
81
+ debug("Not modified #{full_path}")
82
+ raise HTTPStatus.new(Spider::HTTP::NOT_MODIFIED)
83
+ return
84
+ end
85
+ end
78
86
  if File.directory?(full_path)
79
87
  ct = "httpd/unix-directory"
80
88
  else
@@ -104,6 +112,10 @@ module Spider; module ControllerMixins
104
112
  return scene
105
113
  end
106
114
 
115
+ def serving_static?
116
+ @serving_static
117
+ end
118
+
107
119
  end
108
120
 
109
121
 
@@ -61,12 +61,13 @@ module Spider; module ControllerMixins
61
61
  @visual_params ||= {}
62
62
  end
63
63
 
64
- def init_widgets(template)
64
+ def init_widgets(template, layout=nil)
65
65
  widget_target = @request.params['_wt']
66
66
  widget_execute = @request.params['_we']
67
67
  if (widget_target && !@rendering_error)
68
68
  first, rest = widget_target.split('/', 2)
69
- @_widget = find_widget(first)
69
+ @_widget = template.find_widget(first)
70
+ @_widget = layout.find_widget(first) if !@_widget && layout
70
71
  raise Spider::Controller::NotFound.new("Widget #{widget_target}") unless @_widget
71
72
  @_widget.is_target = true unless rest
72
73
  @_widget.set_action(widget_execute) if widget_execute
@@ -74,6 +75,7 @@ module Spider; module ControllerMixins
74
75
  @_widget.widget_target = rest
75
76
  end
76
77
  template.do_widgets_before
78
+ layout.do_widgets_before if layout
77
79
  if @_widget
78
80
  @_widget.execute
79
81
  done
@@ -82,7 +84,7 @@ module Spider; module ControllerMixins
82
84
 
83
85
  def execute(action='', *params)
84
86
  @visual_params = @executed_format_params
85
- @is_target = false if @request.params['_wt']
87
+ @is_target = false if @request.params['_wt'] && !self.is_a?(Spider::Widget)
86
88
  if (self.is_a?(Widget) && @is_target && @request.params['_wp'])
87
89
  params = @request.params['_wp']
88
90
  elsif (@visual_params.is_a?(Hash) && @visual_params[:params])
@@ -91,7 +93,7 @@ module Spider; module ControllerMixins
91
93
  end
92
94
  super(action, *params)
93
95
  return unless @visual_params.is_a?(Hash)
94
- @template = init_template if !@template && @visual_params[:template]
96
+ @template = get_template if !@template && @visual_params[:template]
95
97
  init_widgets(@template) if @template
96
98
  if @visual_params[:call]
97
99
  send(@visual_params[:call], *params)
@@ -138,7 +140,7 @@ module Spider; module ControllerMixins
138
140
  end
139
141
 
140
142
 
141
- def init_template(path=nil, scene=nil, options={})
143
+ def get_template(path=nil, scene=nil, options={})
142
144
  return @template if @template && @loaded_template_path == path
143
145
  scene ||= @scene
144
146
  scene ||= get_scene
@@ -149,14 +151,15 @@ module Spider; module ControllerMixins
149
151
  options = format_params.merge(options)
150
152
  end
151
153
  template = load_template(path)
152
- do_template_init(template, options)
154
+ init_template(template, options)
153
155
  @template = template
154
156
  @loaded_template_path = path
155
157
 
156
158
  return template
157
159
  end
158
160
 
159
- def do_template_init(template, options={})
161
+ def init_template(template, options={})
162
+ prepare_template(template) unless template.owner # if called directly
160
163
  template.init(scene)
161
164
  if (@request.params['_action'])
162
165
  template._widget_action = @request.params['_action']
@@ -166,17 +169,10 @@ module Spider; module ControllerMixins
166
169
  end
167
170
  return template
168
171
  end
169
-
170
- def render_layout(path, content={})
171
- layout = self.class.load_layout(path)
172
- layout.request = @request
173
- layout.render(content)
174
- end
175
-
172
+
176
173
  def init_layout(layout)
177
174
  l = layout.is_a?(Layout) ? layout : self.class.load_layout(layout)
178
- l.owner = self
179
- l.request = request
175
+ prepare_template(l)
180
176
  return l
181
177
  end
182
178
 
@@ -189,21 +185,25 @@ module Spider; module ControllerMixins
189
185
  if (path.is_a?(Spider::Template))
190
186
  template = path
191
187
  else
192
- template = init_template(path, scene, options)
188
+ template = get_template(path, scene, options)
193
189
  end
194
- init_widgets(template)
195
- return template if done?
190
+ layout = nil
196
191
  chosen_layouts = options[:layout] || @layout
197
192
  chosen_layouts = [chosen_layouts] if chosen_layouts && !chosen_layouts.is_a?(Array)
198
193
  if (chosen_layouts)
199
194
  t = template
200
- l = nil
195
+ layout = nil
201
196
  (chosen_layouts.length-1).downto(0) do |i|
202
- l = init_layout(chosen_layouts[i])
203
- l.template = t
204
- t = l
197
+ layout = init_layout(chosen_layouts[i])
198
+ layout.template = t
199
+ t = layout
205
200
  end
206
- l.render(scene)
201
+ end
202
+ layout.init(scene) if layout
203
+ init_widgets(template, layout)
204
+ return template if done?
205
+ if layout
206
+ layout.render(scene)
207
207
  else
208
208
  template.render(scene)
209
209
  end
@@ -265,7 +265,7 @@ module Spider; module ControllerMixins
265
265
  @scene.backtrace = build_backtrace(exc)
266
266
  client_editor = Spider.conf.get('client.text_editor')
267
267
  prefix = 'txmt://open?url=' if client_editor == 'textmate'
268
- @scene.exception = "#{exc.class.name}: #{exc.message}"
268
+ @scene.exception = "#{exc.class.name}: #{CGI.escapeHTML(exc.message)}"
269
269
  cnt = 0
270
270
  @scene.backtrace.each do |tr|
271
271
  tr[:index] = cnt
@@ -1,4 +1,5 @@
1
1
  require 'spiderfw/controller/controller'
2
+ require 'spiderfw/controller/mixins/visual'
2
3
 
3
4
  module Spider
4
5
 
@@ -19,6 +20,8 @@ module Spider
19
20
  if (@widgets[$1])
20
21
  return Route.new(:path => path, :dest => @widgets[$1], :action => $2)
21
22
  end
23
+ elsif (path =~ /_h\/(.+)/) # Route back to home
24
+ return Route.new(:path => path, :dest => Spider::HomeController, :action => $1)
22
25
  end
23
26
  return super
24
27
  end
@@ -2,7 +2,7 @@ module Spider
2
2
 
3
3
  class Request
4
4
  attr_accessor :action, :params, :cookies, :env, :protocol,
5
- :format, :extension, :session, :user_id, :server, :request_time, :controller_path,
5
+ :format, :session, :user_id, :server, :request_time, :controller_path,
6
6
  :locale, :misc
7
7
 
8
8
  BUFSIZE = 1024*4
@@ -14,6 +14,9 @@ module Spider
14
14
  @env = env
15
15
  @locale = Locale.current[0]
16
16
  @misc = {}
17
+ @params = {}
18
+ @action = ""
19
+ @session = {}
17
20
  end
18
21
 
19
22
  def body=(b)
@@ -41,8 +41,13 @@ module Spider
41
41
  @sid = sid || generate_sid
42
42
  end
43
43
 
44
- def delete
45
- self.class.delete(@sid)
44
+ def delete(key=nil)
45
+ if key
46
+ restore unless @restored
47
+ @data.delete(key)
48
+ else
49
+ self.class.delete(@sid)
50
+ end
46
51
  end
47
52
 
48
53
  def generate_sid
@@ -61,10 +66,6 @@ module Spider
61
66
  @data[key] = val
62
67
  end
63
68
 
64
- def delete(key)
65
- restore unless @restored
66
- @data.delete(key)
67
- end
68
69
 
69
70
  def persist
70
71
  return unless @restored