spiderfw 0.6.21 → 0.6.22

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 (149) hide show
  1. data/CHANGELOG +33 -0
  2. data/Rakefile +0 -1
  3. data/VERSION +1 -1
  4. data/apps/core/admin/_init.rb +4 -0
  5. data/apps/core/admin/admin.rb +20 -4
  6. data/apps/core/admin/controllers/admin_controller.rb +63 -4
  7. data/apps/core/admin/controllers/app_admin_controller.rb +15 -0
  8. data/apps/core/admin/data/locale/it/LC_MESSAGES/admin.mo +0 -0
  9. data/apps/core/admin/po/admin.pot +33 -0
  10. data/apps/core/admin/po/it/admin.po +34 -0
  11. data/apps/core/admin/public/css/admin.css +13 -0
  12. data/apps/core/admin/public/css/login.css +51 -0
  13. data/apps/core/admin/public/css/sass/admin.css +198 -0
  14. data/apps/core/admin/public/css/sass/bootstrap/bootstrap.css +3107 -0
  15. data/apps/core/admin/public/img/css/header_bg.png +0 -0
  16. data/apps/core/admin/public/img/css/noise.png +0 -0
  17. data/apps/core/admin/public/img/css/side_bg.png +0 -0
  18. data/apps/core/admin/public/img/icons/logout.png +0 -0
  19. data/apps/core/admin/public/img/icons-s845a69dd9f.png +0 -0
  20. data/apps/core/admin/public/js/bootstrap-alerts.js +113 -0
  21. data/apps/core/admin/public/js/bootstrap-buttons.js +62 -0
  22. data/apps/core/admin/public/js/bootstrap-dropdown.js +55 -0
  23. data/apps/core/admin/public/js/bootstrap-modal.js +260 -0
  24. data/apps/core/admin/public/js/bootstrap-popover.js +90 -0
  25. data/apps/core/admin/public/js/bootstrap-scrollspy.js +107 -0
  26. data/apps/core/admin/public/js/bootstrap-tabs.js +80 -0
  27. data/apps/core/admin/public/js/bootstrap-twipsy.js +321 -0
  28. data/apps/core/admin/public/sass/admin.scss +167 -0
  29. data/apps/core/admin/public/sass/bootstrap/bootstrap.scss +29 -0
  30. data/apps/core/admin/public/sass/bootstrap/forms.scss +478 -0
  31. data/apps/core/admin/public/sass/bootstrap/mixins.scss +220 -0
  32. data/apps/core/admin/public/sass/bootstrap/patterns.scss +1062 -0
  33. data/apps/core/admin/public/sass/bootstrap/reset.scss +141 -0
  34. data/apps/core/admin/public/sass/bootstrap/scaffolding.scss +136 -0
  35. data/apps/core/admin/public/sass/bootstrap/tables.scss +224 -0
  36. data/apps/core/admin/public/sass/bootstrap/type.scss +187 -0
  37. data/apps/core/admin/public/sass/bootstrap/variables.scss +60 -0
  38. data/apps/core/admin/public/sass/grid.scss +54 -0
  39. data/apps/core/admin/views/_app_info.shtml +5 -0
  40. data/apps/core/admin/views/admin.layout.shtml +35 -0
  41. data/apps/core/admin/views/index.shtml +1 -1
  42. data/apps/core/admin/views/login.layout.shtml +13 -0
  43. data/apps/core/auth/controllers/mixins/auth_helper.rb +1 -1
  44. data/apps/core/auth/models/super_user.rb +6 -0
  45. data/apps/core/auth/models/user.rb +9 -0
  46. data/apps/core/components/assets.rb +5 -1
  47. data/apps/core/components/data/locale/it/LC_MESSAGES/spider_components.mo +0 -0
  48. data/apps/core/components/po/it/spider_components.po +23 -9
  49. data/apps/core/components/po/spider_components.pot +16 -8
  50. data/apps/core/components/public/css/admin.css +0 -12
  51. data/apps/core/components/public/css/crud.css +16 -19
  52. data/apps/core/components/public/css/table.css +11 -5
  53. data/apps/core/components/public/js/less-1.1.3.min.js +16 -0
  54. data/apps/core/components/public/widgets/table.js +1 -1
  55. data/apps/core/components/widgets/admin/admin.rb +10 -0
  56. data/apps/core/components/widgets/admin/admin.shtml +24 -4
  57. data/apps/core/components/widgets/confirm/confirm.rb +2 -2
  58. data/apps/core/components/widgets/confirm/confirm.shtml +5 -2
  59. data/apps/core/components/widgets/crud/crud.rb +10 -1
  60. data/apps/core/components/widgets/crud/crud.shtml +18 -21
  61. data/apps/core/components/widgets/menu/menu.shtml +1 -2
  62. data/apps/core/components/widgets/switcher/switcher.rb +6 -3
  63. data/apps/core/components/widgets/switcher/templates/default.shtml +3 -1
  64. data/apps/core/components/widgets/table/table.rb +3 -2
  65. data/apps/core/components/widgets/table/table.shtml +44 -25
  66. data/apps/core/forms/data/locale/it/LC_MESSAGES/spider_forms.mo +0 -0
  67. data/apps/core/forms/po/it/spider_forms.po +7 -2
  68. data/apps/core/forms/po/spider_forms.pot +5 -1
  69. data/apps/core/forms/public/css/form.css +3 -3
  70. data/apps/core/forms/public/css/html_area.css +0 -1
  71. data/apps/core/forms/public/date_time.js +4 -3
  72. data/apps/core/forms/public/select.js +5 -4
  73. data/apps/core/forms/tags/element_label.erb +1 -1
  74. data/apps/core/forms/tags/row.erb +1 -1
  75. data/apps/core/forms/widgets/form/form.rb +23 -1
  76. data/apps/core/forms/widgets/form/form.shtml +7 -8
  77. data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +3 -3
  78. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +3 -3
  79. data/apps/core/forms/widgets/inputs/file_input/file_input.rb +4 -2
  80. data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +1 -1
  81. data/apps/core/forms/widgets/inputs/hidden/hidden.shtml +1 -1
  82. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  83. data/apps/core/forms/widgets/inputs/password/password.shtml +3 -3
  84. data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +2 -2
  85. data/apps/core/forms/widgets/inputs/select/select.shtml +16 -13
  86. data/apps/core/forms/widgets/inputs/text/text.shtml +3 -3
  87. data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +5 -2
  88. data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +3 -3
  89. data/apps/messenger/_init.rb +10 -2
  90. data/apps/messenger/controllers/messenger_admin_controller.rb +53 -0
  91. data/apps/messenger/controllers/messenger_controller.rb +2 -0
  92. data/apps/messenger/controllers/mixins/messenger_helper.rb +2 -2
  93. data/apps/messenger/models/message.rb +1 -1
  94. data/apps/messenger/public/app_icon.png +0 -0
  95. data/apps/messenger/views/admin/_admin.layout.shtml +26 -0
  96. data/apps/messenger/views/admin/index.shtml +13 -0
  97. data/apps/messenger/views/admin/queue.shtml +28 -0
  98. data/apps/messenger/views/index.shtml +3 -3
  99. data/data/locale/it/LC_MESSAGES/spider.mo +0 -0
  100. data/lib/spiderfw/app.rb +10 -1
  101. data/lib/spiderfw/cache/template_cache.rb +21 -22
  102. data/lib/spiderfw/cmd/commands/app.rb +3 -3
  103. data/lib/spiderfw/cmd/commands/setup.rb +1 -1
  104. data/lib/spiderfw/config/options/spider.rb +18 -2
  105. data/lib/spiderfw/controller/controller.rb +9 -3
  106. data/lib/spiderfw/controller/dispatcher.rb +25 -12
  107. data/lib/spiderfw/controller/home_controller.rb +3 -3
  108. data/lib/spiderfw/controller/http_controller.rb +11 -0
  109. data/lib/spiderfw/controller/mixins/static_content.rb +3 -12
  110. data/lib/spiderfw/controller/mixins/visual.rb +21 -20
  111. data/lib/spiderfw/controller/request.rb +1 -3
  112. data/lib/spiderfw/http/adapters/mongrel.rb +1 -1
  113. data/lib/spiderfw/i18n/gettext.rb +14 -0
  114. data/lib/spiderfw/i18n/shtml_parser.rb +2 -2
  115. data/lib/spiderfw/model/base_model.rb +4 -3
  116. data/lib/spiderfw/model/mappers/db_mapper.rb +137 -79
  117. data/lib/spiderfw/model/mappers/mapper.rb +6 -2
  118. data/lib/spiderfw/model/migrations/drop_element.rb +1 -1
  119. data/lib/spiderfw/model/migrations/previous_model.rb +73 -0
  120. data/lib/spiderfw/model/migrations/rename_element.rb +42 -0
  121. data/lib/spiderfw/model/migrations.rb +14 -1
  122. data/lib/spiderfw/model/mixins/tree.rb +65 -19
  123. data/lib/spiderfw/model/model_hash.rb +9 -5
  124. data/lib/spiderfw/model/query.rb +8 -0
  125. data/lib/spiderfw/model/query_funcs.rb +23 -0
  126. data/lib/spiderfw/model/query_set.rb +1 -1
  127. data/lib/spiderfw/model/request.rb +11 -3
  128. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +28 -1
  129. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +10 -10
  130. data/lib/spiderfw/model/storage/db/db_schema.rb +20 -3
  131. data/lib/spiderfw/model/storage/db/db_storage.rb +39 -17
  132. data/lib/spiderfw/setup/app_manager.rb +69 -31
  133. data/lib/spiderfw/setup/setup_task.rb +76 -8
  134. data/lib/spiderfw/spider.rb +21 -1
  135. data/lib/spiderfw/templates/blocks/text.rb +4 -4
  136. data/lib/spiderfw/templates/blocks/text_domain.rb +25 -0
  137. data/lib/spiderfw/templates/blocks/widget.rb +1 -1
  138. data/lib/spiderfw/templates/layout.rb +160 -92
  139. data/lib/spiderfw/templates/resources/less.rb +10 -2
  140. data/lib/spiderfw/templates/resources/sass.rb +66 -9
  141. data/lib/spiderfw/templates/template.rb +35 -10
  142. data/lib/spiderfw/templates/template_blocks.rb +6 -3
  143. data/lib/spiderfw/utils/logger.rb +20 -0
  144. data/lib/spiderfw/utils/memory.rb +7 -3
  145. data/lib/spiderfw/widget/widget.rb +13 -7
  146. data/lib/spiderfw/widget/widget_attributes.rb +2 -2
  147. data/spider.gemspec +1 -0
  148. metadata +68 -11
  149. data/apps/core/admin/views/spider_admin.layout.shtml +0 -23
