gettalong-webgen 0.5.4.20080929

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 (290) hide show
  1. data/AUTHORS +5 -0
  2. data/COPYING +10 -0
  3. data/GPL +340 -0
  4. data/Rakefile +324 -0
  5. data/THANKS +17 -0
  6. data/bin/webgen +10 -0
  7. data/data/webgen/resources.yaml +3 -0
  8. data/data/webgen/webgui/controller/main.rb +129 -0
  9. data/data/webgen/webgui/overrides/win32console.rb +0 -0
  10. data/data/webgen/webgui/public/css/jquery.autocomplete.css +50 -0
  11. data/data/webgen/webgui/public/css/ramaze_error.css +90 -0
  12. data/data/webgen/webgui/public/css/style.css +55 -0
  13. data/data/webgen/webgui/public/img/headerbg.jpg +0 -0
  14. data/data/webgen/webgui/public/img/webgen_logo.png +0 -0
  15. data/data/webgen/webgui/public/js/jquery.autocomplete.js +15 -0
  16. data/data/webgen/webgui/public/js/jquery.js +32 -0
  17. data/data/webgen/webgui/view/create_website.xhtml +22 -0
  18. data/data/webgen/webgui/view/error.xhtml +64 -0
  19. data/data/webgen/webgui/view/index.xhtml +22 -0
  20. data/data/webgen/webgui/view/manage_website.xhtml +18 -0
  21. data/data/webgen/webgui/view/page.xhtml +40 -0
  22. data/data/webgen/website_skeleton/README +10 -0
  23. data/data/webgen/website_skeleton/Rakefile +40 -0
  24. data/data/webgen/website_skeleton/config.yaml +17 -0
  25. data/data/webgen/website_skeleton/ext/init.rb +6 -0
  26. data/data/webgen/website_styles/1024px/README +13 -0
  27. data/data/webgen/website_styles/1024px/src/default.css +188 -0
  28. data/data/webgen/website_styles/1024px/src/default.template +60 -0
  29. data/data/webgen/website_styles/1024px/src/images/background.gif +0 -0
  30. data/data/webgen/website_styles/andreas00/README +13 -0
  31. data/data/webgen/website_styles/andreas00/src/default.css +290 -0
  32. data/data/webgen/website_styles/andreas00/src/default.template +60 -0
  33. data/data/webgen/website_styles/andreas00/src/images/bg.gif +0 -0
  34. data/data/webgen/website_styles/andreas00/src/images/front.jpg +0 -0
  35. data/data/webgen/website_styles/andreas00/src/images/menubg.gif +0 -0
  36. data/data/webgen/website_styles/andreas00/src/images/menubg2.gif +0 -0
  37. data/data/webgen/website_styles/andreas01/README +14 -0
  38. data/data/webgen/website_styles/andreas01/src/default.css +310 -0
  39. data/data/webgen/website_styles/andreas01/src/default.template +61 -0
  40. data/data/webgen/website_styles/andreas01/src/images/bg.gif +0 -0
  41. data/data/webgen/website_styles/andreas01/src/images/front.jpg +0 -0
  42. data/data/webgen/website_styles/andreas01/src/print.css +35 -0
  43. data/data/webgen/website_styles/andreas03/README +14 -0
  44. data/data/webgen/website_styles/andreas03/src/default.css +223 -0
  45. data/data/webgen/website_styles/andreas03/src/default.template +58 -0
  46. data/data/webgen/website_styles/andreas03/src/images/bodybg.png +0 -0
  47. data/data/webgen/website_styles/andreas03/src/images/contbg.png +0 -0
  48. data/data/webgen/website_styles/andreas03/src/images/footerbg.png +0 -0
  49. data/data/webgen/website_styles/andreas03/src/images/gradient1.png +0 -0
  50. data/data/webgen/website_styles/andreas03/src/images/gradient2.png +0 -0
  51. data/data/webgen/website_styles/andreas04/README +15 -0
  52. data/data/webgen/website_styles/andreas04/src/default.css +290 -0
  53. data/data/webgen/website_styles/andreas04/src/default.template +81 -0
  54. data/data/webgen/website_styles/andreas04/src/images/blinkarrow.gif +0 -0
  55. data/data/webgen/website_styles/andreas04/src/images/bodybg.png +0 -0
  56. data/data/webgen/website_styles/andreas04/src/images/contentbg.png +0 -0
  57. data/data/webgen/website_styles/andreas04/src/images/entrybg.png +0 -0
  58. data/data/webgen/website_styles/andreas04/src/images/flash.gif +0 -0
  59. data/data/webgen/website_styles/andreas04/src/images/flash2.gif +0 -0
  60. data/data/webgen/website_styles/andreas04/src/images/globe.gif +0 -0
  61. data/data/webgen/website_styles/andreas04/src/images/globebottom.gif +0 -0
  62. data/data/webgen/website_styles/andreas04/src/images/linkarrow.gif +0 -0
  63. data/data/webgen/website_styles/andreas04/src/images/menuhover.png +0 -0
  64. data/data/webgen/website_styles/andreas05/README +14 -0
  65. data/data/webgen/website_styles/andreas05/src/default.css +33 -0
  66. data/data/webgen/website_styles/andreas05/src/default.template +40 -0
  67. data/data/webgen/website_styles/andreas05/src/images/bodybg.gif +0 -0
  68. data/data/webgen/website_styles/andreas05/src/images/front.png +0 -0
  69. data/data/webgen/website_styles/andreas06/README +14 -0
  70. data/data/webgen/website_styles/andreas06/src/default.css +354 -0
  71. data/data/webgen/website_styles/andreas06/src/default.template +70 -0
  72. data/data/webgen/website_styles/andreas06/src/images/bodybg.gif +0 -0
  73. data/data/webgen/website_styles/andreas06/src/images/boxbg.gif +0 -0
  74. data/data/webgen/website_styles/andreas06/src/images/greypx.gif +0 -0
  75. data/data/webgen/website_styles/andreas06/src/images/header.jpg +0 -0
  76. data/data/webgen/website_styles/andreas06/src/images/innerbg.gif +0 -0
  77. data/data/webgen/website_styles/andreas06/src/images/leaves.jpg +0 -0
  78. data/data/webgen/website_styles/andreas06/src/images/tabs.gif +0 -0
  79. data/data/webgen/website_styles/andreas07/README +15 -0
  80. data/data/webgen/website_styles/andreas07/src/browserfix.css +7 -0
  81. data/data/webgen/website_styles/andreas07/src/default.css +92 -0
  82. data/data/webgen/website_styles/andreas07/src/default.template +42 -0
  83. data/data/webgen/website_styles/andreas07/src/images/bodybg.gif +0 -0
  84. data/data/webgen/website_styles/andreas07/src/images/sidebarbg.gif +0 -0
  85. data/data/webgen/website_styles/andreas08/README +14 -0
  86. data/data/webgen/website_styles/andreas08/src/default.css +224 -0
  87. data/data/webgen/website_styles/andreas08/src/default.template +51 -0
  88. data/data/webgen/website_styles/andreas09/README +14 -0
  89. data/data/webgen/website_styles/andreas09/src/default.css +308 -0
  90. data/data/webgen/website_styles/andreas09/src/default.template +68 -0
  91. data/data/webgen/website_styles/andreas09/src/images/bodybg-black.jpg +0 -0
  92. data/data/webgen/website_styles/andreas09/src/images/bodybg-green.jpg +0 -0
  93. data/data/webgen/website_styles/andreas09/src/images/bodybg-orange.jpg +0 -0
  94. data/data/webgen/website_styles/andreas09/src/images/bodybg-purple.jpg +0 -0
  95. data/data/webgen/website_styles/andreas09/src/images/bodybg-red.jpg +0 -0
  96. data/data/webgen/website_styles/andreas09/src/images/bodybg.jpg +0 -0
  97. data/data/webgen/website_styles/andreas09/src/images/footerbg.jpg +0 -0
  98. data/data/webgen/website_styles/andreas09/src/images/menuhover-black.jpg +0 -0
  99. data/data/webgen/website_styles/andreas09/src/images/menuhover-green.jpg +0 -0
  100. data/data/webgen/website_styles/andreas09/src/images/menuhover-orange.jpg +0 -0
  101. data/data/webgen/website_styles/andreas09/src/images/menuhover-purple.jpg +0 -0
  102. data/data/webgen/website_styles/andreas09/src/images/menuhover-red.jpg +0 -0
  103. data/data/webgen/website_styles/andreas09/src/images/menuhover.jpg +0 -0
  104. data/data/webgen/website_styles/simple/README +6 -0
  105. data/data/webgen/website_styles/simple/src/default.css +84 -0
  106. data/data/webgen/website_styles/simple/src/default.template +36 -0
  107. data/data/webgen/website_templates/default/README +6 -0
  108. data/data/webgen/website_templates/default/src/index.page +8 -0
  109. data/data/webgen/website_templates/project/README +5 -0
  110. data/data/webgen/website_templates/project/src/about.page +12 -0
  111. data/data/webgen/website_templates/project/src/download.page +15 -0
  112. data/data/webgen/website_templates/project/src/features.page +8 -0
  113. data/data/webgen/website_templates/project/src/index.page +9 -0
  114. data/data/webgen/website_templates/project/src/screenshots.page +18 -0
  115. data/doc/contentprocessor.template +11 -0
  116. data/doc/contentprocessor/blocks.page +66 -0
  117. data/doc/contentprocessor/builder.page +80 -0
  118. data/doc/contentprocessor/erb.page +56 -0
  119. data/doc/contentprocessor/erubis.page +46 -0
  120. data/doc/contentprocessor/haml.page +47 -0
  121. data/doc/contentprocessor/maruku.page +41 -0
  122. data/doc/contentprocessor/rdiscount.page +37 -0
  123. data/doc/contentprocessor/rdoc.page +36 -0
  124. data/doc/contentprocessor/redcloth.page +39 -0
  125. data/doc/contentprocessor/sass.page +31 -0
  126. data/doc/contentprocessor/tags.page +73 -0
  127. data/doc/extensions.metainfo +29 -0
  128. data/doc/extensions.page +16 -0
  129. data/doc/extensions.template +17 -0
  130. data/doc/faq.page +214 -0
  131. data/doc/getting_started.page +134 -0
  132. data/doc/index.page +65 -0
  133. data/doc/manual.page +532 -0
  134. data/doc/reference_configuration.page +646 -0
  135. data/doc/reference_metainfo.page +213 -0
  136. data/doc/sourcehandler.template +21 -0
  137. data/doc/sourcehandler/copy.page +19 -0
  138. data/doc/sourcehandler/directory.page +27 -0
  139. data/doc/sourcehandler/feed.page +82 -0
  140. data/doc/sourcehandler/metainfo.page +41 -0
  141. data/doc/sourcehandler/page.page +30 -0
  142. data/doc/sourcehandler/sitemap.page +46 -0
  143. data/doc/sourcehandler/template.page +45 -0
  144. data/doc/sourcehandler/virtual.page +49 -0
  145. data/doc/tag.template +25 -0
  146. data/doc/tag/breadcrumbtrail.page +40 -0
  147. data/doc/tag/coderay.page +49 -0
  148. data/doc/tag/date.page +31 -0
  149. data/doc/tag/executecommand.page +26 -0
  150. data/doc/tag/includefile.page +32 -0
  151. data/doc/tag/langbar.page +22 -0
  152. data/doc/tag/menu.page +92 -0
  153. data/doc/tag/metainfo.page +29 -0
  154. data/doc/tag/relocatable.page +38 -0
  155. data/doc/tag/sitemap.page +31 -0
  156. data/doc/upgrading.page +139 -0
  157. data/doc/webgen_page_format.page +128 -0
  158. data/lib/webgen/blackboard.rb +73 -0
  159. data/lib/webgen/cache.rb +85 -0
  160. data/lib/webgen/cli.rb +118 -0
  161. data/lib/webgen/cli/create_command.rb +64 -0
  162. data/lib/webgen/cli/run_command.rb +20 -0
  163. data/lib/webgen/cli/utils.rb +86 -0
  164. data/lib/webgen/cli/webgui_command.rb +49 -0
  165. data/lib/webgen/common.rb +10 -0
  166. data/lib/webgen/common/sitemap.rb +76 -0
  167. data/lib/webgen/configuration.rb +147 -0
  168. data/lib/webgen/contentprocessor.rb +96 -0
  169. data/lib/webgen/contentprocessor/blocks.rb +46 -0
  170. data/lib/webgen/contentprocessor/builder.rb +26 -0
  171. data/lib/webgen/contentprocessor/context.rb +90 -0
  172. data/lib/webgen/contentprocessor/erb.rb +24 -0
  173. data/lib/webgen/contentprocessor/erubis.rb +40 -0
  174. data/lib/webgen/contentprocessor/haml.rb +25 -0
  175. data/lib/webgen/contentprocessor/maruku.rb +18 -0
  176. data/lib/webgen/contentprocessor/rdiscount.rb +15 -0
  177. data/lib/webgen/contentprocessor/rdoc.rb +17 -0
  178. data/lib/webgen/contentprocessor/redcloth.rb +15 -0
  179. data/lib/webgen/contentprocessor/sass.rb +18 -0
  180. data/lib/webgen/contentprocessor/tags.rb +134 -0
  181. data/lib/webgen/coreext.rb +10 -0
  182. data/lib/webgen/default_config.rb +198 -0
  183. data/lib/webgen/languages.rb +578 -0
  184. data/lib/webgen/loggable.rb +23 -0
  185. data/lib/webgen/logger.rb +78 -0
  186. data/lib/webgen/node.rb +347 -0
  187. data/lib/webgen/output.rb +37 -0
  188. data/lib/webgen/output/filesystem.rb +67 -0
  189. data/lib/webgen/page.rb +133 -0
  190. data/lib/webgen/path.rb +182 -0
  191. data/lib/webgen/source.rb +24 -0
  192. data/lib/webgen/source/filesystem.rb +58 -0
  193. data/lib/webgen/source/resource.rb +42 -0
  194. data/lib/webgen/source/stacked.rb +53 -0
  195. data/lib/webgen/sourcehandler.rb +202 -0
  196. data/lib/webgen/sourcehandler/base.rb +211 -0
  197. data/lib/webgen/sourcehandler/copy.rb +41 -0
  198. data/lib/webgen/sourcehandler/directory.rb +31 -0
  199. data/lib/webgen/sourcehandler/feed.rb +121 -0
  200. data/lib/webgen/sourcehandler/fragment.rb +71 -0
  201. data/lib/webgen/sourcehandler/metainfo.rb +117 -0
  202. data/lib/webgen/sourcehandler/page.rb +77 -0
  203. data/lib/webgen/sourcehandler/sitemap.rb +60 -0
  204. data/lib/webgen/sourcehandler/template.rb +68 -0
  205. data/lib/webgen/sourcehandler/virtual.rb +75 -0
  206. data/lib/webgen/tag.rb +23 -0
  207. data/lib/webgen/tag/base.rb +162 -0
  208. data/lib/webgen/tag/breadcrumbtrail.rb +71 -0
  209. data/lib/webgen/tag/coderay.rb +32 -0
  210. data/lib/webgen/tag/date.rb +18 -0
  211. data/lib/webgen/tag/executecommand.rb +29 -0
  212. data/lib/webgen/tag/includefile.rb +42 -0
  213. data/lib/webgen/tag/langbar.rb +52 -0
  214. data/lib/webgen/tag/menu.rb +186 -0
  215. data/lib/webgen/tag/metainfo.rb +25 -0
  216. data/lib/webgen/tag/relocatable.rb +53 -0
  217. data/lib/webgen/tag/sitemap.rb +42 -0
  218. data/lib/webgen/tree.rb +80 -0
  219. data/lib/webgen/version.rb +6 -0
  220. data/lib/webgen/webgentask.rb +148 -0
  221. data/lib/webgen/website.rb +214 -0
  222. data/lib/webgen/websiteaccess.rb +29 -0
  223. data/lib/webgen/websitemanager.rb +125 -0
  224. data/man/man1/webgen.1 +67 -0
  225. data/misc/default.css +360 -0
  226. data/misc/default.template +75 -0
  227. data/misc/htmldoc.metainfo +25 -0
  228. data/misc/htmldoc.virtual +5 -0
  229. data/misc/images/arrow.gif +0 -0
  230. data/misc/images/error.gif +0 -0
  231. data/misc/images/exclamation.gif +0 -0
  232. data/misc/images/headerbg.jpg +0 -0
  233. data/misc/images/information.gif +0 -0
  234. data/misc/images/quote.gif +0 -0
  235. data/setup.rb +1585 -0
  236. data/test/helper.rb +41 -0
  237. data/test/test_blackboard.rb +58 -0
  238. data/test/test_cache.rb +57 -0
  239. data/test/test_common_sitemap.rb +56 -0
  240. data/test/test_configuration.rb +66 -0
  241. data/test/test_contentprocessor.rb +31 -0
  242. data/test/test_contentprocessor_blocks.rb +34 -0
  243. data/test/test_contentprocessor_builder.rb +19 -0
  244. data/test/test_contentprocessor_context.rb +38 -0
  245. data/test/test_contentprocessor_erb.rb +20 -0
  246. data/test/test_contentprocessor_erubis.rb +47 -0
  247. data/test/test_contentprocessor_haml.rb +20 -0
  248. data/test/test_contentprocessor_maruku.rb +27 -0
  249. data/test/test_contentprocessor_rdiscount.rb +15 -0
  250. data/test/test_contentprocessor_rdoc.rb +16 -0
  251. data/test/test_contentprocessor_redcloth.rb +12 -0
  252. data/test/test_contentprocessor_sass.rb +20 -0
  253. data/test/test_contentprocessor_tags.rb +97 -0
  254. data/test/test_languages.rb +53 -0
  255. data/test/test_loggable.rb +30 -0
  256. data/test/test_logger.rb +73 -0
  257. data/test/test_node.rb +339 -0
  258. data/test/test_output_filesystem.rb +58 -0
  259. data/test/test_page.rb +203 -0
  260. data/test/test_path.rb +131 -0
  261. data/test/test_source_filesystem.rb +59 -0
  262. data/test/test_source_resource.rb +26 -0
  263. data/test/test_source_stacked.rb +34 -0
  264. data/test/test_sourcehandler_base.rb +92 -0
  265. data/test/test_sourcehandler_copy.rb +45 -0
  266. data/test/test_sourcehandler_directory.rb +25 -0
  267. data/test/test_sourcehandler_feed.rb +74 -0
  268. data/test/test_sourcehandler_fragment.rb +67 -0
  269. data/test/test_sourcehandler_metainfo.rb +93 -0
  270. data/test/test_sourcehandler_page.rb +70 -0
  271. data/test/test_sourcehandler_sitemap.rb +47 -0
  272. data/test/test_sourcehandler_template.rb +63 -0
  273. data/test/test_sourcehandler_virtual.rb +56 -0
  274. data/test/test_tag_base.rb +82 -0
  275. data/test/test_tag_breadcrumbtrail.rb +89 -0
  276. data/test/test_tag_coderay.rb +30 -0
  277. data/test/test_tag_date.rb +16 -0
  278. data/test/test_tag_executecommand.rb +39 -0
  279. data/test/test_tag_includefile.rb +48 -0
  280. data/test/test_tag_langbar.rb +60 -0
  281. data/test/test_tag_menu.rb +195 -0
  282. data/test/test_tag_metainfo.rb +17 -0
  283. data/test/test_tag_relocatable.rb +57 -0
  284. data/test/test_tag_sitemap.rb +44 -0
  285. data/test/test_tree.rb +69 -0
  286. data/test/test_webgentask.rb +21 -0
  287. data/test/test_website.rb +96 -0
  288. data/test/test_websiteaccess.rb +23 -0
  289. data/test/test_websitemanager.rb +68 -0
  290. metadata +575 -0
