gettalong-webgen 0.5.9.20090620 → 0.5.9.20090626
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.
- 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
|