@@ -31,91 +31,36 @@ module Spider
31
31
  def prepare_assets
32
32
  @template_assets = { :css => [], :js => [] }
33
33
  assets = {:css => [], :js => []}
34
+ compress_assets = {:js => {}, :css => {}}
34
35
  seen = {}
35
36
  js_messages = []
36
37
  use_cdn = Spider.conf.get('assets.use_cdn')
37
- compress_assets = {:js => {}, :css => {}}
38
38
  cname = File.basename(@path, '.layout.shtml')
39
39
  cname = File.basename(cname, '.shtml')
40
40
  cname += "-#{@asset_set}" if @asset_set
41
- pub_dest = nil
41
+ @cname = cname
42
+
42
43
  all_assets.each do |ass|
43
44
  seen_check = ass[:runtime] || ass[:src]
44
45
  next if ass[:src].blank? && !ass[:runtime]
45
46
  next if seen[seen_check]
46
47
  seen[seen_check] = true
47
- type = ass[:type].to_sym
48
48
 
49
49
  ass = compile_asset(ass)
50
-
51
- compress_config = case type
52
- when :js
53
- 'javascript.compress'
54
- when :css
55
- 'css.compress'
56
- end
57
- no_compress = @scene.__is_error_page || !Spider.conf.get(compress_config) || \
58
- ass[:runtime] || ass[:if_ie_lte] || ass[:media] || (use_cdn && ass[:cdn])
59
-
60
- if no_compress
61
- if ass[:runtime]
62
- assets[type] << {:src => Spider::Template.runtime_assets[ass[:runtime]].call(@request, @response, @scene)}
63
- else
64
- assets[type] << ass
65
- end
66
- else
67
- unless pub_dest
68
- pub_dest = self.class.compiled_folder_path
69
- FileUtils.mkdir_p(pub_dest)
70
- end
71
- if comp = ass[:compressed_path] # Already compressed assets
72
- name = File.basename(comp)
73
- if ass[:compressed_rel_path] # Keeps the compressed files in a subdir
74
- dir = File.dirname(ass[:compressed_rel_path])
75
- if ass[:copy_dir] # Copies the source dir (which may contain resources used by the assets)
76
- start = dir
77
- if ass[:copy_dir].is_a?(Fixnum) # How many levels to go up
78
- ass[:copy_dir].downto(0) do |i|
79
- start = File.dirname(start)
80
- end
81
- end
82
- dst_dir = File.join(pub_dest, start)
83
- unless File.dirname(start) == '.' || File.directory?(File.dirname(dst_dir))
84
- FileUtils.mkdir_p(File.join(pub_dest, File.dirname(dst_dir)))
85
- end
86
- unless File.directory?(dst_dir)
87
- FileUtils.cp_r(File.join(ass[:app].pub_path, start), dst_dir)
88
- end
89
- else
90
- FileUtils.mkdir_p(File.join(pub_dest, dir))
91
- File.cp(comp, File.join(pub_dest, dir)) unless File.exist?(File.join(pub_dest, dir))
92
- end
93
- src = dir+'/'+name
94
- else
95
- unless File.exist?(File.join(pub_dest, name))
96
- File.cp(comp, pub_dest)
97
- end
98
- src = name
99
- end
100
- ass[:src] = Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+src
101
- assets[type] << ass
102
- else # needs compression
103
- name = ass[:compress] || cname
104
- unless compress_assets[type][name]
105
- cpr = {:name => name, :assets => [], :cpr => true}
106
- assets[type] << cpr
107
- compress_assets[type][name] = cpr
108
- end
109
- compress_assets[type][name][:assets] << ass
110
- end
111
- end
112
- if ass[:gettext] && type == :js
113
- msg_path = asset_gettext_messages_file(ass[:path])
114
- if File.exists?(msg_path)
115
- js_messages += JSON.parse(File.read(msg_path))
116
- else
117
- Spider.logger.warn("Javascript Gettext file #{msg_path} not found")
118
- end
50
+
51
+ res = prepare_asset(ass, compress_assets, js_messages)
52
+ assets[:css] += res[:css]
53
+ assets[:js] += res[:js]
54
+
55
+ end
56
+
57
+
58
+ if @compile_less == false
59
+ less = Spider::Template.get_named_asset('less')
60
+ less.each do |ass|
61
+ res = prepare_asset(parse_asset(ass[:type], ass[:src], ass).first)
62
+ assets[:css] += res[:css]
63
+ assets[:js] += res[:js]
119
64
  end
