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,102 @@
1
+ module Zafu
2
+ module Core
3
+ module HTML
4
+ def get_html_params(params, tag_type)
5
+ res = {}
6
+ params.each do |k,v|
7
+ next unless v
8
+ if k.to_s =~ /\A(t?)set_(.+)$/
9
+ key = $2
10
+ trans = $1 == 't'
11
+ value, static = parse_attributes_in_value(v, :erb => !trans)
12
+
13
+ if trans
14
+ if static
15
+ value = ["'#{_(value)}'"] # array so it is not escaped on render
16
+ else
17
+ value = ["'<%= _(\"#{value}\") %>'"] # FIXME: use dict ! array so it is not escaped on render
18
+ end
19
+ end
20
+ res[key.to_sym] = value
21
+ elsif tag_type == :link && k == :_name
22
+ # :_name set by r_anchor
23
+ res[:name] ||= v
24
+ elsif tag_type == :link && ![:style, :class, :id, :title].include?(k)
25
+ # bad html parameter for links (some keys for link tags are used as query parameters)
26
+ # filter out
27
+ else
28
+ res[k] ||= v
29
+ end
30
+ end
31
+
32
+ #if params[:anchor]
33
+ # @anchor_param = nil
34
+ # res[:name] = anchor_name(params[:anchor], node)
35
+ #end
36
+
37
+ res
38
+ end
39
+
40
+ # Add a class name to the html_tag
41
+ def add_html_class(class_name)
42
+ if klass = @html_tag_params[:class]
43
+ @html_tag_params[:class] = "#{class_name} #{klass}"
44
+ else
45
+ @html_tag_params[:class] = class_name
46
+ end
47
+ end
48
+
49
+ def render_html_tag(text,*append)
50
+ append ||= []
51
+ return text if @html_tag_done
52
+ set_params = {}
53
+ if_params = {}
54
+ @params.each do |k,v|
55
+ if k.to_s =~ /^t?set_/
56
+ set_params[k] = v
57
+ end
58
+ end
59
+ tag_class = @html_tag_params[:class] || @params[:class]
60
+ if node_kind_of?(Node)
61
+
62
+ if @context[:make_form]
63
+ node_name = node
64
+ elsif (@method == 'each' || @method == 'each_group') && @context[:list]
65
+ node_name = var
66
+ elsif @method == 'context' || !respond_to?("r_#{@method}".to_sym)
67
+ node_name = @var || node
68
+ else
69
+ node_name = node
70
+ end
71
+
72
+ class_cond = nil
73
+ @params.each do |k,v|
74
+ if k.to_s =~ /^(.+)_if$/
75
+ klass = $1
76
+ cond = get_test_condition(node_name, :test => v)
77
+ elsif k.to_s =~ /^(.+)_if_(test|node|kind_of|klass|status|lang|can|in)$/
78
+ klass = $1
79
+ cond = get_test_condition(node_name, $2.to_sym => v)
80
+ end
81
+ if cond
82
+ class_cond = "#{cond} ? \" class='#{klass}'\" : #{class_cond}" # (x = 3) ? "class='foo'" :
83
+ end
84
+ end
85
+
86
+ if class_cond
87
+ append << "<%= #{class_cond}\"#{tag_class ? " class='#{tag_class}'" : ""}\" %>"
88
+ @html_tag_params.delete(:class)
89
+ end
90
+ end
91
+
92
+ @html_tag = 'div' if !@html_tag && (set_params != {} || @html_tag_params != {})
93
+
94
+ bak = @html_tag_params.dup
95
+ @html_tag_params = get_html_params(set_params.merge(@html_tag_params), @html_tag)
96
+ res = super(text,*append)
97
+ @html_tag_params = bak
98
+ res
99
+ end
100
+ end # HTML
101
+ end # Core
102
+ end # Zafu
@@ -0,0 +1,167 @@
1
+ # Elements here should be moved to the core zafu parser
2
+ module Zafu
3
+ module Core
4
+ module MoveToParser
5
+ def before_render
6
+ return unless super
7
+
8
+ @var = nil # reset var counter
9
+
10
+ if key = @params[:store]
11
+ set_stored(Node, key, node)
12
+ end
13
+
14
+ if key = @params[:store_date]
15
+ set_stored(Date, key, current_date)
16
+ end
17
+ if @method != 'link'
18
+ @anchor_param = @params[:anchor]
19
+ end
20
+
21
+ true
22
+ end
23
+
24
+
25
+ def after_render(text)
26
+ if @anchor_param
27
+ @params[:anchor] = @anchor_param # set back in case of double rendering so it is computed again
28
+ r_anchor + super
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ # Our special version of r_expand_with tag with "set_" parsing.
35
+ def r_expand_with
36
+ hash = {}
37
+ @params.each do |k,v|
38
+ if k.to_s =~ /^set_(.+)$/
39
+ # TODO: DRY with render_html_tag
40
+ k = $1
41
+ value, static = parse_attributes_in_value(v, :erb => false)
42
+ hash["exp_#{k}"] = static ? value.inspect : "\"#{value}\""
43
+ else
44
+ hash["exp_#{k}"] = v.inspect
45
+ end
46
+ end
47
+ @params = {}
48
+ expand_with(hash)
49
+ end
50
+
51
+ def expand_with(acontext={})
52
+ # set variables
53
+ context = nil
54
+ pre = ''
55
+ @blocks.each do |block|
56
+ next if block.kind_of?(String) || block.method != 'set'
57
+ @context[:vars] ||= []
58
+ context ||= @context.merge(acontext).merge(:set => true)
59
+ pre << expand_block(block, context)
60
+ @context[:vars] << block.params[:var]
61
+ end
62
+
63
+ pre + super
64
+ end
65
+
66
+ def do_method(sym)
67
+ method = sym
68
+ pre, post = '', ''
69
+
70
+ # do we need recursion ?
71
+ inc = descendant('include')
72
+ if inc && inc.params[:part] == @name
73
+ @context["#{@name}_method".to_sym] = method_name = template_url[1..-1].gsub(/[\/-]/,'_')
74
+ pre << "<% def #{method_name}(depth, node, list); return '' if depth > #{inc.params[:depth] ? [inc.params[:depth].to_i,30].min : 5}; _erbout = '' -%>"
75
+ post << "<% _erbout; end -%><%= #{method_name}(0,#{node},#{list || "[#{node}]"}) %>"
76
+ @context[:node] = 'node'
77
+ @context[:list] = 'list'
78
+ end
79
+
80
+ if @context[:make_form]
81
+ res = case method
82
+ when :r_title
83
+ make_input(:name => 'v_title')
84
+ when :r_link
85
+ make_input(:name => (@params[:attr] || 'v_title'))
86
+ when :r_show
87
+ make_input(:name => (@params[:attr] || @params[:tattr]), :date => @params[:date])
88
+ when :r_text
89
+ make_textarea(:name => 'v_text')
90
+ when :r_summary
91
+ make_textarea(:name => 'v_summary')
92
+ when :r_zazen
93
+ make_textarea(:name => @params[:attr])
94
+ else
95
+ if node_kind_of?(DataEntry) && @method.to_s =~ /node_/
96
+ # select node_id
97
+ "<%= select_id('#{base_class.to_s.underscore}', '#{@method}_id') %>"
98
+ end
99
+ end
100
+ res = "<#{@html_tag || 'div'} class='zazen'>#{res}</#{@html_tag || 'div'}>" if [:r_summary, :r_text].include?(sym)
101
+ end
102
+
103
+
104
+ res ||= super(method)
105
+ "#{pre}#{res}#{post}"
106
+ end
107
+
108
+ # recursion
109
+ def r_include
110
+ return '' if @context[:saved_template]
111
+ return super if @params[:template] || !@params[:part]
112
+ part = @params[:part].gsub(/[^a-zA-Z_]/,'')
113
+ method_name = @context["#{part}_method".to_sym]
114
+ return parser_error("no parent named '#{part}'") unless method_name
115
+ "<%= #{method_name}(depth+1,#{node},#{list}) %>"
116
+ end
117
+
118
+ # Find a block to update on the page
119
+ def find_target(name)
120
+ # find dom_id / template_url
121
+ target = nil
122
+ root.descendants('block').each do |b|
123
+ if b.name == name
124
+ target = b
125
+ break
126
+ end
127
+ end
128
+ out parser_error("could not find a block named '#{name}'") if target.nil?
129
+ target
130
+ end
131
+
132
+ def context
133
+ return @context if @context
134
+ # not rendered yet, find first parent with context
135
+ @context = parent ? parent.context : {}
136
+ end
137
+
138
+ # Block visibility of descendance with 'do_list'.
139
+ def public_descendants
140
+ all = super
141
+ if ['context', 'each', 'block'].include?(self.method)
142
+ # do not propagate 'form',etc up
143
+ all.reject do |k,v|
144
+ ['form','unlink'].include?(k)
145
+ end
146
+ elsif ['if', 'case'].include?(self.method)
147
+ all.reject do |k,v|
148
+ ['else', 'elsif', 'when'].include?(k)
149
+ end
150
+ else
151
+ all
152
+ end
153
+ end
154
+
155
+ def single_child_method
156
+ return @single_child_method if defined?(@single_child_method)
157
+ @single_child_method = if @blocks.size == 1
158
+ single_child = @blocks[0]
159
+ return nil if single_child.kind_of?(String)
160
+ single_child.html_tag ? nil : single_child.method
161
+ else
162
+ nil
163
+ end
164
+ end
165
+ end # MoveToParser
166
+ end # Core
167
+ end # Zafu
@@ -0,0 +1,58 @@
1
+ module Zafu
2
+ module Dates
3
+ def r_date
4
+ select = @params[:select]
5
+ case select
6
+ when 'main'
7
+ expand_with(:date=>'main_date')
8
+ when 'now'
9
+ expand_with(:date=>'Time.now')
10
+ else
11
+ if select =~ /^\d{4}-\d{1,2}-\d{1,2}$/
12
+ begin
13
+ d = Date.parse(select)
14
+ expand_with(:date=>select.inspect)
15
+ rescue
16
+ parser_error("invalid date '#{select}' should be 'YYYY-MM-DD'")
17
+ end
18
+ elsif date = find_stored(Date, select)
19
+ if date[0..0] == '"'
20
+ begin
21
+ d = Date.parse(date[1..-2])
22
+ expand_with(:date=>date)
23
+ rescue
24
+ parser_error("invalid date #{select} (#{date}) should be 'YYYY-MM-DD'")
25
+ end
26
+ else
27
+ expand_with(:date=>select)
28
+ end
29
+ elsif select =~ /\[(.*)\]/
30
+ date, static = parse_attributes_in_value(select, :erb => false)
31
+ expand_with(:date => "\"#{date}\"")
32
+ else
33
+ parser_error("bad parameter '#{select}'")
34
+ end
35
+ end
36
+ end
37
+
38
+ protected
39
+ def current_date
40
+ @context[:date] || 'main_date'
41
+ end
42
+
43
+ # This is used by zafu and it's a mess.
44
+ # ref_date can be a string ('2005-05-03') or ruby ('Time.now'). It should not come uncleaned from evil web.
45
+ def date_condition(date_cond, field, ref_date='today')
46
+ if date_cond == 'today' || ref_date == 'today'
47
+ ref_date = Zena::Db::NOW
48
+ elsif ref_date =~ /(\d{4}-\d{1,2}-\d{1,2}( \d{1,2}:\d{1,2}(:\d{1,2})?)?)/
49
+ ref_date = "'#{$1}'"
50
+ elsif ref_date =~ /\A"/
51
+ ref_date = "'\#{format_date(#{ref_date})}'"
52
+ else
53
+ ref_date = "'\#{#{ref_date}.strftime('%Y-%m-%d %H:%M:%S')}'"
54
+ end
55
+ Zena::Db.date_condition(date_cond, field, ref_date)
56
+ end
57
+ end # Dates
58
+ end # Zafu
@@ -0,0 +1,502 @@
1
+ module Zafu
2
+ module Display
3
+
4
+ # This should be done with rubyless... (methods on the compiler...)
5
+ class << self
6
+ def inline_methods(*args)
7
+ args.each do |name|
8
+ class_eval <<-END
9
+ def r_#{name}
10
+ "<%= #{name}(:node=>\#{node}\#{params_to_erb(@params)}) %>"
11
+ end
12
+ END
13
+ end
14
+ end
15
+
16
+ def direct_methods(*args)
17
+ args.each do |name|
18
+ class_eval <<-END
19
+ def r_#{name}
20
+ helper.#{name}
21
+ end
22
+ END
23
+ end
24
+ end
25
+ end
26
+
27
+ inline_methods :login_link, :visitor_link, :search_box, :show_menu, :show_path, :lang_links
28
+ direct_methods :uses_datebox
29
+
30
+ def r_javascripts
31
+ if @params[:list].nil?
32
+ list = %w{ prototype effects tablekit zena }
33
+ elsif @params[:list] == 'all'
34
+ list = %w{ prototype effects dragdrop tablekit zena }
35
+ else
36
+ list = @params[:list].split(',').map{|e| e.strip}
37
+ end
38
+ helper.javascript_include_tag(*list)
39
+ end
40
+
41
+ def r_stylesheets
42
+ if @params[:list] == 'all' || @params[:list].nil?
43
+ list = %w{ zena code }
44
+ else
45
+ list = @params[:list].split(',').map{|e| e.strip}
46
+ end
47
+ list << {:media => @params[:media]} if @params[:media]
48
+ helper.stylesheet_link_tag(*list)
49
+ end
50
+
51
+ def r_show
52
+ if attr_or_date = @params[:attr_or_date]
53
+ # using [var] shortcut. Can be either a date or an attribute/var
54
+ if attr_or_date == 'current_date' || attr_or_date =~ /_at$/
55
+ @params[:date] = attr_or_date
56
+ else
57
+ @params[:attr] = attr_or_date
58
+ end
59
+ end
60
+
61
+ if var_name = @params[:var]
62
+ return parser_error("var #{@params[:var].inspect} not set") unless @context[:vars] && @context[:vars].include?(var_name)
63
+ attribute_method = "set_#{var_name}"
64
+ elsif @params[:eval]
65
+ return unless attribute_method = parse_eval_parameter(@params[:eval])
66
+ elsif @params[:tattr]
67
+ attribute_method = "_(#{node_attribute(@params[:tattr], :else=>@params[:else], :default=>@params[:default])})"
68
+ elsif @params[:attr]
69
+ attribute_method = node_attribute(@params[:attr], :else=>@params[:else], :default=>@params[:default])
70
+ elsif p = @params[:param]
71
+ return "<%= params[#{p.to_sym.inspect}] %>"
72
+ elsif @params[:date]
73
+ # date can be any attribute v_created_at or updated_at etc.
74
+ # TODO format with @params[:format] and @params[:tformat] << translated format
75
+ # TODO: test
76
+ if @params[:tformat]
77
+ format = _(@params[:tformat])
78
+ elsif @params[:format]
79
+ format = @params[:format]
80
+ else
81
+ format = "%Y-%m-%d"
82
+ end
83
+
84
+ tz = ''
85
+ lang = ''
86
+ if tz_name = @params[:time_zone]
87
+ tz_list = @params.reject {|k,v| !(k.to_s =~ /^time_zone\d*$/)}.to_a.sort {|a,b| a[0].to_s <=> b[0].to_s }.map do |k,tz_name|
88
+ if tz_name =~ /^\[(\w+)\]$/
89
+ node_attribute($1)
90
+ else
91
+ begin
92
+ TZInfo::Timezone.get(tz_name)
93
+ rescue TZInfo::InvalidTimezoneIdentifier
94
+ return parser_error("invalid timezone #{tz_name.inspect}")
95
+ end
96
+ tz_name.inspect
97
+ end
98
+ end
99
+ tz = ", #{tz_list.join(' || ')}"
100
+ end
101
+ if lang = @params[:lang]
102
+ tz = ', nil' if tz == ''
103
+ lang = ", #{lang.inspect}"
104
+ end
105
+ attribute_method = "format_date(#{node_attribute(@params[:date])}, #{format.inspect}#{tz}#{lang})"
106
+ elsif @context[:trans]
107
+ # error
108
+ return "no attribute for 'show'".inspect
109
+ else
110
+ attribute_method = node_class.ancestors.include?(String) ? node : node_attribute('to_s')
111
+ end
112
+
113
+ if !@params[:date] && fmt = @params[:format]
114
+ begin
115
+ # test argument
116
+ sprintf(fmt, 123.45)
117
+ rescue ArgumentError
118
+ return parser_error("incorect format #{fmt.inspect}")
119
+ end
120
+ if fmt =~ /%[\d\.]*f/
121
+ modifier = ".to_f"
122
+ elsif fmt =~ /%[\d\.]*i/
123
+ modifier = ".to_i"
124
+ else
125
+ modifier = ''
126
+ end
127
+
128
+ if @params[:zero] == 'hide'
129
+ attribute_method = "sprintf_unless_zero(#{fmt.inspect}, #{attribute_method}#{modifier})"
130
+ else
131
+ attribute_method = "sprintf(#{fmt.inspect}, #{attribute_method}#{modifier})"
132
+ end
133
+ end
134
+
135
+
136
+ if @context[:trans]
137
+ # TODO: what do we do here with gsubs, url ?
138
+ return attribute_method
139
+ end
140
+
141
+ if gsub = @params[:gsub]
142
+ if gsub =~ /\A\/(.+)\/(.+)\/\Z/
143
+ value = $2
144
+ key = $1.gsub(/\#([\{\$\@])/,'# \1') # FIXME: SECURITY.
145
+ # Please note that .gsub(/#([\{\$\@])/,'\#\1') won't work, since '\#{blah}' will become '\\#{blah}' and 'blah' will be evaluated.
146
+ regexp_ok = begin
147
+ output = StringIO.open('','w')
148
+ $stderr = output
149
+ re = /#{key}/
150
+ output.string !~ /warning:/
151
+ rescue
152
+ false
153
+ ensure
154
+ $stderr = STDERR
155
+ false
156
+ end
157
+
158
+ if regexp_ok
159
+ attribute_method = "#{attribute_method}.to_s.gsub(/#{key}/,#{value.inspect})"
160
+ else
161
+ # invalid regexp
162
+ return parser_error("invalid gsub #{gsub.inspect}")
163
+ end
164
+ else
165
+ # error
166
+ return parser_error("invalid gsub #{gsub.inspect}")
167
+ end
168
+ end
169
+
170
+ if @params[:actions]
171
+ actions = "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)}) %>"
172
+ else
173
+ actions = ''
174
+ end
175
+
176
+ attribute = @params[:attr] || @params[:tattr] || @params[:date]
177
+
178
+ if (@params[:edit_preview] || @params[:ep]) == 'true'
179
+ @html_tag_params[:id] = "#{attribute}#{erb_node_id}"
180
+ @html_tag ||= 'span'
181
+ end
182
+
183
+ if @params[:edit] == 'true' && !['url','path'].include?(attribute)
184
+ "<% if #{node}.can_write? -%><span class='show_edit' id='#{erb_dom_id("_#{attribute}")}'>#{actions}<%= link_to_remote(#{attribute_method}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}\", :method => :get) %></span><% else -%>#{actions}<%= #{attribute_method} %><% end -%>"
185
+ else
186
+ "#{actions}<%= #{attribute_method} %>"
187
+ end
188
+ end
189
+
190
+ def r_zazen
191
+ attribute = @params[:attr] || @params[:tattr]
192
+ limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
193
+ if @context[:trans]
194
+ # TODO: what do we do here with dates ?
195
+ return "#{node_attribute(attribute)}"
196
+ elsif @params[:tattr]
197
+ return "<%= zazen(_(#{node_attribute(attribute)})#{limit}, :node=>#{node(Node)}) %>"
198
+ elsif @params[:attr]
199
+ if output_format == 'html'
200
+ res = "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}) %>"
201
+ else
202
+ return "<%= zazen(#{node_attribute(attribute)}#{limit}, :node=>#{node(Node)}, :output=>#{output_format.inspect}) %>"
203
+ end
204
+ elsif @params[:date]
205
+ # date can be any attribute v_created_at or updated_at etc.
206
+ # TODO format with @params[:format] and @params[:tformat] << translated format
207
+ else
208
+ # error
209
+ end
210
+
211
+ @html_tag ||= 'div'
212
+
213
+ add_html_class('zazen')
214
+
215
+ if (@params[:edit_preview] || @params[:ep]) == 'true'
216
+ @html_tag_params[:id] = "#{attribute}#{erb_node_id}"
217
+ end
218
+
219
+ if @params[:edit] == 'true' && !['url','path'].include?(attribute)
220
+ edit_text = _('edit')
221
+ @html_tag_params[:id] = erb_dom_id("_#{attribute}")
222
+ res = "<% if #{node}.can_write? -%><span class='zazen_edit'><%= link_to_remote(#{edit_text.inspect}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("_#{attribute}")}#{auto_publish_param(true)}&zazen=true\", :method => :get) %></span><% end -%>#{res}"
223
+ else
224
+ res
225
+ end
226
+ end
227
+
228
+ # TODO: test
229
+ def r_filter
230
+ if upd = @params[:update]
231
+ return unless block = find_target(upd)
232
+ else
233
+ return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block')
234
+ end
235
+ return parser_error("cannot use 's' as key (used by start_node)") if @params[:key] == 's'
236
+ out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/>#{start_node_s_param(:input)}</div><div class='wrapper'>"
237
+ if @blocks == []
238
+ out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>"
239
+ else
240
+ out expand_with(:in_filter => true)
241
+ end
242
+ out "</div></form>"
243
+ if @params[:live] || @params[:update]
244
+ out "<%= observe_form( \"#{dom_id}_f\" , :method => :get, :frequency => 1, :submit =>\"#{dom_id}_f\", :url => zafu_node_path(#{node_id})) %>"
245
+ end
246
+ end
247
+
248
+ def r_title
249
+ if node_kind_of?(Version)
250
+ node = "#{self.node}.node"
251
+ elsif node_kind_of?(Node)
252
+ node = self.node
253
+ else
254
+ return parser_error('title','only works with nodes')
255
+ end
256
+ title_params = {}
257
+
258
+ title_params[:check_lang] = @params[:check_lang] if @params.include?(:check_lang)
259
+
260
+ if @params[:link]
261
+ value, static = parse_attributes_in_value(@params[:link], :erb => false)
262
+ link_param = ", :link=>\"#{value}\""
263
+ else
264
+ link_param = ''
265
+ end
266
+
267
+ res = "<%= show_title(:node=>#{node}#{link_param}#{params_to_erb(title_params)}"
268
+ if @params[:text]
269
+ res << ", :text=>#{@params[:text].inspect}"
270
+ elsif @params[:attr]
271
+ res << ", :text=>#{node_attribute(@params[:attr])}"
272
+ end
273
+
274
+ if @params.include?(:project)
275
+ res << ", :project=>#{@params[:project] == 'true'}"
276
+ end
277
+ res << ")"
278
+ if @params[:actions]
279
+ res << " + node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:actions], :publish_after_save=>auto_publish_param)})"
280
+ end
281
+ res << "%>"
282
+ if @params[:status] == 'true' || (@params[:status].nil? && @params[:actions])
283
+ @html_tag ||= 'span'
284
+ add_html_class("s<%= #{node}.version.status %>")
285
+ end
286
+ res
287
+ end
288
+
289
+ def r_content_for_layout
290
+ "<% if content_for_layout = yield -%><%= content_for_layout %><% else -%>" +
291
+ expand_with +
292
+ "<% end -%>"
293
+ end
294
+
295
+ def r_title_for_layout
296
+ "<% if @title_for_layout -%><%= @title_for_layout %><% elsif @node && !@node.new_record? -%><%= @node.rootpath %><% elsif @node.parent -%><%= @node.parent.rootpath %><% else -%>" +
297
+ expand_with +
298
+ "<% end -%>"
299
+ end
300
+
301
+ # TODO: replace with a more general 'zazen' or 'show' with id ?
302
+ def r_summary
303
+ limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
304
+ @html_tag ||= 'div'
305
+ if @html_tag_params[:id]
306
+ # add a sub-div
307
+ pre = "<div id='v_summary#{erb_node_id}'>"
308
+ post = "</div>"
309
+ else
310
+ pre = post = ''
311
+ @html_tag_params[:id] = "v_summary#{erb_node_id}"
312
+ end
313
+
314
+ add_html_class('zazen')
315
+
316
+ unless @params[:or]
317
+ text = @params[:text] ? @params[:text].inspect : node_attribute('v_summary')
318
+ out "#{pre}<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>#{post}"
319
+ else
320
+ limit ||= ', :limit => 2'
321
+ first_name = 'v_summary'
322
+ first = node_attribute(first_name)
323
+
324
+ second_name = @params[:or].gsub(/[^a-z_]/,'') # FIXME: ist this still needed ? (ERB injection)
325
+ second = node_attribute(second_name)
326
+ out "#{pre}<% if #{first} != '' %>"
327
+ out "<%= zazen(#{first}, :node=>#{node(Node)}) %>"
328
+ out "<% else %>"
329
+ out "<%= zazen(#{second}#{limit}, :node=>#{node(Node)}) %>"
330
+ out "<% end %>#{post}"
331
+ end
332
+ end
333
+
334
+ def r_show_author
335
+ if @params[:size] == 'large'
336
+ out "#{_("posted by")} <b><%= #{node}.author.fullname %></b>"
337
+ out "<% if #{node}[:user_id] != #{node}.version[:user_id] -%>"
338
+ out "<% if #{node}[:ref_lang] != #{node}.version[:lang] -%>"
339
+ out "#{_("traduction by")} <b><%= #{node}.version.author.fullname %></b>"
340
+ out "<% else -%>"
341
+ out "#{_("modified by")} <b><%= #{node}.version.author.fullname %></b>"
342
+ out "<% end"
343
+ out " end -%>"
344
+ out " #{_("on")} <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>."
345
+ if @params[:traductions] == 'true'
346
+ out " #{_("Traductions")} : <span class='traductions'><%= helper.traductions(:node=>#{node}).join(', ') %></span>"
347
+ end
348
+ else
349
+ out "<b><%= #{node}.version.author.initials %></b> - <%= format_date(#{node}.version.updated_at, #{_('short_date').inspect}) %>"
350
+ if @params[:traductions] == 'true'
351
+ out " <span class='traductions'>(<%= helper.traductions(:node=>#{node}).join(', ') %>)</span>"
352
+ end
353
+ end
354
+ end
355
+
356
+ # TODO: test
357
+ def r_actions
358
+ out expand_with
359
+ out "<%= node_actions(:node=>#{node}#{params_to_erb(:actions=>@params[:select], :publish_after_save=>auto_publish_param)}) %>"
360
+ end
361
+
362
+ # TODO: test
363
+ def r_admin_links
364
+ "<%= show_link(:admin_links).join('</#{@html_tag}><#{@html_tag}>') %>"
365
+ end
366
+
367
+ def r_text
368
+ text = @params[:text] ? @params[:text].inspect : "#{node_attribute('v_text')}"
369
+ limit = @params[:limit] ? ", :limit=>#{@params[:limit].to_i}" : ""
370
+
371
+ @html_tag ||= 'div'
372
+
373
+ if @html_tag_params[:id]
374
+ # add a sub-div
375
+ pre = "<div id='v_text#{erb_node_id}'>"
376
+ post = "</div>"
377
+ else
378
+ pre = post = ''
379
+ @html_tag_params[:id] = "v_text#{erb_node_id}"
380
+ end
381
+
382
+ add_html_class('zazen')
383
+
384
+ unless @params[:empty] == 'true'
385
+ out "#{pre}<% if #{node}.kind_of?(TextDocument); l = #{node}.content_lang -%>"
386
+ out "<%= zazen(\"<code\#{l ? \" lang='\#{l}'\" : ''} class=\\'full\\'>\#{#{text}}</code>\") %>"
387
+ out "<% else -%>"
388
+ out "<%= zazen(#{text}#{limit}, :node=>#{node(Node)}) %>"
389
+ out "<% end -%>#{post}"
390
+ else
391
+ out "#{pre}#{post}"
392
+ end
393
+ end
394
+
395
+ def r_img
396
+ return unless node_kind_of?(Node)
397
+ if @params[:src]
398
+ finder, klass = build_finder_for(:first, @params[:src])
399
+ return unless finder
400
+ return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
401
+ img = finder
402
+ else
403
+ img = node
404
+ end
405
+ mode = @params[:mode] || 'std'
406
+ # FIXME: replace this call by something that integrates better with html_tag_params and such.
407
+ res = "img_tag(#{img}, :mode=>#{mode.inspect}"
408
+ [:class, :alt_src, :id, :border, :style].each do |k|
409
+ res += ", :#{k}=>#{@params[k].inspect}" if @params[k]
410
+ end
411
+ res += ", :host => #{@context["exp_host"]}" if @context["exp_host"]
412
+ res += ")"
413
+ if @params[:link]
414
+ finder, klass = build_finder_for(:first, @params[:link])
415
+ return unless finder
416
+ return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node)
417
+
418
+ opts_str = @context["exp_host"] ? ", :host => #{@context["exp_host"]}" : ""
419
+
420
+ "<a href='<%= zen_path(#{finder}#{opts_str}) %>'><%= #{res} %></a>"
421
+ else
422
+ "<%= #{res} %>"
423
+ end
424
+ end
425
+
426
+ # Compute statistics on elements in the current list context.
427
+ def r_stat
428
+ return parser_error("must be used inside a list context") unless list
429
+ find = @params[:find] || @params[:date] || 'count'
430
+ key = @params[:of] || @params[:from] || 'value'
431
+ case find
432
+ when 'sum'
433
+ value = "#{list}.flatten.inject(0) {|#{var}_sum,#{var}| #{var}_sum + #{node_attribute(key, :node => var)}.to_f}"
434
+ when 'min'
435
+ value = "#{node_attribute(key, :node => "min_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
436
+ when 'max'
437
+ value = "#{node_attribute(key, :node => "max_array(#{list}) {|e| #{node_attribute(key, :node => 'e')}}")}"
438
+ when 'count'
439
+ return "<%= #{list}.size %>"
440
+ end
441
+ if @params[:date]
442
+ # FIXME: DRY (r_show)
443
+ if @params[:tformat]
444
+ format = _(@params[:tformat])
445
+ elsif @params[:format]
446
+ format = @params[:format]
447
+ else
448
+ format = "%Y-%m-%d"
449
+ end
450
+ "<%= #{list}==[] ? '' : format_date(#{value}, #{format.inspect}) %>"
451
+ elsif format = @params[:format]
452
+
453
+ if @params[:zero] == 'hide'
454
+ "<%= #{list}==[] ? '' : sprintf_unless_zero(#{@params[:format].inspect}, #{value}) %>"
455
+ else
456
+ "<%= #{list}==[] ? '' : sprintf(#{@params[:format].inspect}, #{value}) %>"
457
+ end
458
+ else
459
+ "<%= #{list}==[] ? '' : #{value} %>"
460
+ end
461
+ end
462
+
463
+ def r_design
464
+ if @params[:by]
465
+ by = "<a href='#{@params[:href]}'>#{@params[:by]}</a>"
466
+ else
467
+ by = expand_with(:trans => true)
468
+ end
469
+ unless skin = @params[:skin]
470
+ skin = helper.instance_variable_get(:@controller).instance_variable_get(:@skin_name)
471
+ end
472
+ skin = "<i>#{skin}</i>" unless skin.blank?
473
+ _("%{skin}, design by %{name}") % {:name => by, :skin => skin}
474
+ end
475
+
476
+ # Shows a 'made with zena' link or logo. ;-) Thanks for using this !
477
+ # TODO: test and add translation.
478
+ # <r:zena show='logo'/> or <r:zena show='text'/> == <r:zena/>
479
+ def r_zena
480
+ if logo = @params[:logo]
481
+ # FIXME
482
+ case logo
483
+ when 'tiny'
484
+ else
485
+ end
486
+ else
487
+ text = case @params[:type]
488
+ when 'riding'
489
+ _("riding zena")
490
+ when 'peace'
491
+ _("in peace with zena")
492
+ when 'garden'
493
+ _("a zen garden")
494
+ else
495
+ _("made with zena")
496
+ end
497
+ "<a class='zena' href='http://zenadmin.org' title='zena <%= Zena::VERSION %>'>#{text}</a>"
498
+ end
499
+ end
500
+
501
+ end # Display
502
+ end # Zafu