@@ -0,0 +1,32 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/tag'
3
+
4
+ module Webgen::Tag
5
+
6
+ # Provides syntax highlighting via the +coderay+ library.
7
+ class Coderay
8
+
9
+ include Webgen::Tag::Base
10
+ include Webgen::WebsiteAccess
11
+
12
+ # Highlight the body of the block.
13
+ def call(tag, body, context)
14
+ require 'coderay'
15
+ options = {
16
+ :css => :style,
17
+ :wrap => param('tag.coderay.wrap').to_sym,
18
+ :line_numbers => (param('tag.coderay.line_numbers') ? :inline : nil),
19
+ :line_number_start => param('tag.coderay.line_number_start'),
20
+ :tab_width => param('tag.coderay.tab_width'),
21
+ :bold_every => param('tag.coderay.bold_every')
22
+ }
23
+
24
+ if param('tag.coderay.process_body')
25
+ body = website.blackboard.invoke(:content_processor, 'tags').call(context.clone(:content => body)).content
26
+ end
27
+ CodeRay.scan(body, param('tag.coderay.lang').to_sym).html(options)
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,18 @@
1
+ require 'webgen/tag'
2
+
3
+ module Webgen::Tag
4
+
5
+ # Prints out the date using a format string which will be passed to Time#strftime. Therefore you
6
+ # can use everything Time#strftime offers.
7
+ class Date
8
+
9
+ include Base
10
+
11
+ # Return the current date formatted as specified.
12
+ def call(tag, body, context)
13
+ Time.now.strftime(param('tag.date.format'))
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'webgen/tag'
2
+ require 'cgi'
3
+ require "tempfile"
4
+ require 'rbconfig'
5
+
6
+ module Webgen::Tag
7
+
8
+ # Executes the given command and returns the standard output. All special HTML characters are
9
+ # escaped.
10
+ class ExecuteCommand
11
+
12
+ include Webgen::Tag::Base
13
+
14
+ BIT_BUCKET = (Config::CONFIG['arch'].include?('mswin32') ? "nul" : "/dev/null")
15
+
16
+ # Execute the command and return the standard output.
17
+ def call(tag, body, context)
18
+ command = param('tag.executecommand.command')
19
+ output = `#{command} 2> #{BIT_BUCKET}`
20
+ if ($? >> 8) != 0
21
+ raise "Command '#{command}' in <#{context.ref_node.absolute_lcn}> has return value != 0: #{output}"
22
+ end
23
+ output = CGI::escapeHTML(output) if param('tag.executecommand.escape_html')
24
+ [output, param('tag.executecommand.process_output')]
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,42 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/tag'
3
+ require 'cgi'
4
+
5
+ module Webgen::Tag
6
+
7
+ # Includes a file verbatim and optionally escapes all special HTML characters and processes webgen
8
+ # tags in it.
9
+ class IncludeFile
10
+
11
+ include Webgen::Tag::Base
12
+ include Webgen::WebsiteAccess
13
+
14
+ def initialize #:nodoc:
15
+ website.blackboard.add_listener(:node_changed?, method(:node_changed?))
16
+ end
17
+
18
+ # Include the specified file verbatim in the output, optionally escaping special HTML characters
19
+ # and processing tags in it.
20
+ def call(tag, body, context)
21
+ filename = param('tag.includefile.filename')
22
+ filename = File.join(website.directory, filename) unless filename =~ /^(\/|\w:)/
23
+ content = File.open(filename, 'rb') {|f| f.read}
24
+ content = CGI::escapeHTML(content) if param('tag.includefile.escape_html')
25
+ (context.dest_node.node_info[:tag_includefile_filenames] ||= []) << [filename, File.mtime(filename)]
26
+
27
+ [content, param('tag.includefile.process_output')]
28
+ end
29
+
30
+ #######
31
+ private
32
+ #######
33
+
34
+ def node_changed?(node)
35
+ if filenames = node.node_info[:tag_includefile_filenames]
36
+ node.dirty = true if filenames.any? {|f, mtime| File.mtime(f) > mtime}
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,52 @@
1
+ require 'webgen/tag'
2
+ require 'webgen/websiteaccess'
3
+
4
+ module Webgen::Tag
5
+
6
+ # Generates a list with all the languages of the page.
7
+ class Langbar
8
+
9
+ include Webgen::Tag::Base
10
+ include Webgen::WebsiteAccess
11
+
12
+ def initialize #:nodoc:
13
+ website.blackboard.add_listener(:node_changed?, method(:node_changed?))
14
+ end
15
+
16
+ # Return a list of all translations of the content page.
17
+ def call(tag, body, context)
18
+ lang_nodes = all_lang_nodes(context.content_node)
19
+ (context.dest_node.node_info[:tag_langbar_data] ||= {})[context.content_node.absolute_cn] = lang_nodes.map {|n| n.absolute_lcn}
20
+ result = lang_nodes.
21
+ reject {|n| (context.content_node.lang == n.lang && !param('tag.langbar.show_own_lang'))}.
22
+ sort {|a, b| a.lang <=> b.lang}.
23
+ collect {|n| context.dest_node.link_to(n, :link_text => n.lang, :lang => n.lang)}.
24
+ join(param('tag.langbar.separator'))
25
+ (param('tag.langbar.show_single_lang') || lang_nodes.length > 1 ? result : "")
26
+ end
27
+
28
+ #######
29
+ private
30
+ #######
31
+
32
+ # Return all nodes with the same absolute cn as +node+.
33
+ def all_lang_nodes(node)
34
+ node.tree.node_access[:acn][node.absolute_cn]
35
+ end
36
+
37
+ # Check if the langbar tag for +node+ changed.
38
+ def node_changed?(node)
39
+ return unless (cdata = node.node_info[:tag_langbar_data])
40
+ cdata.each do |acn, clang_nodes|
41
+ lang_nodes = all_lang_nodes(node.tree[acn, :acn]) rescue nil
42
+ if !lang_nodes || lang_nodes.length != clang_nodes.length ||
43
+ lang_nodes.any? {|n| n.meta_info_changed?}
44
+ node.dirty = true
45
+ break
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,186 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/tag'
3
+
4
+ module Webgen::Tag
5
+
6
+ # Generates a menu that can be configured extensively.
7
+ class Menu
8
+
9
+ include Webgen::WebsiteAccess
10
+ include Base
11
+
12
+ # Special menu node class. It encapsulates the original node for later access.
13
+ class MenuNode
14
+
15
+ # Array of the child nodes.
16
+ attr_reader :children
17
+
18
+ # The parent node.
19
+ attr_reader :parent
20
+
21
+ # The encapsulated node.
22
+ attr_reader :node
23
+
24
+ # Set to +true+ if the menu node is in the tree of files.
25
+ attr_writer :is_in_tree_of_files
26
+
27
+ # Create a new menu node under +parent+ for the real node +node+.
28
+ def initialize(parent, node)
29
+ @parent = parent
30
+ @node = node
31
+ @children = []
32
+ end
33
+
34
+ # Return +true+ if the menu node is in the menu tree of only files.
35
+ def is_in_tree_of_files?
36
+ @is_in_tree_of_files
37
+ end
38
+
39
+ # Sort recursively all children of the node using the wrapped nodes.
40
+ def sort!
41
+ self.children.sort! {|a,b| a.node <=> b.node}
42
+ self.children.each {|child| child.sort!}
43
+ self
44
+ end
45
+
46
+ # Return the menu tree under the node as nested list of alcn values.
47
+ def to_lcn_list
48
+ self.children.inject([]) {|temp, n| temp << n.node.absolute_lcn; temp += ((t = n.to_lcn_list).empty? ? [] : [t]) }
49
+ end
50
+
51
+ end
52
+
53
+ def initialize #:nodoc:
54
+ website.blackboard.add_listener(:node_changed?, method(:node_changed?))
55
+ end
56
+
57
+ # Generate the menu.
58
+ def call(tag, body, context)
59
+ tree = specific_menu_tree_for(context.content_node)
60
+
61
+ (context.dest_node.node_info[:tag_menu_menus] ||= {})[[@params.to_a.sort, context.content_node.absolute_lcn]] = (tree ? tree.to_lcn_list : nil)
62
+ (tree && !tree.children.empty? ? create_output(context, tree) : '')
63
+ end
64
+
65
+ #########
66
+ protected
67
+ #########
68
+
69
+ # Check if the menus for +node+ have changed.
70
+ def node_changed?(node)
71
+ return if !node.node_info[:tag_menu_menus]
72
+
73
+ node.node_info[:tag_menu_menus].each do |(params, cn_alcn), cached_tree|
74
+ cn = node.tree[cn_alcn]
75
+ menu_tree = menu_tree_for_lang(cn.lang, cn.tree.root)
76
+
77
+ set_params(params.to_hash)
78
+ tree = build_specific_menu_tree(cn, menu_tree)
79
+ tree_list = tree.to_lcn_list if tree
80
+ set_params({})
81
+
82
+ if (tree.nil? && !cached_tree.nil?) || (tree_list && tree_list != cached_tree) ||
83
+ (tree_list && tree_list.flatten.any? do |alcn|
84
+ (n = node.tree[alcn]) && (r = n.routing_node(cn.lang)) && r != node && r.meta_info_changed?
85
+ end)
86
+ node.dirty = true
87
+ break
88
+ end
89
+ end
90
+ end
91
+
92
+ # Wrapper method for returning the specific menu tree for +content_node+.
93
+ def specific_menu_tree_for(content_node)
94
+ tree = menu_tree_for_lang(content_node.lang, content_node.tree.root)
95
+ if param('tag.menu.used_nodes') == 'fragments'
96
+ @params['tag.menu.start_level'] = param('tag.menu.start_level') + content_node.level
97
+ end
98
+ build_specific_menu_tree(content_node, tree)
99
+ end
100
+
101
+ # Build a menu tree for +content_node+ from the tree +menu_node+.
102
+ def build_specific_menu_tree(content_node, menu_node, level = 1)
103
+ if menu_node.nil? \
104
+ || level > param('tag.menu.max_levels') + param('tag.menu.start_level') - 1 \
105
+ || ((level > param('tag.menu.min_levels') + param('tag.menu.start_level') - 1) \
106
+ && (menu_node.node.level >= content_node.level \
107
+ || (param('tag.menu.show_current_subtree_only') && !content_node.in_subtree_of?(menu_node.node))
108
+ )
109
+ ) \
110
+ || (level == param('tag.menu.start_level') && !content_node.in_subtree_of?(menu_node.node))
111
+ return nil
112
+ end
113
+
114
+ sub_menu_tree = MenuNode.new(nil, menu_node.node)
115
+ menu_tree = MenuNode.new(nil, menu_node.node)
116
+ menu_node.children.each do |child|
117
+ next if param('tag.menu.used_nodes') == 'files' && !child.is_in_tree_of_files?
118
+ menu_tree.children << (this_node = MenuNode.new(menu_tree, child.node))
119
+ sub_node = child.children.length > 0 ? build_specific_menu_tree(content_node, child, level + 1) : nil
120
+ sub_node.children.each {|n| this_node.children << n; sub_menu_tree.children << n} if sub_node
121
+ end
122
+
123
+ if level < param('tag.menu.start_level')
124
+ sub_menu_tree
125
+ else
126
+ menu_tree
127
+ end
128
+ end
129
+
130
+ # Create the HTML menu of the +tree+ using the provided +context+.
131
+ def create_output(context, tree, level = 1)
132
+ out = "<ul>"
133
+ tree.children.each do |child|
134
+ menu = child.children.length > 0 ? create_output(context, child, level + 1) : ''
135
+ style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level)
136
+
137
+ out << "<li #{style}>#{link}"
138
+ out << menu
139
+ out << "</li>"
140
+ end
141
+ out << "</ul>"
142
+ out
143
+ end
144
+
145
+ # Return style information (node is selected, ...) and a link from +dest_node+ to +node+.
146
+ def menu_item_details(dest_node, node, lang, level)
147
+ styles = ['webgen-menu-level' + level.to_s]
148
+ styles << 'webgen-menu-submenu' if node.is_directory? || (node.is_fragment? && node.children.length > 0)
149
+ styles << 'webgen-menu-submenu-inhierarchy' if (node.is_directory? || (node.is_fragment? && node.children.length > 0)) &&
150
+ dest_node.in_subtree_of?(node)
151
+ styles << 'webgen-menu-item-selected' if node == dest_node
152
+ style = "class=\"#{styles.join(' ')}\"" if styles.length > 0
153
+
154
+ link = dest_node.link_to(node, :lang => lang)
155
+
156
+ [style, link]
157
+ end
158
+
159
+ # Return the menu tree for the language +lang+.
160
+ def menu_tree_for_lang(lang, root)
161
+ menus = (website.cache.volatile[:menutrees] ||= {})
162
+ unless menus[lang]
163
+ menus[lang] = create_menu_tree(root, nil, lang)
164
+ menus[lang].sort! if menus[lang]
165
+ end
166
+ menus[lang]
167
+ end
168
+
169
+ # Create and return a menu tree if at least one node is in the menu or +nil+ otherwise.
170
+ def create_menu_tree(node, parent, lang)
171
+ menu_node = MenuNode.new(parent, node)
172
+
173
+ node.children.select do |child|
174
+ child.lang == lang || child.lang.nil? || child.is_directory?
175
+ end.each do |child|
176
+ sub_node = create_menu_tree(child, menu_node, lang)
177
+ menu_node.children << sub_node unless sub_node.nil?
178
+ end
179
+ menu_node.is_in_tree_of_files = (!node.is_fragment? && node['in_menu']) || menu_node.children.any? {|c| c.is_in_tree_of_files?}
180
+
181
+ menu_node.children.empty? ? (node['in_menu'] ? menu_node : nil) : menu_node
182
+ end
183
+
184
+ end
185
+
186
+ end
@@ -0,0 +1,25 @@
1
+ require 'webgen/tag'
2
+
3
+ module Webgen::Tag
4
+
5
+ # Provides easy access to the meta information of a node.
6
+ class Metainfo
7
+
8
+ include Base
9
+
10
+ # Return the meta information key specified in +tag+ of the content node.
11
+ def call(tag, body, context)
12
+ output = ''
13
+ if tag == 'lang'
14
+ output = context.content_node.lang
15
+ elsif context.content_node[tag]
16
+ output = context.content_node[tag].to_s
17
+ else
18
+ log(:warn) { "No value for meta info key '#{tag}' in <#{context.ref_node.absolute_lcn}> found in <#{context.content_node.absolute_lcn}>" }
19
+ end
20
+ output
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,53 @@
1
+ require 'webgen/tag'
2
+ require 'uri'
3
+
4
+ module Webgen::Tag
5
+
6
+ # Makes a path relative. This is very useful for templates. For example, you normally include a
7
+ # stylesheet in a template. If you specify the filename of the stylesheet directly, the reference
8
+ # to the stylesheet in the output file of a page file that is not in the same directory as the
9
+ # template would be invalid.
10
+ #
11
+ # By using the +relocatable+ tag you ensure that the path stays valid.
12
+ class Relocatable
13
+
14
+ include Webgen::Tag::Base
15
+
16
+ # Return the relativized path for the path provided in the tag definition.
17
+ def call(tag, body, context)
18
+ uri_string = param('tag.relocatable.path')
19
+ result = ''
20
+ unless uri_string.nil?
21
+ begin
22
+ uri = URI.parse(uri_string)
23
+ if uri.absolute?
24
+ result = uri_string
25
+ else
26
+ result = resolve_path(uri_string, context)
27
+ end
28
+ if result.empty?
29
+ log(:error) { "Could not resolve path '#{uri_string}' in <#{context.ref_node.absolute_lcn}>" }
30
+ context.dest_node.dirty = true
31
+ end
32
+ rescue URI::InvalidURIError => e
33
+ log(:error) { "Error while parsing path for tag relocatable in <#{context.ref_node.absolute_lcn}>: #{e.message}" }
34
+ context.dest_node.dirty = true
35
+ end
36
+ end
37
+ result
38
+ end
39
+
40
+ #######
41
+ private
42
+ #######
43
+
44
+ # Resolve the path +uri+ using the reference node and return the correct relative path from the
45
+ # destination node.
46
+ def resolve_path(uri, context)
47
+ dest_node = context.ref_node.resolve(uri, context.dest_node.lang)
48
+ (dest_node ? context.dest_node.route_to(dest_node) : '')
49
+ end
50
+
51
+ end
52
+
53
+ end