120
65
  end
121
66
  assets[:js].each do |ass|
@@ -133,7 +78,7 @@ module Spider
133
78
  @template_assets[:css] << Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+compressed
134
79
  else
135
80
  ass[:src] = ass[:cdn] if ass[:cdn] && use_cdn
136
- is_dyn = ass[:if_ie_lte] || ass[:media]
81
+ is_dyn = ass[:if_ie_lte] || ass[:media] || ass[:rel]
137
82
  @template_assets[:css] << (is_dyn ? ass : ass[:src])
138
83
  end
139
84
  end
@@ -151,6 +96,84 @@ module Spider
151
96
 
152
97
  @assets_prepared = true
153
98
  end
99
+
100
+ def prepare_asset(ass, compress_assets={}, js_messages=[])
101
+ type = ass[:type].to_sym
102
+ assets = {:css => [], :js => []}
103
+ pub_dest = nil
104
+ use_cdn = Spider.conf.get('assets.use_cdn')
105
+
106
+ compress_config = case type
107
+ when :js
108
+ 'javascript.compress'
109
+ when :css
110
+ 'css.compress'
111
+ end
112
+ no_compress = @scene.__is_error_page || !Spider.conf.get(compress_config) || \
113
+ ass[:runtime] || ass[:if_ie_lte] || ass[:media] || (use_cdn && ass[:cdn])
114
+
115
+ if no_compress
116
+ if ass[:runtime]
117
+ assets[type] << {:src => Spider::Template.runtime_assets[ass[:runtime]].call(@request, @response, @scene)}
118
+ else
119
+ assets[type] << ass
120
+ end
121
+ else
122
+ unless pub_dest
123
+ pub_dest = self.class.compiled_folder_path
124
+ FileUtils.mkdir_p(pub_dest)
125
+ end
126
+ if comp = ass[:compressed_path] # Already compressed assets
127
+ name = File.basename(comp)
128
+ if ass[:compressed_rel_path] # Keeps the compressed files in a subdir
129
+ dir = File.dirname(ass[:compressed_rel_path])
130
+ if ass[:copy_dir] # Copies the source dir (which may contain resources used by the assets)
131
+ start = dir
132
+ if ass[:copy_dir].is_a?(Fixnum) # How many levels to go up
133
+ ass[:copy_dir].downto(0) do |i|
134
+ start = File.dirname(start)
135
+ end
136
+ end
137
+ dst_dir = File.join(pub_dest, start)
138
+ unless File.dirname(start) == '.' || File.directory?(File.dirname(dst_dir))
139
+ FileUtils.mkdir_p(File.join(pub_dest, File.dirname(dst_dir)))
140
+ end
141
+ unless File.directory?(dst_dir)
142
+ FileUtils.cp_r(File.join(ass[:app].pub_path, start), dst_dir)
143
+ end
144
+ else
145
+ FileUtils.mkdir_p(File.join(pub_dest, dir))
146
+ FileUtils.cp(comp, File.join(pub_dest, dir)) unless File.exist?(File.join(pub_dest, dir))
147
+ end
148
+ src = dir+'/'+name
149
+ else
150
+ unless File.exist?(File.join(pub_dest, name))
151
+ FileUtils.cp(comp, pub_dest)
152
+ end
153
+ src = name
154
+ end
155
+ ass[:src] = Spider::HomeController.pub_url+'/'+COMPILED_FOLDER+'/'+src
156
+ assets[type] << ass
157
+ else # needs compression
158
+ name = ass[:compress] || @cname
159
+ unless compress_assets[type][name]
160
+ cpr = {:name => name, :assets => [], :cpr => true}
161
+ assets[type] << cpr
162
+ compress_assets[type][name] = cpr
163
+ end
164
+ compress_assets[type][name][:assets] << ass
165
+ end
166
+ end
167
+ if ass[:gettext] && type == :js
168
+ msg_path = asset_gettext_messages_file(ass[:path])
169
+ if File.exists?(msg_path)
170
+ js_messages += JSON.parse(File.read(msg_path))
171
+ else
172
+ Spider.logger.warn("Javascript Gettext file #{msg_path} not found")
173
+ end
174
+ end
175
+ assets
176
+ end
154
177
 
