zena 0.15.2 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (284) hide show
  1. data/.gitignore +20 -0
  2. data/CREDITS +27 -0
  3. data/Capfile +3 -0
  4. data/DEVELOPERS +46 -0
  5. data/History.txt +15 -0
  6. data/MIT-LICENSE +19 -0
  7. data/Rakefile +44 -0
  8. data/TODO +24 -0
  9. data/TODO_ZENA_1_0 +23 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/documents_controller.rb +22 -56
  12. data/app/controllers/nodes_controller.rb +42 -27
  13. data/app/controllers/pings_controller.rb +19 -0
  14. data/app/controllers/relations_controller.rb +5 -1
  15. data/app/controllers/sites_controller.rb +1 -46
  16. data/app/controllers/user_sessions_controller.rb +47 -0
  17. data/app/controllers/users_controller.rb +1 -0
  18. data/app/controllers/versions_controller.rb +25 -7
  19. data/app/controllers/virtual_classes_controller.rb +1 -1
  20. data/app/helpers/application_helper.rb +1 -1
  21. data/app/models/comment.rb +2 -1
  22. data/app/models/contact_content.rb +2 -2
  23. data/app/models/data_entry.rb +5 -6
  24. data/app/models/document.rb +14 -10
  25. data/app/models/document_content.rb +4 -6
  26. data/app/models/iformat.rb +2 -2
  27. data/app/models/image_content.rb +6 -9
  28. data/app/models/node.rb +106 -164
  29. data/app/models/page.rb +0 -20
  30. data/app/models/site.rb +42 -12
  31. data/app/models/template.rb +3 -8
  32. data/app/models/template_content.rb +2 -0
  33. data/app/models/text_document.rb +13 -8
  34. data/app/models/user.rb +47 -100
  35. data/app/models/user_session.rb +4 -0
  36. data/app/models/version.rb +1 -1
  37. data/app/views/comments/create.rjs +3 -3
  38. data/app/views/comments/edit.rjs +1 -1
  39. data/app/views/comments/update.rjs +1 -1
  40. data/app/views/nodes/_import_results.rhtml +1 -1
  41. data/app/views/nodes/create.rjs +3 -3
  42. data/app/views/templates/document_create_tabs/_file.rhtml +1 -2
  43. data/app/views/templates/document_create_tabs/_import.rhtml +7 -2
  44. data/app/views/templates/edit_tabs/_document.rhtml +1 -3
  45. data/app/views/templates/edit_tabs/_image.rhtml +1 -3
  46. data/app/views/versions/_tr.rhtml +1 -1
  47. data/app/views/versions/edit.rhtml +2 -26
  48. data/bin/zena +6 -1
  49. data/bricks/delayed_job/README +18 -0
  50. data/bricks/delayed_job/migrate/20091104191643_create_delayed_jobs_table.rb +19 -0
  51. data/bricks/delayed_job/misc/init.rb +8 -0
  52. data/bricks/delayed_job/misc/tasks.rb +2 -0
  53. data/bricks/math/patch/application_helper.rb +1 -1
  54. data/bricks/sphinx/MIT-LICENSE +19 -0
  55. data/bricks/sphinx/README +19 -0
  56. data/bricks/sphinx/lib/use_sphinx.rb +78 -0
  57. data/bricks/sphinx/migrate/20091102171258_add_delta_for_sphinx.rb +9 -0
  58. data/bricks/sphinx/misc/deploy.rb +20 -0
  59. data/bricks/sphinx/misc/sphinx.yml +12 -0
  60. data/bricks/sphinx/misc/tasks.rb +21 -0
  61. data/bricks/sphinx/patch/node.rb +8 -0
  62. data/bricks/tags/lib/has_tags.rb +5 -3
  63. data/bricks/tags/test/zafu/tags.yml +13 -1
  64. data/config/bricks.yml +35 -0
  65. data/config/deploy.rb +8 -1
  66. data/config/environment.rb +1 -1
  67. data/config/environments/production.rb +1 -1
  68. data/config/gems.yml +28 -5
  69. data/config/sphinx.yml +12 -0
  70. data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -16
  71. data/db/migrate/20091026161708_add_persistence_token.rb +13 -0
  72. data/db/migrate/20091101184952_add_session_table.rb +16 -0
  73. data/db/migrate/20091123175137_add_single_access_token.rb +9 -0
  74. data/db/migrate/20091124161608_rebuild_fullpath.rb +11 -0
  75. data/db/schema.rb +21 -8
  76. data/doc/README_FOR_APP +24 -0
  77. data/doc/fixtures.graffle +19568 -0
  78. data/doc/fixtures.pdf +0 -0
  79. data/doc/template/LICENSE +184 -0
  80. data/doc/template/README +37 -0
  81. data/doc/template/allison.css +283 -0
  82. data/doc/template/allison.js +307 -0
  83. data/doc/template/allison.rb +260 -0
  84. data/doc/template/cache/BODY +588 -0
  85. data/doc/template/cache/CLASS_INDEX +4 -0
  86. data/doc/template/cache/CLASS_PAGE +1 -0
  87. data/doc/template/cache/FILE_INDEX +4 -0
  88. data/doc/template/cache/FILE_PAGE +1 -0
  89. data/doc/template/cache/FONTS +1 -0
  90. data/doc/template/cache/FR_INDEX_BODY +1 -0
  91. data/doc/template/cache/IMGPATH +1 -0
  92. data/doc/template/cache/INDEX +1 -0
  93. data/doc/template/cache/JAVASCRIPT +307 -0
  94. data/doc/template/cache/METHOD_INDEX +4 -0
  95. data/doc/template/cache/METHOD_LIST +1 -0
  96. data/doc/template/cache/SRC_PAGE +1 -0
  97. data/doc/template/cache/STYLE +283 -0
  98. data/doc/template/cache/URL +1 -0
  99. data/doc/zafu_changes.yml +29 -0
  100. data/lib/base_additions.rb +1 -1
  101. data/lib/bricks.rb +9 -0
  102. data/lib/bricks/loader.rb +86 -0
  103. data/lib/bricks/requirements_validation.rb +71 -0
  104. data/lib/tasks/zena.rake +42 -4
  105. data/lib/zafu/action.rb +285 -0
  106. data/lib/zafu/ajax.rb +93 -0
  107. data/lib/zafu/attributes.rb +117 -0
  108. data/lib/zafu/calendar.rb +159 -0
  109. data/lib/zafu/context.rb +330 -0
  110. data/lib/zafu/core/html.rb +102 -0
  111. data/lib/zafu/core/move_to_parser.rb +167 -0
  112. data/lib/zafu/dates.rb +58 -0
  113. data/lib/zafu/display.rb +502 -0
  114. data/lib/zafu/eval.rb +66 -0
  115. data/lib/zafu/experimental.rb +66 -0
  116. data/lib/zafu/i18n.rb +64 -0
  117. data/lib/zafu/meta.rb +25 -0
  118. data/lib/zafu/refactor.rb +73 -0
  119. data/lib/zafu/support/context.rb +265 -0
  120. data/lib/zafu/support/dom.rb +145 -0
  121. data/lib/zafu/support/erb.rb +62 -0
  122. data/lib/zafu/support/flow.rb +401 -0
  123. data/lib/zafu/support/forms.rb +461 -0
  124. data/lib/zafu/support/links.rb +306 -0
  125. data/lib/zafu_parser.rb +26 -2
  126. data/lib/zena.rb +34 -15
  127. data/lib/zena/acts/multiversion.rb +2 -2
  128. data/lib/zena/acts/secure.rb +41 -30
  129. data/lib/zena/app.rb +7 -10
  130. data/lib/zena/controller/test_case.rb +12 -7
  131. data/lib/zena/crypto_provider/initial.rb +15 -0
  132. data/lib/zena/db.rb +6 -1
  133. data/lib/zena/deploy.rb +34 -6
  134. data/lib/zena/deploy/logrotate_app.rhtml +9 -0
  135. data/lib/zena/deploy/logrotate_host.rhtml +34 -0
  136. data/lib/zena/deploy/template.rb +1 -9
  137. data/lib/zena/foxy_parser.rb +1 -1
  138. data/lib/zena/info.rb +3 -1
  139. data/lib/zena/migrator.rb +1 -1
  140. data/lib/zena/parser.rb +12 -4
  141. data/lib/zena/parser/zazen_rules.rb +6 -6
  142. data/lib/zena/parser/zena_rules.rb +1 -7
  143. data/lib/zena/routes.rb +5 -5
  144. data/lib/zena/test_controller.rb +7 -2
  145. data/lib/zena/unit/test_case.rb +6 -8
  146. data/lib/zena/use/ajax.rb +10 -10
  147. data/lib/zena/use/authlogic.rb +93 -0
  148. data/lib/zena/use/dyn_attributes.rb +5 -0
  149. data/lib/zena/use/html_tags.rb +16 -34
  150. data/lib/zena/use/i18n.rb +4 -1
  151. data/lib/zena/use/node_query_finders.rb +8 -4
  152. data/lib/zena/use/refactor.rb +8 -20
  153. data/lib/zena/use/relations.rb +1 -0
  154. data/lib/zena/use/rendering.rb +4 -2
  155. data/lib/zena/use/search.rb +52 -0
  156. data/lib/zena/use/test_helper.rb +27 -28
  157. data/lib/zena/use/upload.rb +188 -0
  158. data/lib/zena/use/urls.rb +16 -14
  159. data/lib/zena/use/zafu.rb +16 -63
  160. data/lib/zena/use/zazen.rb +8 -8
  161. data/lib/zena/view/test_case.rb +8 -4
  162. data/locale/en/LC_MESSAGES/zena.mo +0 -0
  163. data/locale/en/zena.po +3 -3
  164. data/public/.htaccess +40 -0
  165. data/public/javascripts/upload-progress.js +17 -8
  166. data/public/javascripts/zena.js +8 -2
  167. data/public/stylesheets/popup.css +1 -0
  168. data/script/about +3 -0
  169. data/script/apache_logging +25 -0
  170. data/script/breakpointer +3 -0
  171. data/script/console +3 -0
  172. data/script/dbconsole +3 -0
  173. data/script/destroy +3 -0
  174. data/script/generate +3 -0
  175. data/script/performance/benchmarker +3 -0
  176. data/script/performance/profiler +3 -0
  177. data/script/plugin +3 -0
  178. data/script/process/inspector +3 -0
  179. data/script/process/reaper +3 -0
  180. data/script/process/spawner +3 -0
  181. data/script/runner +3 -0
  182. data/script/server +3 -0
  183. data/script/set_revision +29 -0
  184. data/spec/controllers/versions_controller_spec.rb +11 -0
  185. data/test/fixtures/files/Node-test.zafu +1 -1
  186. data/test/functional/nodes_controller_test.rb +25 -0
  187. data/test/functional/pings_controller_test.rb +8 -0
  188. data/test/functional/user_sessions_controller_test.rb +59 -0
  189. data/test/functional/users_controller_test.rb +81 -19
  190. data/test/helpers/node_query/filters.yml +5 -0
  191. data/test/helpers/node_query_test.rb +3 -3
  192. data/test/integration/multiple_hosts_test.rb +1 -1
  193. data/test/integration/navigation_test.rb +1 -1
  194. data/test/sites/complex/users.yml +1 -1
  195. data/test/sites/ocean/users.yml +3 -3
  196. data/test/sites/zena/users.yml +5 -4
  197. data/test/test_zena.rb +38 -38
  198. data/test/unit/cached_page_test.rb +2 -2
  199. data/test/unit/comment_test.rb +0 -1
  200. data/test/unit/document_test.rb +23 -11
  201. data/test/unit/helpers/ping_helper_test.rb +4 -0
  202. data/test/unit/multiversion_test.rb +24 -16
  203. data/test/unit/node_test.rb +32 -93
  204. data/test/unit/note_test.rb +9 -0
  205. data/test/unit/page_test.rb +2 -2
  206. data/test/unit/secure_test.rb +2 -12
  207. data/test/unit/site_test.rb +43 -24
  208. data/test/unit/template_test.rb +45 -3
  209. data/test/unit/text_document_test.rb +4 -3
  210. data/test/unit/user_test.rb +13 -33
  211. data/test/unit/zena/db_test.rb +8 -0
  212. data/test/unit/zena/parser/zazen.yml +4 -4
  213. data/test/unit/zena/use/dates_view_methods_test.rb +2 -1
  214. data/test/unit/zena/use/html_tags_test.rb +12 -4
  215. data/test/unit/zena/use/refactor_test.rb +4 -3
  216. data/test/unit/zena/use/rendering_test.rb +1 -0
  217. data/test/unit/zena/use/upload_test.rb +76 -0
  218. data/test/unit/zena/use/urls_test.rb +4 -0
  219. data/test/unit/zena/use/zafu_test.rb +8 -0
  220. data/test/unit/zena/workflow/status_version_test.rb +6 -0
  221. data/test/unit/zena/zena_tags/ajax.yml +4 -4
  222. data/test/unit/zena/zena_tags/basic.yml +21 -10
  223. data/test/unit/zena/zena_tags/relations.yml +0 -6
  224. data/test/unit/zena/zena_tags/rubyless.yml +35 -0
  225. data/test/unit/zena/zena_tags/zazen.yml +4 -4
  226. data/test/unit/zena/zena_tags_test.rb +36 -4
  227. data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +1 -1
  228. data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +2 -3
  229. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
  230. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +102 -58
  231. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
  232. data/vendor/TextMate/Zena.tmbundle/info.plist +2 -0
  233. data/zena.gemspec +2085 -0
  234. metadata +265 -90
  235. data/app/controllers/sessions_controller.rb +0 -41
  236. data/app/views/sites/zena_up.html.erb +0 -11
  237. data/config/database.yml +0 -40
  238. data/db/production.sqlite3 +0 -0
  239. data/lib/bricks/patcher.rb +0 -68
  240. data/lib/zena/parser/zena_tags.rb +0 -3562
  241. data/lib/zena/use/authentification.rb +0 -120
  242. data/public/images/ext/contact_pv.png +0 -0
  243. data/public/images/ext/other_pv.png +0 -0
  244. data/public/images/ext/page_pv.png +0 -0
  245. data/public/images/ext/page_tiny.png +0 -0
  246. data/public/images/ext/pdf_pv.png +0 -0
  247. data/public/images/ext/post_pv.png +0 -0
  248. data/public/images/ext/post_tiny.png +0 -0
  249. data/public/images/ext/project_pv.png +0 -0
  250. data/public/images/ext/project_tiny.png +0 -0
  251. data/public/images/ext/tag_pv.png +0 -0
  252. data/public/images/ext/zip_pv.png +0 -0
  253. data/tasks/ann.rake +0 -80
  254. data/tasks/bones.rake +0 -20
  255. data/tasks/gem.rake +0 -201
  256. data/tasks/git.rake +0 -40
  257. data/tasks/notes.rake +0 -27
  258. data/tasks/post_load.rake +0 -34
  259. data/tasks/rdoc.rake +0 -51
  260. data/tasks/rubyforge.rake +0 -55
  261. data/tasks/setup.rb +0 -292
  262. data/tasks/spec.rake +0 -54
  263. data/tasks/svn.rake +0 -47
  264. data/tasks/test.rake +0 -40
  265. data/tasks/zentest.rake +0 -36
  266. data/test/fixtures/comments.yml +0 -126
  267. data/test/fixtures/contact_contents.yml +0 -132
  268. data/test/fixtures/data_entries.yml +0 -65
  269. data/test/fixtures/discussions.yml +0 -48
  270. data/test/fixtures/document_contents.yml +0 -108
  271. data/test/fixtures/dyn_attributes.yml +0 -66
  272. data/test/fixtures/groups.yml +0 -86
  273. data/test/fixtures/groups_users.yml +0 -81
  274. data/test/fixtures/iformats.yml +0 -29
  275. data/test/fixtures/links.yml +0 -313
  276. data/test/fixtures/nodes.yml +0 -2592
  277. data/test/fixtures/relations.yml +0 -126
  278. data/test/fixtures/sites.yml +0 -58
  279. data/test/fixtures/template_contents.yml +0 -172
  280. data/test/fixtures/users.yml +0 -167
  281. data/test/fixtures/versions.yml +0 -1911
  282. data/test/fixtures/virtual_classes.yml +0 -87
  283. data/test/fixtures/zips.yml +0 -15
  284. data/test/functional/sessions_controller_test.rb +0 -73
