gettalong-webgen 0.5.9.20090620 → 0.5.9.20090626
Sign up to get free protection for your applications and to get access to all the features.
- data/data/webgen/passive_sources/templates/sitemap.template +21 -0
- data/doc/contentprocessor/head.page +21 -0
- data/doc/manual.page +15 -8
- data/doc/reference_configuration.page +6 -3
- data/doc/reference_metainfo.page +11 -1
- data/doc/reference_website_styles.page +1 -1
- data/doc/sourcehandler/sitemap.page +6 -6
- data/lib/webgen/contentprocessor.rb +17 -3
- data/lib/webgen/contentprocessor/head.rb +62 -0
- data/lib/webgen/default_config.rb +7 -3
- data/lib/webgen/node.rb +1 -1
- data/lib/webgen/output.rb +5 -3
- data/lib/webgen/output/filesystem.rb +4 -4
- data/lib/webgen/path.rb +10 -5
- data/lib/webgen/source/filesystem.rb +1 -1
- data/lib/webgen/source/tararchive.rb +1 -1
- data/lib/webgen/sourcehandler/copy.rb +2 -1
- data/lib/webgen/sourcehandler/sitemap.rb +15 -19
- data/test/test_contentprocessor.rb +8 -2
- data/test/test_contentprocessor_head.rb +43 -0
- data/test/test_node.rb +3 -1
- data/test/test_path.rb +15 -0
- data/test/test_sourcehandler_metainfo.rb +10 -1
- data/test/test_sourcehandler_sitemap.rb +19 -0
- data/test/test_tag_base.rb +0 -2
- metadata +6 -2
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
template: ~
|
3
|
+
--- pipeline:erb
|
4
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
5
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
6
|
+
<%
|
7
|
+
context.node.alcns.each do |alcn|
|
8
|
+
item = context.node.tree[alcn]
|
9
|
+
%>
|
10
|
+
<url>
|
11
|
+
<loc><%= URI.escape(File.join(context.node['site_url'], item.path)) %></loc>
|
12
|
+
<lastmod><%= item['modified_at'].iso8601 %></lastmod>
|
13
|
+
<changefreq><%= item['change_freq'] || context.node['default_change_freq'] %></changefreq>
|
14
|
+
<% if priority = item['priority'] || context.node['default_priority'] %>
|
15
|
+
<priority><%= priority %></priority>
|
16
|
+
<% end %>
|
17
|
+
</url>
|
18
|
+
<%
|
19
|
+
end
|
20
|
+
%>
|
21
|
+
</urlset>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
title: Webgen::ContentProcessor::Head
|
3
|
+
---
|
4
|
+
## Description
|
5
|
+
|
6
|
+
This processor inserts before the end of the HTML head section links to used javascript and css
|
7
|
+
files, inline javascript and css content and general meta tags. This functionality can be used, for
|
8
|
+
example, by webgen tags to add needed javascript or css fragments on a page-per-page basis.
|
9
|
+
|
10
|
+
It can also be used to insert arbitrary meta tags on a page-per-page basis. This can be done by
|
11
|
+
setting the meta information named [`meta`]({relocatable: ../reference_metainfo.html#meta}) on a
|
12
|
+
page file.
|
13
|
+
|
14
|
+
This content processor should be used on template files since its output is only useful in the head
|
15
|
+
section of an HTML file. And it should be the last content processor in the pipeline because
|
16
|
+
otherwise not all needed information is available! There is no need for a special markup since the
|
17
|
+
HTML head end tag is unique in a HTML element and therefore the insertion place can easily be found.
|
18
|
+
|
19
|
+
Developers wanting to use the functionality of this content processor should have a look at its [API
|
20
|
+
documentation](../rdoc/Webgen/ContentProcessor/Head.html).
|
21
|
+
|
data/doc/manual.page
CHANGED
@@ -567,14 +567,21 @@ There are several types of extensions:
|
|
567
567
|
Webgen Page Format. It is not specified how they have to process the content but this type of
|
568
568
|
extension can basically be divided into two groups:
|
569
569
|
|
570
|
-
*
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
570
|
+
* Text content processors: These processors are used to process textual content like files in
|
571
|
+
Webgen Page Format. This group can furthe be divided:
|
572
|
+
|
573
|
+
* Markup processors: Processors like Maruku or RedCloth belong to this group and they
|
574
|
+
convert markup text that is easy to read and write to a more structure format like HTML.
|
575
|
+
This allows you to write an HTML page without knowing HTML.
|
576
|
+
|
577
|
+
* String replacers: These processors normally process special strings and substitute them
|
578
|
+
with other content. For example, the `erb` processors replaces delimited strings
|
579
|
+
interpreted as Ruby code with the interpreted value. Another example would be webgen's
|
580
|
+
`tags` processor which replaces strings like `\{relocatable: ../index.html}` with a
|
581
|
+
processed value.
|
582
|
+
|
583
|
+
* Binary content processors: These processors are used to process binary data. For example, one
|
584
|
+
might want to process an image to produce a thumbnailed version of it.
|
578
585
|
|
579
586
|
* **Source Handler**: These extensions are used for handling source paths. They read the content of
|
580
587
|
a path and produce one or more nodes (the internal representation of an output path, see [source
|
@@ -354,12 +354,14 @@ configuration options) and/or how to use it in a webgen tag (for tag configurati
|
|
354
354
|
* ### contentprocessor.map
|
355
355
|
|
356
356
|
This configuration option maps short names for content processor to their class names. The short
|
357
|
-
names are used, for example, in the
|
357
|
+
names are used, for example, in the processing pipeline of a content block of a file in Webgen
|
358
358
|
Page Format. This configuration option is normally only used by extensions to register the short
|
359
359
|
name of a content processor!
|
360
360
|
|
361
|
-
* Syntax: `\{SHORT: NAME, ...}` where `SHORT` is the short name of the
|
362
|
-
`NAME`.
|
361
|
+
* Syntax: `\{SHORT: NAME, SHORT: [NAME, TYPE], ...}` where `SHORT` is the short name of the
|
362
|
+
content processor class `NAME`. The second form allows one to additionally specify the type
|
363
|
+
`TYPE` of the content processor which has to be `:binary` or `:text`. If the first form is
|
364
|
+
used, then the type defaults to `:text`.
|
363
365
|
|
364
366
|
<%= show_default['contentprocessor.map'] %>
|
365
367
|
|
@@ -367,6 +369,7 @@ configuration options) and/or how to use it in a webgen tag (for tag configurati
|
|
367
369
|
|
368
370
|
config = Webgen::WebsiteAccess.website.config
|
369
371
|
config['contentprocessor.map']['newcp'] = 'Extension::MyNewContentProcessor'
|
372
|
+
config['contentprocessor.map']['newcp'] = ['Extension::MyNewContentProcessor', :binary]
|
370
373
|
|
371
374
|
|
372
375
|
* ### contentprocessor.erubis.use\_pi
|
data/doc/reference_metainfo.page
CHANGED
@@ -110,7 +110,7 @@ information for nodes created by them.
|
|
110
110
|
|
111
111
|
{:miref}
|
112
112
|
* String: `de`
|
113
|
-
*
|
113
|
+
* Any
|
114
114
|
|
115
115
|
Sets the language for the path. Has to be a valid ISO-639-1/2 character code for the language. This
|
116
116
|
meta information needs to be set before a node gets created.
|
@@ -124,6 +124,16 @@ meta information needs to be set before a node gets created.
|
|
124
124
|
Specifies additional attribute-value pairs (in form of a Hash) that should be added to a link to the
|
125
125
|
path.
|
126
126
|
|
127
|
+
### meta
|
128
|
+
|
129
|
+
{:miref}
|
130
|
+
* Hash: `\{author: Thomas Leitner, generator: My program}`
|
131
|
+
* Any
|
132
|
+
|
133
|
+
Specifies names and values for `<meta>` HTML tags. These key-value pairs are then properly escaped
|
134
|
+
and inserted into the output file by [`ContentProcessor::Head`]({relocatable:
|
135
|
+
contentprocessor/head.html}).
|
136
|
+
|
127
137
|
### modified\_at
|
128
138
|
|
129
139
|
{:miref}
|
@@ -20,7 +20,7 @@ context.content_node.tree.node_access[:alcn].select do |name, node|
|
|
20
20
|
node.is_directory? && node.parent == context.content_node.tree[File.join(context.content_node.parent.alcn, '/website_styles/')]
|
21
21
|
end.sort.each do |name, node|
|
22
22
|
%>
|
23
|
-
<h2 id="<%= node.cn %>"><%= node.cn %></h2>
|
23
|
+
<h2 id="<%= node.cn.chomp('/') %>"><%= node.cn %></h2>
|
24
24
|
<div class="website-styles">
|
25
25
|
<%= context.dest_node.link_to(node, :link_text => "Full window version") %>
|
26
26
|
<object type="text/html" data="<%= context.dest_node.route_to(node) %>">Nothing</object>
|
@@ -7,12 +7,6 @@ This source handler automatically generates a sitemap based on the specification
|
|
7
7
|
[sitemaps.org](http://sitemaps.org) from a file in [Webgen Page Format]({relocatable:
|
8
8
|
../webgen_page_format.html}).
|
9
9
|
|
10
|
-
> This extension can only be used if you have installed the [builder](http://builder.rubyforge.org)
|
11
|
-
> library. The preferred way to do this is via Rubygems:
|
12
|
-
>
|
13
|
-
> gem install builder
|
14
|
-
{.warning}
|
15
|
-
|
16
10
|
The following meta information keys are supported:
|
17
11
|
|
18
12
|
* `site_url` (MANDATORY)
|
@@ -44,3 +38,9 @@ The following meta information keys of files are used if they are specified:
|
|
44
38
|
* `priority`
|
45
39
|
|
46
40
|
The priority of the file in respect to the other files.
|
41
|
+
|
42
|
+
The generation of the sitemap is done via a template and the template used needs to be located under
|
43
|
+
the ALCN `/templates/sitemap.template`. This default template is automatically created and used if
|
44
|
+
no such path exists in the webgen website. You can also override the default generation mechanism on
|
45
|
+
a file per file basis by adding a `template` block in the sitemap file which is then used to generate
|
46
|
+
the sitemap.
|
@@ -18,8 +18,13 @@ module Webgen
|
|
18
18
|
#
|
19
19
|
# After writing the content processor class, one needs to add it to the
|
20
20
|
# <tt>contentprocessor.map</tt> hash so that it is used by webgen. The key for the entry needs to
|
21
|
-
# be a short name without special characters or spaces and the value
|
22
|
-
#
|
21
|
+
# be a short name without special characters or spaces and the value can be:
|
22
|
+
#
|
23
|
+
# * the class name, not as constant but as a string - then this content processor is assumed to
|
24
|
+
# work with textual data -, or
|
25
|
+
#
|
26
|
+
# * an array with the class name like before and the type, which needs to be <tt>:binary</tt> or
|
27
|
+
# <tt>:text</tt>.
|
23
28
|
#
|
24
29
|
# == Sample Content Processor
|
25
30
|
#
|
@@ -52,6 +57,8 @@ module Webgen
|
|
52
57
|
# end
|
53
58
|
#
|
54
59
|
# WebsiteAccess.website.config['contentprocessor.map']['replacer'] = 'SampleProcessor'
|
60
|
+
# # Or one could equally write
|
61
|
+
# # WebsiteAccess.website.config['contentprocessor.map']['replacer'] = ['SampleProcessor', :text]
|
55
62
|
#
|
56
63
|
module ContentProcessor
|
57
64
|
|
@@ -67,6 +74,7 @@ module Webgen
|
|
67
74
|
autoload :Erubis, 'webgen/contentprocessor/erubis'
|
68
75
|
autoload :RDiscount, 'webgen/contentprocessor/rdiscount'
|
69
76
|
autoload :Fragments, 'webgen/contentprocessor/fragments'
|
77
|
+
autoload :Head, 'webgen/contentprocessor/head'
|
70
78
|
|
71
79
|
# Return the list of all available content processors.
|
72
80
|
def self.list
|
@@ -75,10 +83,16 @@ module Webgen
|
|
75
83
|
|
76
84
|
# Return the content processor object identified by +name+.
|
77
85
|
def self.for_name(name)
|
78
|
-
klass = WebsiteAccess.website.config['contentprocessor.map'][name]
|
86
|
+
klass, cp_type = WebsiteAccess.website.config['contentprocessor.map'][name]
|
79
87
|
klass.nil? ? nil : WebsiteAccess.website.cache.instance(klass)
|
80
88
|
end
|
81
89
|
|
90
|
+
# Return whether the content processor identified by +name+ is processing binary data.
|
91
|
+
def self.is_binary?(name)
|
92
|
+
WebsiteAccess.website.config['contentprocessor.map'][name].kind_of?(Array) &&
|
93
|
+
WebsiteAccess.website.config['contentprocessor.map'][name].last == :binary
|
94
|
+
end
|
95
|
+
|
82
96
|
# Helper class for accessing content processors in a Webgen::Context object.
|
83
97
|
class AccessHash
|
84
98
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Webgen::ContentProcessor
|
4
|
+
|
5
|
+
# Inserts additional links to CSS/JS files and other HTML head meta info directly before the HTML
|
6
|
+
# head end tag.
|
7
|
+
#
|
8
|
+
# The data used by this content processor is taken from the Context object. Therefore this
|
9
|
+
# processor should be the last in the processing pipeline so that all other processors have been
|
10
|
+
# able to set the data.
|
11
|
+
#
|
12
|
+
# The key <tt>:cp_head</tt> of <tt>context.options</tt> is used and it has to be a Hash with the
|
13
|
+
# following values:
|
14
|
+
#
|
15
|
+
# [:js_file] An array of already resolved relative or absolute paths to Javascript files.
|
16
|
+
# [:js_inline] An array of Javascript fragments to be inserted directly into the head section.
|
17
|
+
# [:css_file] An array of already resolved relative or absolute paths to CSS files.
|
18
|
+
# [:css_inline] An array of CSS fragments to be inserted directly into the head section.
|
19
|
+
# [:meta] A hash with key-value pairs from which <tt>meta</tt> tags are generated. The keys and
|
20
|
+
# the values will be properly escaped before insertion. The entries in the meta
|
21
|
+
# information <tt>meta</tt> of the content node are also used and take precedence over
|
22
|
+
# these entries.
|
23
|
+
class Head
|
24
|
+
|
25
|
+
include Webgen::Loggable
|
26
|
+
|
27
|
+
HTML_HEAD_END_RE = /<\/head\s*>/i #:nodoc:
|
28
|
+
|
29
|
+
# Insert the additional header information.
|
30
|
+
def call(context)
|
31
|
+
require 'erb'
|
32
|
+
context.content.sub!(HTML_HEAD_END_RE) do |match|
|
33
|
+
result = ''
|
34
|
+
if context[:cp_head].kind_of?(Hash)
|
35
|
+
context[:cp_head][:js_file].each do |js_file|
|
36
|
+
result += "\n<script type=\"text/javascript\" src=\"#{js_file}\"></script>"
|
37
|
+
end if context[:cp_head][:js_file].kind_of?(Array)
|
38
|
+
|
39
|
+
context[:cp_head][:js_inline].each do |content|
|
40
|
+
result += "\n<script type=\"text/javascript\">\n#{content}\n</script>"
|
41
|
+
end if context[:cp_head][:js_inline].kind_of?(Array)
|
42
|
+
|
43
|
+
context[:cp_head][:css_file].each do |css_file|
|
44
|
+
result += "\n<link rel=\"stylesheet\" href=\"#{css_file}\" type=\"text/css\"/>"
|
45
|
+
end if context[:cp_head][:css_file].kind_of?(Array)
|
46
|
+
|
47
|
+
context[:cp_head][:css_inline].each do |content|
|
48
|
+
result += "\n<style type=\"text/css\"><![CDATA[/\n#{content}\n]]></style>"
|
49
|
+
end if context[:cp_head][:css_inline].kind_of?(Array)
|
50
|
+
|
51
|
+
context[:cp_head][:meta].merge(context.node['meta'] || {}).each do |name, content|
|
52
|
+
result += "\n<meta name=\"#{ERB::Util.h(name)}\" content=\"#{ERB::Util.h(content)}\" />"
|
53
|
+
end if context[:cp_head][:meta].kind_of?(Hash)
|
54
|
+
end
|
55
|
+
result + match
|
56
|
+
end
|
57
|
+
context
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -89,19 +89,21 @@ config.sourcehandler.default_meta_info({
|
|
89
89
|
'kind' => 'fragment'
|
90
90
|
},
|
91
91
|
'Webgen::SourceHandler::Template' => {
|
92
|
-
'blocks' => {'default' => {'pipeline' => 'erb,tags,blocks'}}
|
92
|
+
'blocks' => {'default' => {'pipeline' => 'erb,tags,blocks,head'}}
|
93
93
|
},
|
94
94
|
'Webgen::SourceHandler::Metainfo' => {
|
95
95
|
'blocks' => {1 => {'name' => 'paths'}, 2 => {'name' => 'alcn'}}
|
96
96
|
},
|
97
97
|
'Webgen::SourceHandler::Feed' => {
|
98
98
|
'rss' => true,
|
99
|
-
'atom' => true
|
99
|
+
'atom' => true,
|
100
|
+
'blocks' => {'default' => {'pipeline' => 'erb'}}
|
100
101
|
},
|
101
102
|
'Webgen::SourceHandler::Sitemap' => {
|
102
103
|
'default_priority' => 0.5,
|
103
104
|
'default_change_freq' => 'weekly',
|
104
|
-
'common.sitemap.any_lang' => true
|
105
|
+
'common.sitemap.any_lang' => true,
|
106
|
+
'blocks' => {'default' => {'pipeline' => 'erb'}}
|
105
107
|
}
|
106
108
|
}, :doc => "Default meta information for all nodes and for nodes belonging to a specific source handler")
|
107
109
|
|
@@ -137,10 +139,12 @@ config.contentprocessor.map({
|
|
137
139
|
'erubis' => 'Webgen::ContentProcessor::Erubis',
|
138
140
|
'rdiscount' => 'Webgen::ContentProcessor::RDiscount',
|
139
141
|
'fragments' => 'Webgen::ContentProcessor::Fragments',
|
142
|
+
'head' => 'Webgen::ContentProcessor::Head'
|
140
143
|
}, :doc => 'Content processor name to class map')
|
141
144
|
|
142
145
|
Webgen::WebsiteAccess.website.blackboard.add_service(:content_processor_names, Webgen::ContentProcessor.method(:list))
|
143
146
|
Webgen::WebsiteAccess.website.blackboard.add_service(:content_processor, Webgen::ContentProcessor.method(:for_name))
|
147
|
+
Webgen::WebsiteAccess.website.blackboard.add_service(:content_processor_binary?, Webgen::ContentProcessor.method(:is_binary?))
|
144
148
|
|
145
149
|
# All things regarding tags
|
146
150
|
config.contentprocessor.tags.prefix('', :doc => 'The prefix used for tag names to avoid name clashes when another content processor uses similar markup.')
|
data/lib/webgen/node.rb
CHANGED
@@ -116,7 +116,7 @@ module Webgen
|
|
116
116
|
end
|
117
117
|
|
118
118
|
# Check if the node is a directory.
|
119
|
-
def is_directory?; @path[-1] ==
|
119
|
+
def is_directory?; @path[-1] == ?/ && !is_fragment?; end
|
120
120
|
|
121
121
|
# Check if the node is a file.
|
122
122
|
def is_file?; !is_directory? && !is_fragment?; end
|
data/lib/webgen/output.rb
CHANGED
@@ -18,8 +18,10 @@ module Webgen
|
|
18
18
|
# Write the +data+ to the given output +path+. The parameter +data+ is either a String with the
|
19
19
|
# content or a Webgen::Path::SourceIO object. The parameter +type+ specifies the type of the to
|
20
20
|
# be written path: <tt>:file</tt> or <tt>:directory</tt>.
|
21
|
-
# [<tt>read(path)</tt>]
|
22
|
-
# Return the content of the given path if it exists or raise an error otherwise.
|
21
|
+
# [<tt>read(path, mode = 'rb')</tt>]
|
22
|
+
# Return the content of the given path if it exists or raise an error otherwise. The parameter
|
23
|
+
# +mode+ specifies the mode in which the path should be opened and defaults to reading in binary
|
24
|
+
# mode.
|
23
25
|
#
|
24
26
|
# It seems a bit odd that an output instance has to implement reading functionality. However,
|
25
27
|
# consider the case where you want webgen to render a website programmatically and *use* the
|
@@ -52,7 +54,7 @@ module Webgen
|
|
52
54
|
# @data[path] = [(io.kind_of?(String) ? io : io.data), type]
|
53
55
|
# end
|
54
56
|
#
|
55
|
-
# def read(path)
|
57
|
+
# def read(path, mode = 'rb')
|
56
58
|
# path = File.join('/', path)
|
57
59
|
# raise "No such file #{path}" unless @data[path] && @data[path].last == :file
|
58
60
|
# @data[path].first
|
@@ -50,7 +50,7 @@ module Webgen::Output
|
|
50
50
|
if data.kind_of?(String)
|
51
51
|
File.open(dest, 'wb') {|f| f.write(data) }
|
52
52
|
else
|
53
|
-
data.stream do |source|
|
53
|
+
data.stream('rb') do |source|
|
54
54
|
File.open(dest, 'wb') {|f| FileUtils.copy_stream(source, f) }
|
55
55
|
end
|
56
56
|
end
|
@@ -59,9 +59,9 @@ module Webgen::Output
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
# Return the content of the given +path+.
|
63
|
-
def read(path)
|
64
|
-
File.open(File.join(@root, path),
|
62
|
+
# Return the content of the given +path+ which is opened in +mode+.
|
63
|
+
def read(path, mode = 'rb')
|
64
|
+
File.open(File.join(@root, path), mode) {|f| f.read}
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
data/lib/webgen/path.rb
CHANGED
@@ -49,16 +49,21 @@ module Webgen
|
|
49
49
|
|
50
50
|
# Provide direct access to the wrapped IO object by yielding it. After the method block
|
51
51
|
# returns the IO object is automatically closed.
|
52
|
-
|
53
|
-
|
52
|
+
#
|
53
|
+
# The parameter +mode+ specifies the mode in which the wrapped IO object should be opened.
|
54
|
+
# This can be used, for example, to open a file in binary mode (or specify a certain input
|
55
|
+
# encoding under Ruby 1.9).
|
56
|
+
def stream(mode = 'r')
|
57
|
+
io = @block.call(mode)
|
54
58
|
yield(io)
|
55
59
|
ensure
|
56
60
|
io.close
|
57
61
|
end
|
58
62
|
|
59
|
-
# Return the whole content of the wrapped IO object as string.
|
60
|
-
|
61
|
-
|
63
|
+
# Return the whole content of the wrapped IO object as string. For a description of the
|
64
|
+
# parameter +mode+ see #stream.
|
65
|
+
def data(mode = 'r')
|
66
|
+
stream(mode) {|io| io.read}
|
62
67
|
end
|
63
68
|
|
64
69
|
end
|
@@ -14,7 +14,7 @@ module Webgen
|
|
14
14
|
|
15
15
|
# Create a new object with absolute path +path+ for the file system path +fs_path+.
|
16
16
|
def initialize(path, fs_path)
|
17
|
-
super(path) { File.open(fs_path,
|
17
|
+
super(path) {|mode| File.open(fs_path, mode) }
|
18
18
|
@fs_path = fs_path
|
19
19
|
WebsiteAccess.website.cache[[:fs_path, @fs_path]] = File.mtime(@fs_path)
|
20
20
|
@meta_info['modified_at'] = File.mtime(@fs_path)
|
@@ -24,7 +24,7 @@ module Webgen
|
|
24
24
|
|
25
25
|
# Create a new tar archive path object for the entry +entry+.
|
26
26
|
def initialize(path, data, mtime, uri)
|
27
|
-
super(path) { StringIO.new(data.to_s) }
|
27
|
+
super(path) {|mode| StringIO.new(data.to_s, mode) }
|
28
28
|
@uri = uri
|
29
29
|
@mtime = mtime
|
30
30
|
WebsiteAccess.website.cache[[:tararchive_path, @uri, path]] = @mtime if WebsiteAccess.website
|
@@ -30,7 +30,8 @@ module Webgen::SourceHandler
|
|
30
30
|
def content(node)
|
31
31
|
io = website.blackboard.invoke(:source_paths)[node.node_info[:src]].io
|
32
32
|
if node.node_info[:preprocessor]
|
33
|
-
|
33
|
+
is_binary = website.blackboard.invoke(:content_processor_binary?, node.node_info[:preprocessor])
|
34
|
+
context = Webgen::Context.new(:content => io.data(is_binary ? 'rb' : 'r'), :chain => [node])
|
34
35
|
website.blackboard.invoke(:content_processor, node.node_info[:preprocessor]).call(context)
|
35
36
|
context.content
|
36
37
|
else
|
@@ -16,32 +16,28 @@ module Webgen::SourceHandler
|
|
16
16
|
|
17
17
|
# Create an XML sitemap from +path+.
|
18
18
|
def create_node(path)
|
19
|
-
page_from_path(path)
|
19
|
+
page = page_from_path(path)
|
20
20
|
path.ext = 'xml'
|
21
21
|
raise "Needed information site_url missing for sitemap <#{path}>" if path.meta_info['site_url'].nil?
|
22
|
-
super(path)
|
22
|
+
super(path) do |node|
|
23
|
+
node.node_info[:sitemap] = page
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
# Return the rendered feed represented by +node+.
|
26
28
|
def content(node)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
29
|
+
if node.node_info[:sitemap].blocks.has_key?('template')
|
30
|
+
node.node_info[:sitemap].blocks['template'].render(Webgen::Context.new(:chain => [node])).content
|
31
|
+
else
|
32
|
+
chain = [node.resolve("/templates/sitemap.template"), node]
|
33
|
+
node.node_info[:used_nodes] << chain.first.alcn
|
34
|
+
chain.first.node_info[:page].blocks['content'].render(Webgen::Context.new(:chain => chain)).content
|
43
35
|
end
|
44
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the alcns of the sitemap +node+ as a flat list.
|
39
|
+
def alcns(node)
|
40
|
+
website.blackboard.invoke(:create_sitemap, node, node.lang, options_for_node(node)).to_lcn_list.flatten
|
45
41
|
end
|
46
42
|
|
47
43
|
#######
|
@@ -10,7 +10,7 @@ class TestContentProcessor < Test::Unit::TestCase
|
|
10
10
|
|
11
11
|
def setup
|
12
12
|
super
|
13
|
-
@website.config.data['contentprocessor.map'] = {'test' => Hash}
|
13
|
+
@website.config.data['contentprocessor.map'] = {'test' => Hash, 'binary' => [Hash, :binary]}
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_access_hash
|
@@ -22,12 +22,18 @@ class TestContentProcessor < Test::Unit::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_list
|
25
|
-
assert_equal(['test'], Webgen::ContentProcessor.list)
|
25
|
+
assert_equal(['binary', 'test'], Webgen::ContentProcessor.list.sort)
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_for_name
|
29
29
|
assert_kind_of(Hash, Webgen::ContentProcessor.for_name('test'))
|
30
|
+
assert_kind_of(Hash, Webgen::ContentProcessor.for_name('binary'))
|
30
31
|
assert_nil(Webgen::ContentProcessor.for_name('other'))
|
31
32
|
end
|
32
33
|
|
34
|
+
def test_is_binary
|
35
|
+
assert(!Webgen::ContentProcessor.is_binary?('test'))
|
36
|
+
assert(Webgen::ContentProcessor.is_binary?('binary'))
|
37
|
+
end
|
38
|
+
|
33
39
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'helper'
|
5
|
+
require 'webgen/tree'
|
6
|
+
require 'webgen/page'
|
7
|
+
require 'webgen/contentprocessor'
|
8
|
+
|
9
|
+
class TestContentProcessorHead < Test::Unit::TestCase
|
10
|
+
|
11
|
+
include Test::WebsiteHelper
|
12
|
+
|
13
|
+
def test_call
|
14
|
+
obj = Webgen::ContentProcessor::Head.new
|
15
|
+
root = Webgen::Node.new(Webgen::Tree.new.dummy_root, '/', '/')
|
16
|
+
node = Webgen::Node.new(root, 'test', 'test')
|
17
|
+
|
18
|
+
context = Webgen::Context.new(:chain => [node])
|
19
|
+
context.content = '</head>'
|
20
|
+
obj.call(context)
|
21
|
+
assert_equal('</head>', context.content)
|
22
|
+
|
23
|
+
context.content = '</head>'
|
24
|
+
context[:cp_head] = {
|
25
|
+
:js_file => ['hallo.js', 'hallo2.js'],
|
26
|
+
:js_inline => ["somescript", "anotherscript"],
|
27
|
+
:css_file => ['hallo.css', 'hallo2.css'],
|
28
|
+
:css_inline => ["somestyle", "anotherstyle"],
|
29
|
+
:meta => {:lucky => 'me<"'}
|
30
|
+
}
|
31
|
+
obj.call(context)
|
32
|
+
assert_equal("\n<script type=\"text/javascript\" src=\"hallo.js\"></script>" +
|
33
|
+
"\n<script type=\"text/javascript\" src=\"hallo2.js\"></script>" +
|
34
|
+
"\n<script type=\"text/javascript\">\nsomescript\n</script>" +
|
35
|
+
"\n<script type=\"text/javascript\">\nanotherscript\n</script>" +
|
36
|
+
"\n<link rel=\"stylesheet\" href=\"hallo.css\" type=\"text/css\"/>" +
|
37
|
+
"\n<link rel=\"stylesheet\" href=\"hallo2.css\" type=\"text/css\"/>" +
|
38
|
+
"\n<style type=\"text/css\"><![CDATA[/\nsomestyle\n]]></style>" +
|
39
|
+
"\n<style type=\"text/css\"><![CDATA[/\nanotherstyle\n]]></style>" +
|
40
|
+
"\n<meta name=\"lucky\" content=\"me<"\" /></head>", context.content)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/test/test_node.rb
CHANGED
@@ -23,7 +23,7 @@ class TestNode < Test::Unit::TestCase
|
|
23
23
|
:other_en => Webgen::Node.new(node, '/other1.html', 'other.page', {'lang' => 'en'}),
|
24
24
|
:somename_en_frag => frag_en = Webgen::Node.new(child_en, '/somename.en.html#frag', '#othertest', {'title' => 'frag'}),
|
25
25
|
:somename_de_frag => Webgen::Node.new(child_de, '/somename.de.html#frag', '#othertest'),
|
26
|
-
:somename_en_fragnest => Webgen::Node.new(frag_en, '/somename.en.html#fragnest', '#nestedpath'),
|
26
|
+
:somename_en_fragnest => Webgen::Node.new(frag_en, '/somename.en.html#fragnest/', '#nestedpath'),
|
27
27
|
:dir => dir = Webgen::Node.new(node, '/dir/', 'dir/'),
|
28
28
|
:dir_file => dir_file = Webgen::Node.new(dir, '/dir/file.html', 'file.html'),
|
29
29
|
:dir_file_frag => Webgen::Node.new(dir_file, '/dir/file.html#frag', '#frag'),
|
@@ -74,6 +74,8 @@ class TestNode < Test::Unit::TestCase
|
|
74
74
|
assert(nodes[:somename_en_frag].is_fragment?)
|
75
75
|
assert(nodes[:root].is_root?)
|
76
76
|
assert(!nodes[:somename_en].is_root?)
|
77
|
+
assert(nodes[:somename_en_fragnest].is_fragment?)
|
78
|
+
assert(!nodes[:somename_en_fragnest].is_directory?)
|
77
79
|
end
|
78
80
|
|
79
81
|
def test_meta_info_assignment
|
data/test/test_path.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'webgen/path'
|
5
5
|
require 'stringio'
|
6
|
+
require 'tmpdir'
|
6
7
|
|
7
8
|
class TestPath < Test::Unit::TestCase
|
8
9
|
|
@@ -130,6 +131,19 @@ class TestPath < Test::Unit::TestCase
|
|
130
131
|
p = Webgen::Path.new('/test.de.page') { StringIO.new('hallo') }
|
131
132
|
assert_equal('hallo', p.io.data)
|
132
133
|
assert_equal('hallo', p.io.stream {|f| f.read })
|
134
|
+
|
135
|
+
if RUBY_VERSION >= '1.9'
|
136
|
+
begin
|
137
|
+
dir = File.join(Dir.tmpdir, 'webgen-' + Process.pid.to_s)
|
138
|
+
FileUtils.mkdir_p(dir)
|
139
|
+
File.open(File.join(dir, 'src'), 'wb+') {|f| f.write("\303\274")}
|
140
|
+
sio = Webgen::Path::SourceIO.new {|mode| File.open(File.join(dir, 'src'), mode) }
|
141
|
+
assert_equal(1, sio.data('r:UTF-8').length)
|
142
|
+
assert_equal(2, sio.data('rb').length)
|
143
|
+
ensure
|
144
|
+
FileUtils.rm_rf(dir) if dir
|
145
|
+
end
|
146
|
+
end
|
133
147
|
end
|
134
148
|
|
135
149
|
def test_equality
|
@@ -168,6 +182,7 @@ class TestPath < Test::Unit::TestCase
|
|
168
182
|
path = '/dir/'
|
169
183
|
assert(Webgen::Path.match(path, '/dir/'))
|
170
184
|
assert(Webgen::Path.match(path, '/dir'))
|
185
|
+
assert(Webgen::Path.match(path, '/*/'))
|
171
186
|
|
172
187
|
path = '/dir'
|
173
188
|
assert(Webgen::Path.match(path, '/dir/'))
|
@@ -15,6 +15,9 @@ class TestSourceHandlerMetainfo < Test::Unit::TestCase
|
|
15
15
|
/default.*:
|
16
16
|
title: new title
|
17
17
|
before: valbef
|
18
|
+
|
19
|
+
/*/:
|
20
|
+
title: test
|
18
21
|
---
|
19
22
|
/default.css:
|
20
23
|
after: valaft
|
@@ -28,6 +31,7 @@ EOF
|
|
28
31
|
@website.blackboard.add_service(:source_paths) do
|
29
32
|
{'/default.css' => path_with_meta_info('/default.css') {StringIO.new('# header')},
|
30
33
|
'/other.page' => path_with_meta_info('/other.page') {StringIO.new('other page')},
|
34
|
+
'/hallo/' => path_with_meta_info('/hallo/')
|
31
35
|
}
|
32
36
|
end
|
33
37
|
|
@@ -37,7 +41,8 @@ EOF
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def test_create_node
|
40
|
-
assert_equal({'/default.*' => {'title' => 'new title', 'before' => 'valbef'}
|
44
|
+
assert_equal({'/default.*' => {'title' => 'new title', 'before' => 'valbef'},
|
45
|
+
'/*' => {'title' => 'test'}}, @node.node_info[:mi_paths])
|
41
46
|
assert_equal({'/default.css' => {'after' => 'valaft'},
|
42
47
|
'/other.page' => {'title' => 'Not Other'}}, @node.node_info[:mi_alcn])
|
43
48
|
end
|
@@ -75,6 +80,10 @@ EOF
|
|
75
80
|
path = path_with_meta_info('/default.css')
|
76
81
|
@website.blackboard.dispatch_msg(:before_node_created, path)
|
77
82
|
assert('valbef', path.meta_info['before'])
|
83
|
+
|
84
|
+
path = path_with_meta_info('/hallo/')
|
85
|
+
@website.blackboard.dispatch_msg(:before_node_created, path)
|
86
|
+
assert('test', path.meta_info['title'])
|
78
87
|
end
|
79
88
|
|
80
89
|
def test_after_node_created
|
@@ -13,10 +13,21 @@ class TestSourceHandlerSitemap < Test::Unit::TestCase
|
|
13
13
|
---
|
14
14
|
site_url: http://example.com
|
15
15
|
default_change_freq: daily
|
16
|
+
EOF
|
17
|
+
|
18
|
+
SITEMAP_CONTENT_TEMPLATE = <<EOF
|
19
|
+
---
|
20
|
+
site_url: http://example.com
|
21
|
+
default_change_freq: daily
|
22
|
+
--- name:template
|
23
|
+
Yeah <%= context.node['title'] %>
|
16
24
|
EOF
|
17
25
|
|
18
26
|
def setup
|
19
27
|
super
|
28
|
+
shm = Webgen::SourceHandler::Main.new
|
29
|
+
@website.blackboard.del_listener(:node_meta_info_changed?, shm.method(:meta_info_changed?))
|
30
|
+
@website.config['passive_sources'] << ['/', "Webgen::Source::Resource", "webgen-passive-sources"]
|
20
31
|
@nodes = create_sitemap_nodes
|
21
32
|
@nodes.each {|k,v| v['modified_at'] = Time.now}
|
22
33
|
@nodes[:file11_en]['priority'] = 0.9
|
@@ -37,6 +48,14 @@ EOF
|
|
37
48
|
end
|
38
49
|
end
|
39
50
|
|
51
|
+
def test_create_node_with_own_template
|
52
|
+
@path = path_with_meta_info('/test.sitemap', {}, @obj.class.name) {StringIO.new(SITEMAP_CONTENT_TEMPLATE)}
|
53
|
+
sitemap = @obj.create_node(@path)
|
54
|
+
sitemap['title'] = 'test'
|
55
|
+
assert_not_nil(sitemap)
|
56
|
+
assert_equal('Yeah test', sitemap.content)
|
57
|
+
end
|
58
|
+
|
40
59
|
def test_content
|
41
60
|
sitemap = @obj.create_node(@path)
|
42
61
|
content = sitemap.content
|
data/test/test_tag_base.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gettalong-webgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.9.
|
4
|
+
version: 0.5.9.20090626
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Leitner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-25 15:00:00 -07:00
|
13
13
|
default_executable: webgen
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -201,6 +201,7 @@ files:
|
|
201
201
|
- data/webgen/passive_sources/templates
|
202
202
|
- data/webgen/passive_sources/templates/atom_feed.template
|
203
203
|
- data/webgen/passive_sources/templates/rss_feed.template
|
204
|
+
- data/webgen/passive_sources/templates/sitemap.template
|
204
205
|
- data/webgen/resources.yaml
|
205
206
|
- data/webgen/webgui
|
206
207
|
- data/webgen/webgui/app.rb
|
@@ -359,6 +360,7 @@ files:
|
|
359
360
|
- doc/contentprocessor/erubis.page
|
360
361
|
- doc/contentprocessor/fragments.page
|
361
362
|
- doc/contentprocessor/haml.page
|
363
|
+
- doc/contentprocessor/head.page
|
362
364
|
- doc/contentprocessor/maruku.page
|
363
365
|
- doc/contentprocessor/rdiscount.page
|
364
366
|
- doc/contentprocessor/rdoc.page
|
@@ -424,6 +426,7 @@ files:
|
|
424
426
|
- lib/webgen/contentprocessor/erubis.rb
|
425
427
|
- lib/webgen/contentprocessor/fragments.rb
|
426
428
|
- lib/webgen/contentprocessor/haml.rb
|
429
|
+
- lib/webgen/contentprocessor/head.rb
|
427
430
|
- lib/webgen/contentprocessor/maruku.rb
|
428
431
|
- lib/webgen/contentprocessor/rdiscount.rb
|
429
432
|
- lib/webgen/contentprocessor/rdoc.rb
|
@@ -510,6 +513,7 @@ files:
|
|
510
513
|
- test/test_contentprocessor_erubis.rb
|
511
514
|
- test/test_contentprocessor_fragments.rb
|
512
515
|
- test/test_contentprocessor_haml.rb
|
516
|
+
- test/test_contentprocessor_head.rb
|
513
517
|
- test/test_contentprocessor_maruku.rb
|
514
518
|
- test/test_contentprocessor_rdiscount.rb
|
515
519
|
- test/test_contentprocessor_rdoc.rb
|