155
178
  @@named_layouts = {}
156
179
 
@@ -190,26 +213,71 @@ module Spider
190
213
  end
191
214
 
192
215
  def compile_asset(ass)
193
- return ass unless ass[:src]
216
+ return ass unless ass[:src] && ass[:path]
194
217
  if ass[:type] == :css
195
218
  ext = File.extname(ass[:path])
196
219
  compile_exts = ['.scss', '.sass', '.less']
220
+
197
221
  if compile_exts.include?(ext)
222
+ ass_type = nil
223
+ if ext == '.less'
224
+ ass_type = :less
225
+ if @compile_less.nil?
226
+ @compile_less = false
227
+ if Spider.conf.get('css.compile_less')
228
+ begin
229
+ require 'spiderfw/templates/resources/less'
230
+ @compile_less = true
231
+ rescue LoadError
232
+ Spider.logger.error("Unable to compile LESS. Please install less-js gem and a JS backend.")
233
+ end
234
+ end
235
+ end
236
+ unless @compile_less
237
+ ass[:rel] = 'stylesheet/less'
238
+ return ass
239
+ end
240
+ elsif ['.scss', '.sass'].include?(ext)
241
+ ass_type = :sass
242
+ end
198
243
  dir = File.dirname(ass[:path])
199
244
  base = File.basename(ass[:path], ext)