@@ -0,0 +1,66 @@
1
+ module Zafu
2
+ module Eval
3
+
4
+ def r_set
5
+ return parser_error("'var' missing") unless var_name = @params[:var]
6
+ return parser_error("bad value for 'var' (#{var_name.inspect})") unless var_name =~ /^[a-zA-Z_]+$/
7
+ return '' unless @context[:set]
8
+ if @params[:value]
9
+ out "<% set_#{var_name} = #{@params[:value].inspect} -%>"
10
+ # TODO: isn't @context[:vars] = @params[:value].inspect missing here ?
11
+ elsif @params[:eval]
12
+ return unless eval_string = parse_eval_parameter(@params[:eval])
13
+ out "<% set_#{var_name} = #{eval_string} -%>"
14
+ else
15
+ out "<% set_#{var_name} = capture do %>"
16
+ out expand_with(:set => false) # do not propagate
17
+ out "<% end -%>"
18
+ end
19
+ end
20
+
21
+ def parse_eval_parameter(str)
22
+ # evaluate an expression. Can only contain vars, '(', ')', '*', '+', '/', '-', '[attr]'
23
+ # FIXME: SECURITY (audit this)
24
+ vars = @context[:vars] || []
25
+ parts = str.split(/\s+/)
26
+ res = []
27
+ test = []
28
+ parts.each do |p|
29
+ if p =~ /\[([\w_]+)\]/
30
+ test << 1
31
+ res << (node_attribute($1) + '.to_f')
32
+ elsif p =~ /^[a-zA-Z_]+$/
33
+ unless vars.include?(p)
34
+ out parser_error("var #{p.inspect} not set in eval")
35
+ return nil
36
+ end
37
+ test << 1
38
+ res << "set_#{p}.to_f"
39
+ elsif ['(', ')', '*', '+', '/', '-'].include?(p)
40
+ res << p
41
+ test << p
42
+ elsif p =~ /^[0-9\.]+$/
43
+ res << p
44
+ test << p
45
+ else
46
+ out parser_error("bad argument #{p.inspect} in eval")
47
+ return nil
48
+ end
49
+ end
50
+ begin
51
+ begin
52
+ eval test.join(' ')
53
+ rescue
54
+ # rescue evaluation error
55
+ out parser_error("error in eval")
56
+ return nil
57
+ end
58
+ "(#{res.join(' ')})"
59
+ rescue SyntaxError => err
60
+ # rescue compilation error
61
+ out parser_error("compilation error in eval")
62
+ return nil
63
+ end
64
+ end
65
+ end # Eval
66
+ end # Zafu
@@ -0,0 +1,66 @@
1
+ module Zafu
2
+ module Experimental
3
+
4
+ # part caching
5
+ def r_cache
6
+ kpath = @params[:kpath] || Page.kpath
7
+ out "<% #{cache} = Cache.with(visitor.id, visitor.group_ids, #{kpath.inspect}, #{helper.send(:lang).inspect}, #{template_url.inspect}) do capture do %>"
8
+ out expand_with
9
+ out "<% end; end %><%= #{cache} %>"
10
+ end
11
+
12
+ def cache
13
+ return @cache if @cache
14
+ if @context[:cache] =~ /^cache(\d+)$/
15
+ @cache = "cache#{$1.to_i + 1}"
16
+ else
17
+ @cache = "cache1"
18
+ end
19
+ end
20
+
21
+ def r_flash_messages
22
+ type = @params[:show] || 'both'
23
+ "<div id='messages'>" +
24
+ if (type == 'notice' || type == 'both')
25
+ "<% if flash[:notice] -%><div id='notice' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:notice] %></div><% end -%>"
26
+ else
27
+ ''
28
+ end +
29
+ if (type == 'error' || type == 'both')
30
+ "<% if flash[:error] -%><div id='error' class='flash' onclick='new Effect.Fade(\"error\")'><%= flash[:error] %></div><% end -%>"
31
+ else
32
+ ''
33
+ end +
34
+ "</div>"
35
+ end
36
+
37
+ # Prepare stylesheet and xml content for xsl-fo post-processor
38
+ def r_fop
39
+ return parser_error("missing 'stylesheet' argument") unless @params[:stylesheet]
40
+ # get stylesheet text
41
+ xsl_content, absolute_url, doc = self.class.get_template_text(@params[:stylesheet], @options[:helper], @options[:current_folder])
42
+ return parser_error("stylesheet #{@params[:stylesheet].inspect} not found") unless doc
43
+
44
+ template_url = (self.template_url.split('/')[0..-2] + ['_main.xsl']).join('/')
45
+ helper.save_erb_to_url(xsl_content, template_url)
46
+ out "<?xml version='1.0' encoding='utf-8'?>\n"
47
+ out "<!-- xsl_id:#{doc[:id] } -->\n" if doc
48
+ out expand_with
49
+ end
50
+
51
+ # Prepare content for LateX post-processor
52
+ def r_latex
53
+ out "% latex\n"
54
+ # all content inside this will be informed to render for Latex output
55
+ out expand_with(:output_format => 'latex')
56
+ end
57
+
58
+ def r_inspect
59
+ out ["params: #{@params.inspect}",
60
+ "name: #{@context[:name]}",
61
+ "node: #{node}",
62
+ "list: #{list}"].join("<br/>")
63
+ end
64
+
65
+ end # Experimental
66
+ end # Zafu
@@ -0,0 +1,64 @@
1
+ module Zafu
2
+ module I18n
3
+ def r_load
4
+ if dict = @params[:dictionary]
5
+ dict_content, absolute_url, doc = self.class.get_template_text(dict, @options[:helper], @options[:current_folder])
6
+ return parser_error("dictionary #{dict.inspect} not found") unless doc
7
+ @context[:dict] ||= {}
8
+ begin
9
+ definitions = YAML::load(dict_content)
10
+ definitions['translations'].each do |elem|
11
+ @context[:dict][elem[0]] = elem[1]
12
+ end
13
+ rescue
14
+ return parser_error("invalid dictionary content #{dict.inspect}")
15
+ end
16
+ else
17
+ return parser_error("missing 'dictionary'")
18
+ end
19
+ expand_with
20
+ end
21
+
22
+ def _(text)
23
+ if @context[:dict]
24
+ @context[:dict][text] || helper.send(:_,text)
25
+ else
26
+ helper.send(:_,text)
27
+ end
28
+ end
29
+
30
+ def r_trans
31
+ static = true
32
+ if @params[:text]
33
+ text = @params[:text]
34
+ elsif @params[:attr]
35
+ text = "#{node_attribute(@params[:attr])}"
36
+ static = false
37
+ else
38
+ res = []
39
+ text = ""
40
+ @blocks.each do |b|
41
+ if b.kind_of?(String)
42
+ res << b.inspect
43
+ text << b
44
+ elsif ['show', 'current_date'].include?(b.method)
45
+ res << expand_block(b, :trans=>true)
46
+ static = false
47
+ else
48
+ # ignore
49
+ end
50
+ end
51
+ unless static
52
+ text = res.join(' + ')
53
+ end
54
+ end
55
+ if static
56
+ _(text)
57
+ else
58
+ "<%= _(#{text}) %>"
59
+ end
60
+ end
61
+
62
+ alias r_t r_trans
63
+ end # I18n
64
+ end # Zafu
@@ -0,0 +1,25 @@
1
+ module Zafu
2
+ module Meta
3
+
4
+ def r_debug
5
+ return '' unless @context[:dev]
6
+ add_html_class('debug')
7
+ out "<p>#{@params[:title] || @params[:message]}</p>" if @params[:title] || @params[:message]
8
+ (@params[:show] || '').split(',').map(&:strip).each do |what|
9
+ case what
10
+ when 'params'
11
+ out "<pre><%= params.inspect %></pre>"
12
+ when 'class'
13
+ out "<pre>expected: #{node_class} / got: <%= #{node}.class %></pre>"
14
+ else
15
+ parser_error("invalid element to show. Options are ['params', 'class'].")
16
+ end
17
+ end
18
+ out expand_with
19
+ end
20
+
21
+ def parser_error(message, tag=@method)
22
+ "<span class='parser_error'>[#{tag}] #{message}</span>"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,73 @@
1
+ module Zafu
2
+ module Refactor
3
+ def r_node
4
+ @method = @params[:select] || 'node' # 'node' is for version.node
5
+ r_unknown
6
+ end
7
+
8
+ def base_class
9
+ if node_kind_of?(Node)
10
+ Node
11
+ elsif node_kind_of?(Version)
12
+ Version
13
+ else
14
+ node_class
15
+ end
16
+ end
17
+
18
+ # get current output format
19
+ def output_format
20
+ @context[:output_format] || 'html'
21
+ end
22
+
23
+ # icon or first image (defined using build_finder_for instead of zafu_known_context for performance reasons).
24
+ def r_icon
25
+ if !@params[:in] && !@params[:where] && !@params[:from] && !@params[:find]
26
+ finder, klass = build_finder_for(:first, 'icon', @params.merge(:or => 'image', :order => 'l_id desc, position asc, name asc', :group => 'id,l_id'))
27
+ return unless finder
28
+ return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
29
+ do_var(finder, :node_class => klass)
30
+ else
31
+ r_unknown
32
+ end
33
+ end
34
+
35
+ # be carefull, this gives a list of 'versions', not 'nodes'
36
+ def r_traductions
37
+ if @params[:except]
38
+ case @params[:except]
39
+ when 'current'
40
+ opts = "(:conditions=>\"lang != '#{helper.lang}'\")"
41
+ else
42
+ # list of lang
43
+ # TODO: test
44
+ langs = @params[:except].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
45
+ opts = "(:conditions=>\"lang NOT IN ('#{langs.join("','")}')\")"
46
+ end
47
+ elsif @params[:only]
48
+ # TODO: test
49
+ case @params[:only]
50
+ when 'current'
51
+ opts = "(:conditions=>\"lang = '#{helper.lang}'\")"
52
+ else
53
+ # list of lang
54
+ # TODO: test
55
+ langs = @params[:only].split(',').map{|l| l.gsub(/[^a-z]/,'').strip }
56
+ opts = "(:conditions=>\"lang IN ('#{langs.join("','")}')\")"
57
+ end
58
+ else
59
+ opts = ""
60
+ end
61
+ out "<% if #{list_var} = #{node}.traductions#{opts} -%>"
62
+ out expand_with(:list=>list_var, :node_class => Version)
63
+ out "<% end -%>"
64
+ end
65
+
66
+ # TODO: test
67
+ def r_show_traductions
68
+ "<% if #{list_var} = #{node}.traductions -%>"
69
+ "#{_("Traductions:")} <span class='traductions'><%= #{list_var}.join(', ') %></span>"
70
+ "<%= traductions(:node=>#{node}).join(', ') %>"
71
+ end
72
+ end # Refactor
73
+ end # Zafu
@@ -0,0 +1,265 @@
1
+ module Zafu
2
+ module Support
3
+ module Context
4
+
5
+ # use all other tags as rubyless or relations
6
+ def r_unknown
7
+ context = change_context(@method)
8
+ open_context(context)
9
+ end
10
+
11
+
12
+ # Enter a new context (<r:context find='all' select='pages'>). This is the same as '<r:pages>...</r:pages>'). It is
13
+ # considered better style to use '<r:pages>...</r:pages>' instead of the more general '<r:context>' because the tags
14
+ # give a clue on the context at start and end. Another way to open a context is the 'do' syntax: "<div do='pages'>...</div>".
15
+ # FIXME: 'else' clause has been removed, find a solution to put it back.
16
+ def r_context
17
+ # DRY ! (build_finder_for, block)
18
+ return parser_error("missing 'select' parameter") unless method = @params[:select]
19
+ context = change_context(method, :skip_rubyless => true)
20
+ open_context(context)
21
+
22
+ #context = RubyLess::SafeClass.safe_method_type_for(node_class, [method]) if use_rubyless
23
+ #if context && @params.keys == [:select]
24
+ # open_context("#{node}.#{context[:method]}", context.dup)
25
+ #elsif node_kind_of?(Node)
26
+ # count = ['first','all','count'].include?(@params[:find]) ? @params[:find].to_sym : nil
27
+ # count ||= Node.plural_relation?(method) ? :all : :first
28
+ # finder, klass, query = build_finder_for(count, method, @params)
29
+ # return unless finder
30
+ # if node_kind_of?(Node) && !klass.ancestors.include?(Node)
31
+ # # moving out of node: store last Node
32
+ # @context[:previous_node] = node
33
+ # end
34
+ # if count == :all
35
+ # # plural
36
+ # do_list( finder, query, :node_class => klass)
37
+ # # elsif count == :count
38
+ # # "<%= #{build_finder_for(count, method, @params)} %>"
39
+ # else
40
+ # # singular
41
+ # do_var( finder, :node_class => klass)
42
+ # end
43
+ #else
44
+ # "unknown relation (#{method}) for #{node_class} class"
45
+ #end
46
+ end
47
+
48
+ # Group elements in a list. Use :order to specify order.
49
+ def r_group
50
+ return parser_error("cannot be used outside of a list") unless list_var = @context[:list]
51
+ return parser_error("missing 'by' clause") unless key = @params[:by]
52
+
53
+ sort_key = @params[:sort] || 'name'
54
+ if node_kind_of?(DataEntry) && DataEntry::NodeLinkSymbols.include?(key.to_sym)
55
+ key = "#{key}_id"
56
+ sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
57
+ group_array = "group_array(#{list_var}) {|e| e.#{key}}"
58
+ elsif node_kind_of?(Node)
59
+ if ['project', 'parent', 'section'].include?(key)
60
+ sort_block = "{|e| (e.#{key} || {})[#{sort_key.to_sym.inspect}]}"
61
+ group_array = "group_array(#{list_var}) {|e| e.#{key}_id}"
62
+ end
63
+ end
64
+
65
+ group_array ||= "group_array(#{list_var}) {|e| #{node_attribute(key, :node => 'e')}}"
66
+
67
+ if sort_block
68
+ out "<% grp_#{list_var} = sort_array(#{group_array}) #{sort_block} -%>"
69
+ else
70
+ out "<% grp_#{list_var} = #{group_array} -%>"
71
+ end
72
+
73
+ if descendant('each_group')
74
+ out expand_with(:group => "grp_#{list_var}")
75
+ else
76
+ @context[:group] = "grp_#{list_var}"
77
+ r_each_group
78
+ end
79
+ end
80
+
81
+ protected
82
+
83
+ # find the current node name in the context
84
+ def node(klass = self.node_class)
85
+ if klass == self.node_class
86
+ (@context[:saved_template] && @context[:main_node]) ? "@#{base_class.to_s.underscore}" : (@context[:node] || '@node')
87
+ elsif klass == Node
88
+ @context[:previous_node] || '@node'
89
+ else
90
+ # ?
91
+ out parser_error("could not find node_name for #{klass} (current class is #{node_class})")
92
+ '@node'
93
+ end
94
+ end
95
+
96
+ def var
97
+ return @var if @var
98
+ if node =~ /^var(\d+)$/
99
+ @var = "var#{$1.to_i + 1}"
100
+ else
101
+ @var = "var1"
102
+ end
103
+ end
104
+
105
+ def list_var
106
+ return @list_var if @list_var
107
+ if (list || "") =~ /^list(\d+)$/
108
+ @list_var = "list#{$1.to_i + 1}"
109
+ else
110
+ @list_var = "list1"
111
+ end
112
+ end
113
+
114
+ # Class of the current 'node' object (can be Version, Comment, Node, DataEntry, etc)
115
+ def node_class
116
+ @context[:node_class] || Node
117
+ end
118
+
119
+ def node_kind_of?(ancestor)
120
+ node_class.ancestors.include?(ancestor)
121
+ end
122
+
123
+ def list
124
+ @context[:list]
125
+ end
126
+
127
+ def helper
128
+ @options[:helper]
129
+ end
130
+
131
+ # Return parameter value accessor
132
+ def get_param(key)
133
+ "params[:#{key}]"
134
+ end
135
+
136
+ def find_stored(klass, key)
137
+ if "#{klass}_#{key}" == "Node_start_node"
138
+ # main node before ajax stuff (the one in browser url)
139
+ "start_node"
140
+ else
141
+ @context["#{klass}_#{key}"]
142
+ end
143
+ end
144
+
145
+ def set_stored(klass, key, obj)
146
+ @context["#{klass}_#{key}"] = obj
147
+ end
148
+
149
+ def open_context(context)
150
+ return nil unless context
151
+ klass = context.delete(:class)
152
+ if klass.kind_of?(Class) && klass.ancestors.include?(String) && (@blocks.empty? || @blocks.size == 1 && @blocks[0].kind_of?(String))
153
+ out "<%= #{context[:method]} %>"
154
+ return
155
+ end
156
+ # hack to store last 'Node' context until we fix node(Node) stuff:
157
+ previous_node = node_kind_of?(Node) ? node : @context[:previous_node]
158
+ if klass.kind_of?(Array)
159
+ # plural
160
+ do_list( context[:method], context.merge(:node_class => klass[0], :previous_node => previous_node) )
161
+ else
162
+ # singular
163
+ do_var( context[:method], context.merge(:node_class => klass, :previous_node => previous_node) )
164
+ end
165
+ end
166
+
167
+ def do_var(var_finder=nil, opts={})
168
+ clear_dom_scope
169
+ if var_finder == 'nil'
170
+ out "<% if nil -%>"
171
+ elsif var_finder
172
+ out "<% if #{var} = #{var_finder} -%>"
173
+ end
174
+
175
+ if descendant('unlink')
176
+ @html_tag ||= 'div'
177
+ new_dom_scope
178
+ @html_tag_params[:id] = erb_dom_id
179
+ end
180
+
181
+ res = expand_with(opts.merge(:node=>var, :in_if => false))
182
+
183
+ if var_finder
184
+ res += expand_with(opts.merge(:in_if => true, :only => ['else', 'elsif'], :html_tag_params => @html_tag_params, :html_tag => @html_tag))
185
+ end
186
+ out render_html_tag(res)
187
+ out "<% end -%>" if var_finder
188
+ end
189
+
190
+ def do_list(list_finder, opts={})
191
+ clear_dom_scope
192
+ query = opts[:query]
193
+
194
+ @context.merge!(opts) # pass options from 'safe_method_type_for' to @context
195
+
196
+ if (each_block = descendant('each')) && (each_block.descendant('edit') || descendant('add') || descendant('add_document') || (descendant('swap') && descendant('swap').parent.method != 'block') || ['block', 'drop'].include?(each_block.single_child_method))
197
+ new_dom_scope
198
+ # ajax, build template. We could merge the following code with 'r_block'.
199
+ add_block = descendant('add')
200
+ form_block = descendant('form') || each_block
201
+
202
+ @context[:need_link_id] = form_block.need_link_id
203
+
204
+ out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
205
+ if query && (pagination_key = query.pagination_key)
206
+ out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
207
+ @context[:paginate] = pagination_key
208
+ @context[:vars] ||= []
209
+ @context[:vars] << "#{pagination_key}_nodes"
210
+ @context[:vars] << "#{pagination_key}_count"
211
+ @context[:vars] << pagination_key
212
+ end
213
+
214
+ # should we publish ?
215
+ publish_after_save ||= form_block ? form_block.params[:publish] : nil
216
+ publish_after_save ||= descendant('edit') ? descendant('edit').params[:publish] : nil
217
+
218
+ # class name for create form
219
+ klass = add_block ? add_block.params[:klass] : nil
220
+ klass ||= form_block ? form_block.params[:klass] : nil
221
+
222
+ # INLINE ==========
223
+ # 'r_add' needs the form when rendering. Send with :form.
224
+ out render_html_tag(expand_with(:list=>list_var, :in_if => false, :form=>form_block, :publish_after_save => publish_after_save, :ignore => ['form'], :klass => klass))
225
+ out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
226
+ out "<% end -%>"
227
+
228
+ # SAVED TEMPLATE ========
229
+ template = expand_block(each_block, :list=>false, :klass => klass, :saved_template => true)
230
+ out helper.save_erb_to_url(template, template_url)
231
+
232
+ # FORM ============
233
+ if each_block != form_block
234
+ form = expand_block(form_block, :klass => klass, :add=>add_block, :publish_after_save => publish_after_save, :saved_template => true)
235
+ else
236
+ form = expand_block(form_block, :klass => klass, :add=>add_block, :make_form=>true, :publish_after_save => publish_after_save, :saved_template => true)
237
+ end
238
+ out helper.save_erb_to_url(form, form_url)
239
+ else
240
+ # no form, render, edit and add are not ajax
241
+ if descendant('add') || descendant('add_document')
242
+ out "<% if (#{list_var} = #{list_finder}) || (#{node}.#{node_kind_of?(Comment) ? "can_comment?" : "can_write?"} && #{list_var}=[]) -%>"
243
+ elsif list_finder != 'nil'
244
+ out "<% if #{list_var} = #{list_finder} -%>"
245
+ else
246
+ out "<% if nil -%>"
247
+ end
248
+
249
+ if query && (pagination_key = query.pagination_key)
250
+ out "<% set_#{pagination_key}_nodes = #{query.finder(:count)}; set_#{pagination_key}_count = (set_#{pagination_key}_nodes / #{query.page_size.to_f}).ceil; set_#{pagination_key} = [1,params[:#{pagination_key}].to_i].max -%>"
251
+ @context[:paginate] = pagination_key
252
+ @context[:vars] ||= []
253
+ @context[:vars] << "#{pagination_key}_nodes"
254
+ @context[:vars] << "#{pagination_key}_count"
255
+ @context[:vars] << "#{pagination_key}"
256
+ end
257
+
258
+ out render_html_tag(expand_with(:list=>list_var, :in_if => false))
259
+ out expand_with(:in_if=>true, :only=>['elsif', 'else'], :html_tag => @html_tag, :html_tag_params => @html_tag_params)
260
+ out "<% end -%>"
261
+ end
262
+ end
263
+ end # Context
264
+ end # Support
265
+ end # Zafu