gettalong-webgen 0.5.4.20080929

Sign up to get free protection for your applications and to get access to all the features.
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