200
245
  newname = "#{base}.css"
201
- tmpdestdir = File.join(dir, 'stylesheets')
202
- dest = File.join(tmpdestdir, newname)
203
- compiler = if ['.scss', '.sass'].include?(ext)
204
- require 'spiderfw/templates/resources/sass'
205
- Spider::SassCompiler
206
- elsif ext == '.less'
207
- require 'spiderfw/templates/resources/less'
208
- Spider::LessCompiler
246
+ parts = dir.split(File::SEPARATOR)
247
+ if type_i = parts.index(ass_type.to_s)
248
+ parts[type_i] = File.join(ass[:type].to_s, ass_type.to_s)
249
+ destdir = parts.join(File::SEPARATOR)
250
+ else
251
+ destdir = dir
252
+ end
253
+ FileUtils.mkdir_p(destdir)
254
+ dest = File.join(destdir, newname)
255
+ if Spider.conf.get('css.compile')
256
+ compiler_class = if ass_type == :sass
257
+ require 'spiderfw/templates/resources/sass'
258
+ Spider::SassCompiler
259
+ elsif ass_type == :less
260
+ Spider::LessCompiler
261
+ end
262
+ begin
263
+ compiler = compiler_class.new(ass[:app].pub_path)
264
+ compiler.compile(ass[:path], dest)
265
+ rescue Exception
266
+ if ext == '.less'
267
+ Spider.logger.error("Unable to compile LESS. Please ensure you have a JS backend
268
+ (see https://github.com/sstephenson/execjs)")
269
+ else
270
+ raise
271
+ end
272
+ end
209
273
  end
210
- compiler.compile(ass[:path], dest)
211
274
  ass[:path] = dest
212
- ass[:src] = File.join(File.dirname(ass[:src]), newname)
275
+ srcdir = File.dirname(ass[:src])
276
+ if destdir != dir
277
+ srcdir = srcdir.sub(ass_type.to_s, File.join(ass[:type].to_s, ass_type.to_s))
278
+ end
279
+ ass[:src] = File.join(srcdir, newname)
280
+
213
281
  end
214
282
  end
215
283
  return ass
@@ -250,7 +318,7 @@ module Spider
250
318
  combined = "#{pub_dest}/._#{compiled_name}"
251
319
 
252
320
  dest = "#{pub_dest}/#{compiled_name}"
253
- File.cp(tmp_combined, combined)
321
+ FileUtils.cp(tmp_combined, combined)
254
322
  File.unlink(tmp_combined)
255
323
  compressor = ::YUI::JavaScriptCompressor.new("charset" => "UTF-8")
256
324
  io = open(combined, 'r')
@@ -320,7 +388,7 @@ module Spider
320
388
  mtime = File.mtime(url_src).to_i
321
389
  if cachebuster && File.exist?(url_dest) && mtime > File.mtime(url_dest).to_i
322
390
  if cachebuster == :soft
323
- File.cp(url_src, url_dest)
391
+ FileUtils.cp(url_src, url_dest)
324
392
  new_url += "?cb=#{mtime}"
325
393
  elsif cachebuster == :hard || cachebuster == :hardcopy
326
394
  url_dir = File.dirname(url)
@@ -330,13 +398,13 @@ module Spider
330
398
  cb_file_name = "#{url_basename}-cb#{mtime}#{url_ext}"
331
399
  new_url = "#{url_dir}/#{cb_file_name}"
332
400
  if cachebuster == :hard
333
- File.cp(url_src, url_dest)
401
+ FileUtils.cp(url_src, url_dest)
334
402
  else
335
- File.cp(url_src, "#{url_dest_dir}/#{cb_file_name}")
403
+ FileUtils.cp(url_src, "#{url_dest_dir}/#{cb_file_name}")
336
404
  end
337
405
  end
338
406
  else
339
- File.cp(url_src, url_dest)
407
+ FileUtils.cp(url_src, url_dest)
340
408
  end
341
409
  else
342
410
  Spider.logger.error("CSS referenced file not found: #{url_src}")
@@ -363,7 +431,7 @@ module Spider
363
431
  combined = "#{pub_dest}/._#{compiled_name}"
364
432
 
365
433
  dest = "#{pub_dest}/#{compiled_name}"
366
- File.cp(tmp_combined, combined)
434
+ FileUtils.cp(tmp_combined, combined)
367
435
  File.unlink(tmp_combined)
368
436
  compressor = ::YUI::CssCompressor.new("charset" => "UTF-8")
369
437
  io = open(combined, 'r')
@@ -392,7 +460,6 @@ module Spider
392
460
 
393
461
  def output_assets(type=nil)
394
462
  types = type ? [type] : self.assets.keys
395
- use_cdn = Spider.conf.get('assets.use_cdn')
396
463
  if types.include?(:js)
397
464
  self.assets[:js].each do |ass|
398
465
  ass = {:src => ass} if ass.is_a?(String)
@@ -412,7 +479,8 @@ module Spider
412
479
  if types.include?(:css)
413
480
  self.assets[:css].each do |ass|
414
481
  ass = {:src => ass} if ass.is_a?(String)
415
- link = "<link rel=\"stylesheet\" type=\"text/css\" href=\"#{ass[:src]}\""
482
+ rel = ass[:rel] || 'stylesheet'
483
+ link = "<link rel=\"#{rel}\" type=\"text/css\" href=\"#{ass[:src]}\""
416
484
  link += " media=\"#{ass[:media]}\"" if ass[:media]
417
485
  link += ">\n"
418
486
  if ass[:if_ie_lte]
@@ -1,10 +1,18 @@
1
- require 'less-js'
1
+ begin
2
+ require 'less-js'
3
+ rescue LoadError
4
+ raise "Please install less-js gem to compile less files"
5
+ end
2
6
 
3
7
  module Spider
4
8
 
5
9
  module LessCompiler
10
+
11
+ def intialize(base_path)
12
+ @base_path = base_path
13
+ end
6
14
 
7
- def self.compile(src, dest)
15
+ def compile(src, dest)
8
16
  output = LessJs.compile File.read(src)
9
17
  File.open(dest, 'w') do |f|
10
18
  f.write "/* This file is autogenerated; do not edit directly (edit #{src} instead) */\n\n"
@@ -1,18 +1,75 @@
1
- require 'sass'
1
+ require 'sass/plugin/configuration'
2
+
3
+ module Sass::Plugin::Configuration
4
+
5
+ def default_options
6
+ @default_options ||= {
7
+ :css_location => './public/stylesheets',
8
+ :always_update => false,
9
+ :always_check => true,
10
+ :full_exception => true,
11
+ :cache_location => File.join(Spider.paths[:tmp], 'sass', '.sass_cache')
12
+ }.freeze
13
+ end
14
+ end
15
+
2
16
  require 'sass/plugin'
3
17
 
4
- Sass::Plugin.options[:cache_location] = File.join(Spider.paths[:tmp], 'sass-cache')
18
+ require 'sass'
19
+
5
20
 
6
21
  module Spider
7
22
 
8
- module SassCompiler
23
+ class SassCompiler
24
+
25
+ def initialize(base_path)
26
+ @base_path = base_path
27
+ end
9
28
 
10
- def self.compile(src, dest)
11
- engine = Sass::Engine.for_file(src, {})
12
- output = engine.render
13
- File.open(dest, 'w') do |f|
14
- f.write "/* This file is autogenerated; do not edit directly (edit #{src} instead) */\n\n"
15
- f.write output
29
+ def compile(src, dest)
30
+ use_compass = false
31
+ if Spider.conf.get('css.sass.use_compass')
32
+ begin
33
+ require 'compass'
34
+ use_compass = true
35
+ rescue LoadError => exc
36
+ Spider.logger.debug(exc)
37
+ Spider.logger.debug("Compass not found. Please install 'compass' gem")
38
+ end
39
+ end
40
+ if use_compass
41
+ work_dir = FileUtils.mkdir_p(File.join(Spider.paths[:tmp], 'sass'))
42
+ src_dir = File.dirname(src)
43
+ src_dir = src_dir
44
+ # dest_dir = File.dirname(dest)
45
+
46
+ options = {
47
+ :project_path => @base_path,
48
+ :css_dir => 'css',
49
+ :sass_dir => 'sass',
50
+ # :fonts_path => src_dir,
51
+ # :images_path => src_dir,
52
+ :fonts_dir => 'fonts',
53
+ :images_dir => 'img',
54
+ :javascripts_dir => 'js',
55
+ :relative_assets => true,
56
+ :line_comments => Spider.runmode == 'devel' ? true : false,
57
+ :sass => Compass.sass_engine_options.merge({
58
+ :cache_location => File.join(work_dir, '.sass_cache')
59
+ }),
60
+ :css_filename => dest
61
+ }
62
+ config = Compass::Configuration::Data.new(:spider, options)
63
+ Compass.add_project_configuration(config)
64
+ compiler = Compass::Compiler.new(work_dir, File.dirname(src), File.dirname(dest), options)
65
+ compiler.compile(src, dest)
66
+ else
67
+ engine = Sass::Engine.for_file(src, {})
68
+ output = engine.render
69
+ File.open(dest, 'w') do |f|
70
+ f.write "/* This file is autogenerated; do not edit directly (edit #{src} instead) */\n\n"
71
+ f.write output
72
+ end
16
73
  end
17
74
  end
18
75
 
@@ -46,7 +46,7 @@ module Spider
46
46
 
47
47
  # Returns the class TemplateCache instance
48
48
  def cache
49
- @@cache ||= TemplateCache.new(Spider.paths[:var]+'/cache/templates')
49
+ @@cache ||= TemplateCache.new(File.join(Spider.paths[:var], 'cache', 'templates'))
50
50
  end
51
51
 
52
52
  # Sets allowed blocks
@@ -362,7 +362,7 @@ module Spider
362
362
  end
363
363
  compiled.block.init_code = res_init + compiled.block.init_code
364
364
  compiled.devel_info["source.xml"] = root.to_html
365
- compiled.assets = @assets + assets
365
+ compiled.assets = (@assets + assets).uniq
366
366
  return compiled
367
367
  end
368
368
 
@@ -407,6 +407,7 @@ module Spider
407
407
  controller = nil
408
408
  if res && res.definer
409
409
  controller = res.definer.controller
410
+ ass[:app] = res.definer unless res.definer.is_a?(Spider::Home)
410
411
  elsif owner_class < Spider::Controller
411
412
  controller = owner_class
412
413
  end
@@ -434,7 +435,7 @@ module Spider
434
435
  ass = processor.process(ass)
435
436
  end
436
437
  if cpr = attributes[:compressed]
437
- if cpr == "true"
438
+ if cpr == true || cpr == "true"
438
439
  ass[:compressed_path] = ass[:path]
439
440
  ass[:compressed_rel_path] = ass[:rel_path]
440
441
  ass[:compressed] = base_url + File.basename(ass[:path])
@@ -477,9 +478,14 @@ module Spider
477
478
  overrides.each{ |o| o.set_attribute('class', 'to_delete') }
478
479
  root.search('.to_delete').remove
479
480
  add_overrides overrides
481
+ our_domain = nil
482
+ if @definer_class
483
+ our_domain = @definer_class.respond_to?(:app) ? @definer_class.app.short_name : 'spider'
484
+ end
480
485
  @overrides += orig_overrides
481
486
  if root.name == 'tpl:extend'
482
487
  orig_overrides = @overrides
488
+
483
489
  @overrides = []
484
490
  ext_src = root.get_attribute('src')
485
491
  ext_app = root.get_attribute('app')
@@ -510,6 +516,9 @@ module Spider
510
516
  @dependencies << ext
511
517
  tpl = Template.new(ext)
512
518
  root = get_el(ext)
519
+ if ext_app.short_name != our_domain
520
+ root.set_attribute('tpl:text-domain', ext_app.short_name)
521
+ end
513
522
  root.children_of_type('tpl:asset').each do |ass|
514
523
  ass_src = ass.get_attribute('src')
515
524
  if ass_src && ass_src[0].chr != '/'
@@ -547,6 +556,10 @@ module Spider
547
556
  end
548
557
  end
549
558
  incl_el.search('.to_delete').remove
559
+ td = resource.definer.respond_to?(:app) ? resource.definer.app.short_name : 'spider'
560
+ if td != our_domain
561
+ incl_el.set_attribute('tpl:text-domain', td)
562
+ end
550
563
  incl.swap(incl_el.to_html)
551
564
  end
552
565
 
@@ -663,6 +676,11 @@ module Spider
663
676
  # - exec
664
677
  # - eval the template's compiled run code.
665
678
  def render(scene=nil)
679
+ prev_domain = nil
680
+ if @definer_class
681
+ td = @definer_class.respond_to?(:app) ? @definer_class.app.short_name : 'spider'
682
+ prev_domain = Spider::GetText.set_domain(td)
683
+ end
666
684
  scene ||= @scene
667
685
  load unless loaded?
668
686
  init(scene) unless init_done?
@@ -693,6 +711,7 @@ module Spider
693
711
  @content[yielded].render if @content[yielded]
694
712
  end
695
713
  end
714
+ Spider::GetText.restore_domain(prev_domain) if prev_domain
696
715
  # end
697
716
  end
698
717
 
@@ -777,7 +796,7 @@ module Spider
777
796
  elsif override.name == 'tpl:content'
778
797
  found = el.search("tpl:placeholder[@name='#{override.get_attribute('name')}']")
779
798
  else
780
- if ['sp:pass', 'tpl:pass', 'sp:template'].include?(el.name)
799
+ if ['sp:template'].include?(el.name)
781
800
  found = el.children.select{ |child| child.is_a?(Hpricot::Elem) }
782
801
  else
783
802
  found = [el]
@@ -803,7 +822,11 @@ module Spider
803
822
  elsif override.name == 'tpl:override' || override.name == 'tpl:content'
804
823
  overridden = f.to_html
805
824
  parent = f.parent
806
- f.swap(override.innerHTML)
825
+ if f == el
826
+ f.innerHTML = override.innerHTML
827
+ else
828
+ f.swap(override.innerHTML)
829
+ end
807
830
  parent.search('tpl:overridden').each do |o|
808
831
  ovr = overridden
809
832
  if o_search = o.get_attribute('search')
@@ -815,8 +838,10 @@ module Spider
815
838
  elsif override.name == 'tpl:override-attr'
816
839
  f.set_attribute(override.get_attribute("name"), override.get_attribute("value"))
817
840
  elsif override.name == 'tpl:append-attr'
818
- f.set_attribute(override.get_attribute("name"), \
819
- (f.get_attribute(override.get_attribute("name")) || '')+override.get_attribute("value"))
841
+ a = f.get_attribute(override.get_attribute("name")) || ''
842
+ a += ' ' unless a.blank?
843
+ a += override.get_attribute("value")
844
+ f.set_attribute(override.get_attribute("name"), a)
820
845
  elsif override.name == 'tpl:append'
821
846
  f.innerHTML += override.innerHTML
822
847
  elsif override.name == 'tpl:prepend'
@@ -854,7 +879,7 @@ module Spider
854
879
  end
855
880
 
856
881
  ExpressionOutputRegexp = /\{?\{\s([^\s].*?)\s\}\}?/
857
- GettextRegexp = /_\(([^\)]+)?\)(\s%\s([^\s,]+(?:,\s*\S+\s*)?))?/
882
+ GettextRegexp = /([snp][snp]?)?_\(([^\)]+)?\)(\s%\s([^\s,]+(?:,\s*\S+\s*)?))?/
858
883
  ERBRegexp = /(<%(.+)?%>)/
