zena 0.15.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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