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,60 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/sourcehandler/base'
3
+ require 'uri'
4
+ require 'time'
5
+
6
+ module Webgen::SourceHandler
7
+
8
+ # Source handler for creating an XML sitemap based on the specification of http://sitemaps.org.
9
+ #
10
+ # Uses Webgen::Common::Sitemap to generate the needed sitemap tree and to check if a sitemap has
11
+ # changed.
12
+ class Sitemap
13
+
14
+ include Webgen::WebsiteAccess
15
+ include Base
16
+
17
+ # Create an XML sitemap from +parent+ and +path+.
18
+ def create_node(parent, path)
19
+ page_from_path(path)
20
+ path.ext = 'xml'
21
+ raise "Needed information site_url missing for sitemap <#{path}>" if path.meta_info['site_url'].nil?
22
+ super(parent, path)
23
+ end
24
+
25
+ # Return the rendered feed represented by +node+.
26
+ def content(node)
27
+ require 'builder'
28
+ list = website.blackboard.invoke(:create_sitemap, node, node.lang, options_for_node(node)).to_lcn_list.flatten
29
+ sitemap = ::Builder::XmlMarkup.new(:indent => 2)
30
+ sitemap.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
31
+ sitemap.urlset(:xmlns => "http://www.sitemaps.org/schemas/sitemap/0.9") do
32
+ list.each do |alcn|
33
+ item = node.tree[alcn]
34
+ sitemap.url do |url|
35
+ sitemap.loc(URI.escape(File.join(node['site_url'], item.path)))
36
+ sitemap.lastmod(item['modified_at'].iso8601)
37
+ changefreq = item['change_freq'] || node['default_change_freq']
38
+ sitemap.changefreq(changefreq) if changefreq
39
+ priority = item['priority'] || node['default_priority']
40
+ sitemap.priority(priority) if priority
41
+ end
42
+ end
43
+ end
44
+ sitemap.target!
45
+ end
46
+
47
+ #######
48
+ private
49
+ #######
50
+
51
+ # Return a hash with the sitemap-creation-options set on the +node+.
52
+ def options_for_node(node)
53
+ options = {}
54
+ node.meta_info.each {|k,v| options[k] = v if k =~ /\./}
55
+ options
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,68 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/loggable'
3
+ require 'webgen/sourcehandler/base'
4
+
5
+ module Webgen::SourceHandler
6
+
7
+ # Source handler for handling template files in Webgen Page Format.
8
+ class Template
9
+
10
+ include Webgen::WebsiteAccess
11
+ include Webgen::Loggable
12
+ include Base
13
+
14
+ # Create a template node in +parent+ for +path+.
15
+ def create_node(parent, path)
16
+ page = page_from_path(path)
17
+ super(parent, path) do |node|
18
+ node.node_info[:page] = page
19
+ end
20
+ end
21
+
22
+ # Return the template chain for +node+.
23
+ def templates_for_node(node, lang = node.lang)
24
+ cached_template = (website.cache.volatile[[node.absolute_lcn, :templates]] ||= {})
25
+ if cached_template[lang]
26
+ template_node = cached_template[lang]
27
+ elsif node['template'].kind_of?(String)
28
+ template_node = node.resolve(node['template'], lang)
29
+ if template_node.nil?
30
+ log(:warn) { "Specified template '#{node['template']}' for <#{node.absolute_lcn}> not found, using default template!" }
31
+ template_node = default_template(node.parent, lang)
32
+ end
33
+ cached_template[lang] = template_node
34
+ elsif node.meta_info.has_key?('template') && node['template'].nil?
35
+ template_node = cached_template[lang] = nil
36
+ else
37
+ log(:info) { "Using default template in language '#{lang}' for <#{node.absolute_lcn}>" }
38
+ template_node = default_template(node.parent, lang)
39
+ if template_node == node && !node.parent.is_root?
40
+ template_node = default_template(node.parent.parent, lang)
41
+ end
42
+ cached_template[lang] = template_node
43
+ end
44
+
45
+ if template_node.nil?
46
+ []
47
+ else
48
+ (template_node == node ? [] : templates_for_node(template_node, lang) + [template_node])
49
+ end
50
+ end
51
+
52
+ # Return the default template for the directory node +dir+. If the template node is not found,
53
+ # the parent directories are searched.
54
+ def default_template(dir_node, lang)
55
+ template_node = dir_node.resolve(website.config['sourcehandler.template.default_template'], lang)
56
+ if template_node.nil?
57
+ if dir_node.is_root?
58
+ log(:warn) { "No default template in root directory found!" }
59
+ else
60
+ template_node = default_template(dir_node.parent, lang)
61
+ end
62
+ end
63
+ template_node
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,75 @@
1
+ require 'uri'
2
+ require 'yaml'
3
+ require 'webgen/sourcehandler/base'
4
+ require 'webgen/websiteaccess'
5
+
6
+ module Webgen::SourceHandler
7
+
8
+ # Handles files which contain specifications for "virtual" nodes, ie. nodes that don't have real
9
+ # source path.
10
+ #
11
+ # This can be used, for example, to provide multiple links to the same node.
12
+ class Virtual
13
+
14
+ include Base
15
+ include Webgen::WebsiteAccess
16
+
17
+ # Create all virtual nodes under +parent+ which are specified in +path+.
18
+ def create_node(parent, path)
19
+ page = page_from_path(path)
20
+ nodes = []
21
+ YAML::load(page.blocks['content'].content).each do |key, value|
22
+ key = (key =~ /^\// ? key : File.join(parent.absolute_lcn, key))
23
+ temp_parent = create_directories(parent.tree.root, File.dirname(key), path)
24
+
25
+ temp_path = Webgen::Path.new(key)
26
+ temp_path.meta_info.update(value || {})
27
+ temp_path.meta_info['modified_at'] = path.meta_info['modified_at']
28
+ temp_path.meta_info['no_output'] = true
29
+ output_path = temp_path.meta_info.delete('url') || key
30
+ output_path = (URI::parse(output_path).absolute? || output_path =~ /^\// ?
31
+ output_path : File.join(temp_parent.absolute_lcn, output_path))
32
+
33
+ if key =~ /\/$/
34
+ nodes << create_directory(temp_parent, key, path, temp_path.meta_info)
35
+ else
36
+ nodes << super(temp_parent, temp_path, output_path) {|n| n.node_info[:src] = path.path}
37
+ end
38
+ end if page.blocks.has_key?('content')
39
+ nodes.compact
40
+ end
41
+
42
+ #######
43
+ private
44
+ #######
45
+
46
+ # Create the needed parent directories for a virtual node.
47
+ def create_directories(parent, dirname, path)
48
+ dirname.sub(/^\//, '').split('/').each do |dir|
49
+ parent = create_directory(parent, File.join(parent.absolute_lcn, dir), path)
50
+ end
51
+ parent
52
+ end
53
+
54
+ # Create a virtual directory if it does not already exist.
55
+ def create_directory(parent, dir, path, meta_info = nil)
56
+ dir_handler = website.cache.instance('Webgen::SourceHandler::Directory')
57
+ website.blackboard.invoke(:create_nodes, parent.tree, parent.absolute_lcn,
58
+ Webgen::Path.new(File.join(dir, '/')),
59
+ dir_handler) do |par, temp_path|
60
+ node = nil
61
+ if (node = dir_handler.node_exists?(par, temp_path)) && (!meta_info || node.node_info[:src] != path.path)
62
+ parent, node = node, nil
63
+ else
64
+ temp_path.meta_info.update(meta_info) if meta_info
65
+ parent = node = dir_handler.create_node(par, temp_path)
66
+ parent.node_info[:src] = path.path
67
+ end
68
+ node
69
+ end
70
+ parent
71
+ end
72
+
73
+ end
74
+
75
+ end
data/lib/webgen/tag.rb ADDED
@@ -0,0 +1,23 @@
1
+ module Webgen
2
+
3
+ # Namespace for all classes that are useable by Webgen::ContentProcessor::Tag.
4
+ #
5
+ # Have a look at the documentation for Webgen::Tag::Base for details on how to implement a tag
6
+ # class.
7
+ module Tag
8
+
9
+ autoload :Base, 'webgen/tag/base'
10
+ autoload :Relocatable, 'webgen/tag/relocatable'
11
+ autoload :Metainfo, 'webgen/tag/metainfo'
12
+ autoload :Menu, 'webgen/tag/menu'
13
+ autoload :BreadcrumbTrail, 'webgen/tag/breadcrumbtrail'
14
+ autoload :Langbar, 'webgen/tag/langbar'
15
+ autoload :IncludeFile, 'webgen/tag/includefile'
16
+ autoload :ExecuteCommand, 'webgen/tag/executecommand'
17
+ autoload :Coderay, 'webgen/tag/coderay'
18
+ autoload :Date, 'webgen/tag/date'
19
+ autoload :Sitemap, 'webgen/tag/sitemap'
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,162 @@
1
+ require 'yaml'
2
+ require 'webgen/loggable'
3
+ require 'webgen/websiteaccess'
4
+
5
+ # This module should be mixed into any class that wants to serve as a webgen tag class. Have a look
6
+ # a the example below to see how a basic tag class looks like.
7
+ #
8
+ # = Tag classes
9
+ #
10
+ # A tag class is a webgen extension that handles specific webgen tags. webgen tags are used to add
11
+ # dynamic content to page and template files and are made for ease of use.
12
+ #
13
+ # A tag class can handle multiple different tags. Just add a (tag name)-(class name) pair to the
14
+ # <tt>contentprocessor.tags.map</tt> configuration entry for each tag name you want to associate
15
+ # with the tag class. The special name <tt>:default</tt> is used for the default tag class which is
16
+ # called if a tag with an unknown tag name is encountered.
17
+ #
18
+ # The only method needed to be written is +call+ which is called by the tags content processor to
19
+ # the actual processing. And the +initialize+ method must not take any parameters!
20
+ #
21
+ # Tag classes *can* also choose to not use this module. If they don't use it they have to provide
22
+ # the following methods: +set_params+, +create_tag_params+, +call+.
23
+ #
24
+ # = Tag parameters
25
+ #
26
+ # webgen tags allow the specification of parameters in the tag definition. The method
27
+ # +tag_params_list+ returns all configuration entries that can be set this way. And the method
28
+ # +tag_config_base+ is used to resolve partially stated configuration entries. An additional
29
+ # configuration entry option is also used: <tt>:mandatory</tt>. If this key is set to +true+ for a
30
+ # configuration entry, the entry counts as mandatory and needs to be set in the tag definition. If
31
+ # this key is set to +default+, this means that this entry should be the default mandatory parameter
32
+ # (used when only a string is provided in the tag definition). There *should* be only one default
33
+ # mandatory parameter.
34
+ #
35
+ # = Sample Tag Class
36
+ #
37
+ # Following is a simple tag class example which just reverses the body text and adds some
38
+ # information about the context to the result. Note that the class does not reside in the
39
+ # Webgen::Tag namespace and that the configuration entry is therefore also not under the
40
+ # <tt>tag.</tt> namespace.
41
+ #
42
+ # class Reverser
43
+ #
44
+ # include Webgen::Tag::Base
45
+ #
46
+ # def call(tag, body, context)
47
+ # result = param('do_reverse') ? body.reverse : body
48
+ # result += "Node: " + context.content_node.absolute_lcn + " (" + context.content_node['title'] + ")"
49
+ # result += "Reference node: " + context.ref_node.absolute_lcn
50
+ # result
51
+ # end
52
+ #
53
+ # end
54
+ #
55
+ # WebsiteAccess.website.config.reverser.do_reverse nil, :mandatory => default
56
+ # WebsiteAccess.website.config['contentprocessor.tags.map']['reverse'] = 'Reverser'
57
+ #
58
+ module Webgen::Tag::Base
59
+
60
+ include Webgen::Loggable
61
+ include Webgen::WebsiteAccess
62
+
63
+ # Return a hash with parameter values extracted from the string +tag_config+.
64
+ def create_tag_params(tag_config, ref_node)
65
+ begin
66
+ config = YAML::load("--- #{tag_config}")
67
+ rescue ArgumentError => e
68
+ log(:error) { "Could not parse the tag params '#{tag_config}' in <#{ref_node.absolute_lcn}>: #{e.message}" }
69
+ config = {}
70
+ end
71
+ create_params_hash(config, ref_node)
72
+ end
73
+
74
+ # Set the current parameter configuration to +params+.
75
+ def set_params(params)
76
+ @params = params
77
+ end
78
+
79
+ # Retrieve the parameter value for +name+. The value is taken from the current parameter
80
+ # configuration if the parameter is specified there or from the website configuration otherwise.
81
+ def param(name)
82
+ (@params && @params.has_key?(name) ? @params[name] : website.config[name])
83
+ end
84
+
85
+ # Default implementation for processing a tag. The parameter +tag+ specifies the name of the tag
86
+ # which should be processed (useful for tag classes which process different tags).
87
+ #
88
+ # The parameter +body+ holds the optional body value for the tag.
89
+ #
90
+ # The +context+ parameter holds all relevant information for processing. Have a look at the
91
+ # Webgen::ContentProcessor::Context class to see what is available.
92
+ #
93
+ # The method has to return the result of the tag processing and, optionally, a boolean value
94
+ # specifying if the result should further be processed (ie. webgen tags replaced).
95
+ #
96
+ # Needs to be redefined by classes that mixin this module!
97
+ def call(tag, body, context)
98
+ raise NotImplementedError
99
+ end
100
+
101
+ #######
102
+ private
103
+ #######
104
+
105
+ # The base part of the configuration name. This is normally the class name without the Webgen
106
+ # module downcased and all "::" substituted with "." (e.g. Webgen::Tag::Menu -> tag.menu).
107
+ def tag_config_base
108
+ self.class.name.gsub('::', '.').gsub(/^Webgen\./, '').downcase
109
+ end
110
+
111
+ # Return the list of all parameters for the tag class.
112
+ def tag_params_list
113
+ regexp = /^#{tag_config_base}/
114
+ website.config.data.keys.select {|key| key =~ regexp}
115
+ end
116
+
117
+ # Create the parameter hash from +config+ which needs to be a Hash, a String or +nil+.
118
+ def create_params_hash(config, node)
119
+ params = tag_params_list
120
+ result = case config
121
+ when Hash then create_from_hash(config, params, node)
122
+ when String then create_from_string(config, params, node)
123
+ when NilClass then {}
124
+ else
125
+ log(:error) { "Invalid parameter type (#{config.class}) for tag '#{self.class.name}' in <#{node.absolute_lcn}>" }
126
+ {}
127
+ end
128
+
129
+ unless params.all? {|k| !website.config.meta_info[k][:mandatory] || result.has_key?(k)}
130
+ log(:error) { "Not all mandatory parameters for tag '#{self.class.name}' in <#{node.absolute_lcn}> set" }
131
+ end
132
+
133
+ result
134
+ end
135
+
136
+ # Return a valid parameter hash taking values from +config+ which has to be a Hash.
137
+ def create_from_hash(config, params, node)
138
+ result = {}
139
+ config.each do |key, value|
140
+ if params.include?(key)
141
+ result[key] = value
142
+ elsif params.include?(tag_config_base + '.' + key)
143
+ result[tag_config_base + '.' + key] = value
144
+ else
145
+ log(:warn) { "Invalid parameter '#{key}' for tag '#{self.class.name}' in <#{node.absolute_lcn}>" }
146
+ end
147
+ end
148
+ result
149
+ end
150
+
151
+ # Return a valid parameter hash by setting +value+ to the default mandatory parameter.
152
+ def create_from_string(value, params, node)
153
+ param_name = params.find {|k| website.config.meta_info[k][:mandatory] == 'default'}
154
+ if param_name.nil?
155
+ log(:error) { "No default mandatory parameter specified for tag '#{self.class.name}' but set in <#{node.absolute_lcn}>"}
156
+ {}
157
+ else
158
+ {param_name => value}
159
+ end
160
+ end
161
+
162
+ end
@@ -0,0 +1,71 @@
1
+ require 'webgen/websiteaccess'
2
+ require 'webgen/tag'
3
+
4
+ module Webgen::Tag
5
+
6
+ # Generates a breadcrumb trail for the page. This is especially useful when pages are in deep
7
+ # hierarchies of directories.
8
+ class BreadcrumbTrail
9
+
10
+ include Webgen::WebsiteAccess
11
+ include Base
12
+
13
+ def initialize #:nodoc:
14
+ website.blackboard.add_listener(:node_changed?, method(:node_changed?))
15
+ end
16
+
17
+ # Create the breadcrumb trail.
18
+ def call(tag, body, context)
19
+ out = breadcrumb_trail_list(context.content_node)
20
+ (context.dest_node.node_info[:tag_breadcrumb_trail] ||= {})[[@params.to_a.sort, context.content_node.absolute_lcn]] = out.map {|n| n.absolute_lcn}
21
+ out = out.map {|n| context.dest_node.link_to(n, :lang => context.content_node.lang) }.
22
+ join(param('tag.breadcrumbtrail.separator'))
23
+ log(:debug) { "Breadcrumb trail for <#{context.content_node.absolute_lcn}>: #{out}" }
24
+ out
25
+ end
26
+
27
+ #######
28
+ private
29
+ #######
30
+
31
+ # Return the list of nodes that make up the breadcrumb trail of +node+ according to the current
32
+ # parameters.
33
+ def breadcrumb_trail_list(node)
34
+ list = []
35
+ omit_index_path = if node.meta_info.has_key?('omit_index_path')
36
+ node['omit_index_path']
37
+ else
38
+ param('tag.breadcrumbtrail.omit_index_path')
39
+ end
40
+ omit_index_path = omit_index_path && node.parent.routing_node(node.lang) == node
41
+
42
+ node = node.parent if omit_index_path
43
+
44
+ until node == node.tree.dummy_root
45
+ list.unshift(node)
46
+ node = node.parent
47
+ end
48
+ list[param('tag.breadcrumbtrail.start_level')..param('tag.breadcrumbtrail.end_level')].to_a
49
+ end
50
+
51
+ # Check if the breadcrumb trails for +node+ have changed.
52
+ def node_changed?(node)
53
+ return if !node.node_info[:tag_breadcrumb_trail]
54
+
55
+ node.node_info[:tag_breadcrumb_trail].each do |(params, cn_alcn), cached_list|
56
+ cn = node.tree[cn_alcn]
57
+ set_params(params.to_hash)
58
+ list = breadcrumb_trail_list(cn)
59
+ set_params({})
60
+
61
+ if (list.map {|n| n.absolute_lcn} != cached_list) ||
62
+ list.any? {|n| (r = n.routing_node(cn.lang)) && r != node && r.meta_info_changed?}
63
+ node.dirty = true
64
+ break
65
+ end
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end