859
884
  SceneVarRegexp = /@(\w[\w\d_]+)/
860
885
 
@@ -875,8 +900,8 @@ module Spider
875
900
  yield :expr, $1, scanner.matched
876
901
  end
877
902
  when GettextRegexp
878
- gt = [$1]
879
- gt << $3 if $2 # interpolated vars
903
+ gt = {:val => $2, :func => $1}
904
+ gt[:vars] = $4 if $3 # interpolated vars
880
905
  yield :gettext, gt, scanner.matched
881
906
  when ERBRegexp
882
907
  yield :erb, $1, scanner.matched
@@ -45,6 +45,8 @@ module Spider
45
45
  block = :ParentContext
46
46
  elsif el.name == 'sp:recurse'
47
47
  block = :Recurse
48
+ elsif !skip_attributes && el.has_attribute?('tpl:text-domain')
49
+ block = :TextDomain
48
50
  elsif Spider::Template.registered?(el.name)
49
51
  klass = Spider::Template.get_registered_class(el.name)
50
52
  if klass < ::Spider::Widget
@@ -145,9 +147,9 @@ module Spider
145
147
  when :expr
146
148
  res += "'+("+vars_to_scene(val)+").to_s+'"
147
149
  when :gettext
148
- res += "'\n$out << _('#{escape_text(val[0])}')"
149
- if val[1]
150
- res += " #{vars_to_scene(val[1])}"
150
+ res += "'\n$out << _('#{escape_text(val[:val])}')"
151
+ if val[:vars]
152
+ res += " #{vars_to_scene(val[:vars])}"
151
153
  end
152
154
  res += "\n$out << '"
153
155
  end
@@ -217,5 +219,6 @@ require 'spiderfw/templates/blocks/layout_assets'
217
219
  require 'spiderfw/templates/blocks/layout_meta'
218
220
  require 'spiderfw/templates/blocks/lambda'
219
221
  require 'spiderfw/templates/blocks/recurse'
222
+ require 'spiderfw/templates/blocks/text_domain'
220
223
 
221
224
 
@@ -7,6 +7,7 @@ module Spider
7
7
  # and will pass log messages to each of its child.
8
8
 
9
9
  module Logger
10
+ @@levels = [:DEBUG, :WARN, :INFO, :ERROR]
10
11
 
11
12
  class << self
12
13
 
@@ -55,6 +56,7 @@ module Spider
55
56
  def send_to_loggers(action, *args, &proc)
56
57
  return if $SAFE > 1
57
58
  return unless @loggers
59
+ return if thread_level && !check_thread_level(action)
58
60
  @loggers.each do |dest, logger|
59
61
  begin
60
62
  logger.send(action, *args, &proc)
@@ -133,6 +135,24 @@ module Spider
133
135
  send_to_loggers(method, *args, &proc)
134
136
  end
135
137
 
138
+ def set_thread_level(level)
139
+ prev = Thread.current[:spider_logger_level]
140
+ Thread.current[:spider_logger_level] = @@levels.index(level)
141
+ return prev
142
+ end
143
+
144
+ def thread_level
145
+ Thread.current[:spider_logger_level]
146
+ end
147
+
148
+ def check_thread_level(action)
149
+ tl = thread_level
150
+ return unless tl
151
+ action_i = @@levels.index(action.to_s.upcase.to_sym)
152
+ return action_i > tl
153
+ end
154
+
155
+
136
156
  end
137
157
 
138
158
  def log(*args, &proc)