nitro 0.20.0 → 0.21.0
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/CHANGELOG +752 -543
- data/INSTALL +38 -38
- data/README +264 -225
- data/Rakefile +48 -49
- data/bin/nitro +3 -3
- data/bin/nitrogen +6 -6
- data/doc/AUTHORS +10 -10
- data/doc/CHANGELOG.1 +1939 -1939
- data/doc/CHANGELOG.2 +954 -954
- data/doc/LICENSE +3 -3
- data/doc/MIGRATION +28 -0
- data/doc/RELEASES +814 -643
- data/doc/config.txt +5 -5
- data/install.rb +7 -17
- data/lib/nitro.rb +38 -9
- data/lib/nitro/adapter/cgi.rb +311 -312
- data/lib/nitro/adapter/fastcgi.rb +18 -25
- data/lib/nitro/adapter/webrick.rb +128 -137
- data/lib/nitro/adapter/wee.rb +51 -0
- data/lib/nitro/caching.rb +20 -20
- data/lib/nitro/caching/actions.rb +43 -43
- data/lib/nitro/caching/fragments.rb +46 -46
- data/lib/nitro/caching/invalidation.rb +11 -11
- data/lib/nitro/caching/output.rb +65 -65
- data/lib/nitro/caching/stores.rb +67 -67
- data/lib/nitro/compiler.rb +262 -0
- data/lib/nitro/compiler/elements.rb +0 -0
- data/lib/nitro/compiler/errors.rb +65 -0
- data/lib/nitro/compiler/localization.rb +25 -0
- data/lib/nitro/compiler/markup.rb +19 -0
- data/lib/nitro/compiler/shaders.rb +206 -0
- data/lib/nitro/compiler/squeeze.rb +20 -0
- data/lib/nitro/compiler/xslt.rb +61 -0
- data/lib/nitro/context.rb +87 -88
- data/lib/nitro/controller.rb +151 -158
- data/lib/nitro/cookie.rb +34 -34
- data/lib/nitro/dispatcher.rb +195 -186
- data/lib/nitro/element.rb +132 -126
- data/lib/nitro/element/java_script.rb +6 -6
- data/lib/nitro/flash.rb +66 -66
- data/lib/nitro/mail.rb +192 -192
- data/lib/nitro/mixin/buffer.rb +66 -0
- data/lib/nitro/mixin/debug.rb +16 -16
- data/lib/nitro/mixin/form.rb +88 -0
- data/lib/nitro/mixin/helper.rb +2 -2
- data/lib/nitro/mixin/javascript.rb +108 -108
- data/lib/nitro/mixin/markup.rb +144 -0
- data/lib/nitro/mixin/pager.rb +202 -202
- data/lib/nitro/mixin/rss.rb +67 -0
- data/lib/nitro/mixin/table.rb +63 -0
- data/lib/nitro/mixin/xhtml.rb +75 -0
- data/lib/nitro/mixin/xml.rb +124 -0
- data/lib/nitro/render.rb +183 -359
- data/lib/nitro/request.rb +140 -140
- data/lib/nitro/response.rb +27 -27
- data/lib/nitro/routing.rb +21 -21
- data/lib/nitro/scaffold.rb +124 -118
- data/lib/nitro/server.rb +117 -80
- data/lib/nitro/server/runner.rb +341 -0
- data/lib/nitro/service.rb +12 -12
- data/lib/nitro/service/xmlrpc.rb +22 -22
- data/lib/nitro/session.rb +122 -120
- data/lib/nitro/session/drb.rb +9 -9
- data/lib/nitro/session/drbserver.rb +34 -34
- data/lib/nitro/template.rb +171 -155
- data/lib/nitro/testing/assertions.rb +90 -90
- data/lib/nitro/testing/context.rb +16 -16
- data/lib/nitro/testing/testcase.rb +34 -34
- data/proto/conf/lhttpd.conf +9 -9
- data/proto/public/error.xhtml +75 -75
- data/proto/public/index.xhtml +18 -18
- data/proto/public/js/behaviour.js +65 -65
- data/proto/public/js/controls.js +1 -1
- data/proto/public/js/prototype.js +3 -3
- data/proto/public/settings.xhtml +61 -61
- data/proto/run.rb +1 -5
- data/test/nitro/adapter/raw_post1.bin +0 -0
- data/test/nitro/adapter/tc_cgi.rb +57 -57
- data/test/nitro/adapter/tc_webrick.rb +4 -4
- data/test/nitro/mixin/tc_pager.rb +25 -25
- data/test/nitro/mixin/tc_rss.rb +24 -0
- data/test/nitro/mixin/tc_table.rb +31 -0
- data/test/nitro/mixin/tc_xhtml.rb +13 -0
- data/test/nitro/tc_caching.rb +10 -10
- data/test/nitro/tc_context.rb +8 -8
- data/test/nitro/tc_controller.rb +48 -48
- data/test/nitro/tc_cookie.rb +6 -6
- data/test/nitro/tc_dispatcher.rb +64 -64
- data/test/nitro/tc_element.rb +27 -27
- data/test/nitro/tc_flash.rb +31 -31
- data/test/nitro/tc_mail.rb +63 -63
- data/test/nitro/tc_server.rb +26 -26
- data/test/nitro/tc_session.rb +9 -9
- data/test/nitro/tc_template.rb +19 -19
- data/test/public/blog/list.xhtml +1 -1
- metadata +31 -37
- data/lib/nitro/buffering.rb +0 -45
- data/lib/nitro/builder/form.rb +0 -104
- data/lib/nitro/builder/rss.rb +0 -104
- data/lib/nitro/builder/table.rb +0 -80
- data/lib/nitro/builder/xhtml.rb +0 -132
- data/lib/nitro/builder/xml.rb +0 -131
- data/lib/nitro/conf.rb +0 -36
- data/lib/nitro/environment.rb +0 -21
- data/lib/nitro/errors.rb +0 -69
- data/lib/nitro/localization.rb +0 -153
- data/lib/nitro/markup.rb +0 -147
- data/lib/nitro/output.rb +0 -24
- data/lib/nitro/runner.rb +0 -348
- data/lib/nitro/shaders.rb +0 -206
- data/test/nitro/builder/tc_rss.rb +0 -23
- data/test/nitro/builder/tc_table.rb +0 -30
- data/test/nitro/builder/tc_xhtml.rb +0 -39
- data/test/nitro/builder/tc_xml.rb +0 -56
- data/test/nitro/tc_localization.rb +0 -49
data/lib/nitro/builder/rss.rb
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
require 'rss/0.9'
|
|
2
|
-
|
|
3
|
-
require 'glue/string'
|
|
4
|
-
require 'nitro/builder/xml'
|
|
5
|
-
|
|
6
|
-
module Nitro
|
|
7
|
-
|
|
8
|
-
# Build RSS represenations of ruby object collections.
|
|
9
|
-
# Utilize duck typing to grab the attributes to render.
|
|
10
|
-
# Add this mixin to you classes to support RSS rendering.
|
|
11
|
-
#
|
|
12
|
-
#--
|
|
13
|
-
# TODO: add more options here, 1.0/2.0 support and more.
|
|
14
|
-
# use custom version to add headers like the following.
|
|
15
|
-
# <?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
-
# <?xml-stylesheet href="rss.css" type="text/css"?>
|
|
17
|
-
#++
|
|
18
|
-
|
|
19
|
-
module RssBuilderMixin
|
|
20
|
-
include XmlBuilderMixin
|
|
21
|
-
|
|
22
|
-
# === Options
|
|
23
|
-
#
|
|
24
|
-
# [+:description+]
|
|
25
|
-
# Description of the Feed
|
|
26
|
-
# [+:base+]
|
|
27
|
-
# Base url of the Feed.
|
|
28
|
-
# [+:link+]
|
|
29
|
-
# Link of the Feed.
|
|
30
|
-
|
|
31
|
-
def build_rss_09(objects, options = {})
|
|
32
|
-
c = {
|
|
33
|
-
:description => 'Syndication'
|
|
34
|
-
}.update(options)
|
|
35
|
-
|
|
36
|
-
c[:base] ||= c[:link]
|
|
37
|
-
|
|
38
|
-
raise "Option ':base' cannot be infered!" unless c[:base]
|
|
39
|
-
|
|
40
|
-
channel = RSS::Rss::Channel.new
|
|
41
|
-
channel.description = c[:description]
|
|
42
|
-
channel.link = c[:link] if c[:link]
|
|
43
|
-
|
|
44
|
-
for obj in objects
|
|
45
|
-
item = RSS::Rss::Channel::Item.new
|
|
46
|
-
item.title = obj.title if obj.respond_to?(:title)
|
|
47
|
-
# item.description = CGI.escape(Glue::StringUtils.head(obj.body, 256)) if obj.respond_to?(:body)
|
|
48
|
-
item.link = "#{c[:base]}/#{obj.to_href}" if obj.respond_to?(:to_href)
|
|
49
|
-
channel.items << item
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
rss = RSS::Rss.new '0.9'
|
|
53
|
-
rss.channel = channel
|
|
54
|
-
|
|
55
|
-
self << rss.to_s
|
|
56
|
-
end
|
|
57
|
-
alias_method :build_rss, :build_rss_09
|
|
58
|
-
|
|
59
|
-
=begin
|
|
60
|
-
Experimental.
|
|
61
|
-
|
|
62
|
-
def build_rss(objects, options = {})
|
|
63
|
-
# pi! :xml, :version => '1.0', :encoding => 'UTF-8'
|
|
64
|
-
self << '<?xml version="1.0" encoding="UTF-8" ?>'
|
|
65
|
-
self << '<?xml-stylesheet href="rss.css" type="text/css" ?>'
|
|
66
|
-
rss(:version => '2.0',
|
|
67
|
-
'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
|
|
68
|
-
'xmlns:trackback' => 'http://madskills.com/public/xml/rss/module/trackback/') {
|
|
69
|
-
channel {
|
|
70
|
-
title 'koko'
|
|
71
|
-
language 'en-us'
|
|
72
|
-
ttl '40'
|
|
73
|
-
description 'hello lamer'
|
|
74
|
-
|
|
75
|
-
for obj in objects
|
|
76
|
-
item {
|
|
77
|
-
title(obj.title)
|
|
78
|
-
description(obj.body)
|
|
79
|
-
trackback :ping => 'http://www.joy.gr'
|
|
80
|
-
}
|
|
81
|
-
end
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
end
|
|
85
|
-
=end
|
|
86
|
-
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Abstract class for the RssBuilderMixin.
|
|
90
|
-
|
|
91
|
-
class RssBuilder < String
|
|
92
|
-
include RssBuilderMixin
|
|
93
|
-
|
|
94
|
-
class << self
|
|
95
|
-
def build_09(objects, options = {})
|
|
96
|
-
RssBuilder.new.build_rss_09(objects, options)
|
|
97
|
-
end
|
|
98
|
-
alias_method :build, :build_09
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/builder/table.rb
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
module Nitro
|
|
2
|
-
|
|
3
|
-
# The TableBuilder is a helper class that automates the creation
|
|
4
|
-
# of tables from collections of objects. The resulting html
|
|
5
|
-
# can be styled using css.
|
|
6
|
-
#
|
|
7
|
-
# === Example
|
|
8
|
-
#
|
|
9
|
-
# <?r
|
|
10
|
-
# users = User.all.map { |u| [u.name, u.first_name, u.last_name, u.email] }
|
|
11
|
-
# header = ['Username', 'First name', 'Last name', 'Email']
|
|
12
|
-
# ?>
|
|
13
|
-
#
|
|
14
|
-
# <div class="custom-table-class">
|
|
15
|
-
# #{N::TableBuilder.build(users, header)}
|
|
16
|
-
# </div>
|
|
17
|
-
#
|
|
18
|
-
# or:
|
|
19
|
-
#
|
|
20
|
-
# <div class="custom-table-class">
|
|
21
|
-
# #{@out.build_table(users, header)}
|
|
22
|
-
# </div>
|
|
23
|
-
#--
|
|
24
|
-
# TODO: sorting, thead/tbody/legend etc, verbose...
|
|
25
|
-
#++
|
|
26
|
-
|
|
27
|
-
module TableBuilderMixin
|
|
28
|
-
|
|
29
|
-
# [+options+]
|
|
30
|
-
# A hash of options.
|
|
31
|
-
#
|
|
32
|
-
# :id = id of the component.
|
|
33
|
-
# :headers = an array of the header values
|
|
34
|
-
# :values = an array of arrays.
|
|
35
|
-
|
|
36
|
-
def build_table(options)
|
|
37
|
-
c = options
|
|
38
|
-
|
|
39
|
-
buf = '<table'
|
|
40
|
-
buf << %| id="#{c[:id]}"| if c[:id]
|
|
41
|
-
buf << '><tr>'
|
|
42
|
-
|
|
43
|
-
for h in c[:headers]
|
|
44
|
-
buf << %|<th>#{h}</th>|
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
buf << "</tr>"
|
|
48
|
-
|
|
49
|
-
for row in c[:values]
|
|
50
|
-
buf << "<tr>"
|
|
51
|
-
|
|
52
|
-
for v in row
|
|
53
|
-
buf << %|<td>#{v}</td>|
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
buf << "</tr>"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
buf << "</table>"
|
|
60
|
-
|
|
61
|
-
return buf
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Abstract class for the TableBuilderMixin.
|
|
67
|
-
|
|
68
|
-
class TableBuilder
|
|
69
|
-
include TableBuilderMixin
|
|
70
|
-
|
|
71
|
-
class << self
|
|
72
|
-
def build(options)
|
|
73
|
-
TableBuilder.new.build_table(options)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/builder/xhtml.rb
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
require 'nitro/builder/xml'
|
|
2
|
-
|
|
3
|
-
module Nitro
|
|
4
|
-
|
|
5
|
-
# A helper mixin for programmatically building XHTML
|
|
6
|
-
# blocks.
|
|
7
|
-
|
|
8
|
-
module XhtmlBuilderMixin
|
|
9
|
-
|
|
10
|
-
# Render select.
|
|
11
|
-
#
|
|
12
|
-
# The first argument can be a String denoting the
|
|
13
|
-
# default option.
|
|
14
|
-
#--
|
|
15
|
-
# gmosx: hmmm String defines select, this is bad!
|
|
16
|
-
#++
|
|
17
|
-
|
|
18
|
-
def select(*args)
|
|
19
|
-
attrs = args.last.is_a?(Hash) ? args.pop : nil
|
|
20
|
-
start_tag!('select', attrs)
|
|
21
|
-
self << %|<option>#{args.first}</option>| unless args.empty?
|
|
22
|
-
yield
|
|
23
|
-
end_tag!('select')
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Render select options.
|
|
27
|
-
#
|
|
28
|
-
# [+opts+]
|
|
29
|
-
# The options to render, can be an Array or a
|
|
30
|
-
# Hash (allows you to explicitly set the value
|
|
31
|
-
# mapping).
|
|
32
|
-
#
|
|
33
|
-
# [+selected+]
|
|
34
|
-
# The value of the selected option.
|
|
35
|
-
#
|
|
36
|
-
# == Example
|
|
37
|
-
#
|
|
38
|
-
# options = ['Male', 'Female']
|
|
39
|
-
# o.select(:name => 'sex') {
|
|
40
|
-
# o.options(options, selected = 1)
|
|
41
|
-
# }
|
|
42
|
-
#
|
|
43
|
-
# or
|
|
44
|
-
#
|
|
45
|
-
# options = { 'Male' => 'm', 'Female' => 'f' }
|
|
46
|
-
# o.select(:name => 'sex') {
|
|
47
|
-
# o.options(options, selected = 1)
|
|
48
|
-
# }
|
|
49
|
-
|
|
50
|
-
def options(opts, selected = nil)
|
|
51
|
-
if opts.is_a?(Array)
|
|
52
|
-
selected = selected.to_i
|
|
53
|
-
opts.each_with_index do |label, value|
|
|
54
|
-
if value == selected
|
|
55
|
-
self << %|<option value="#{value}" selected="1">#{label}</option>|
|
|
56
|
-
else
|
|
57
|
-
self << %|<option value="#{value}">#{label}</option>|
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
else
|
|
61
|
-
opts.each do |label, value|
|
|
62
|
-
if value == selected
|
|
63
|
-
self << %|<option value="#{value}" selected="1">#{label}</option>|
|
|
64
|
-
else
|
|
65
|
-
self << %|<option value="#{value}">#{label}</option>|
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def submit(options = nil)
|
|
72
|
-
if options
|
|
73
|
-
opts = options.collect { |k, v| %[#{k}="#{v}"] }.join(' ')
|
|
74
|
-
self << %[<input type="submit" #{opts} />]
|
|
75
|
-
else
|
|
76
|
-
self << %|<input type="submit" />|
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# A String extension with XHTML generation
|
|
82
|
-
# functionality.
|
|
83
|
-
|
|
84
|
-
class XhtmlString < String
|
|
85
|
-
include XmlBuilderMixin
|
|
86
|
-
include XhtmlBuilderMixin
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# A class that encapsulats the XHTML generation
|
|
90
|
-
# functionality. Utilizes duck typing to redirect
|
|
91
|
-
# output to a target buffer.
|
|
92
|
-
|
|
93
|
-
class XhtmlBuilder
|
|
94
|
-
include XmlBuilderMixin
|
|
95
|
-
include XhtmlBuilderMixin
|
|
96
|
-
|
|
97
|
-
# The target receives the generated xml,
|
|
98
|
-
# should respond_to :<<
|
|
99
|
-
|
|
100
|
-
attr_accessor :target
|
|
101
|
-
|
|
102
|
-
def initialize(target = '')
|
|
103
|
-
@target = target
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def << (str)
|
|
107
|
-
@target << str
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def to_s
|
|
111
|
-
@target.to_s
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# * George Moschovitis <gm@navel.gr>
|
|
118
|
-
|
|
119
|
-
__END__
|
|
120
|
-
|
|
121
|
-
<?r
|
|
122
|
-
labels = []
|
|
123
|
-
values = []
|
|
124
|
-
?>
|
|
125
|
-
<select name="apis">
|
|
126
|
-
<option>-- Please select --</option>
|
|
127
|
-
#{build :options, labels, values, request['selected']}
|
|
128
|
-
#{b.options labels, values, request['selected']}
|
|
129
|
-
</select>
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
|
data/lib/nitro/builder/xml.rb
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
module Nitro
|
|
2
|
-
|
|
3
|
-
# A helper mixin for programmatically building XML
|
|
4
|
-
# blocks.
|
|
5
|
-
|
|
6
|
-
module XmlBuilderMixin
|
|
7
|
-
|
|
8
|
-
def method_missing(tag, *args, &block)
|
|
9
|
-
self.class.module_eval <<-"end_eval", __FILE__, __LINE__
|
|
10
|
-
def #{tag}(*args)
|
|
11
|
-
attrs = args.last.is_a?(Hash) ? args.pop : nil
|
|
12
|
-
|
|
13
|
-
if block_given?
|
|
14
|
-
start_tag!('#{tag}', attrs)
|
|
15
|
-
yield
|
|
16
|
-
end_tag!('#{tag}')
|
|
17
|
-
elsif (!args.empty?)
|
|
18
|
-
start_tag!('#{tag}', attrs)
|
|
19
|
-
self << args.first
|
|
20
|
-
end_tag!('#{tag}')
|
|
21
|
-
else
|
|
22
|
-
start_tag!('#{tag}', attrs, false)
|
|
23
|
-
self << ' />'
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end_eval
|
|
27
|
-
|
|
28
|
-
self.send(tag, *args, &block)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Emit the start (opening) tag of an element.
|
|
32
|
-
|
|
33
|
-
def start_tag!(tag, attributes = nil, close = true)
|
|
34
|
-
unless attributes
|
|
35
|
-
if close
|
|
36
|
-
self << "<#{tag}>"
|
|
37
|
-
else
|
|
38
|
-
self << "<#{tag}"
|
|
39
|
-
end
|
|
40
|
-
else
|
|
41
|
-
self << "<#{tag}"
|
|
42
|
-
for name, value in attributes
|
|
43
|
-
if value
|
|
44
|
-
self << %| #{name}="#{value}"|
|
|
45
|
-
else
|
|
46
|
-
self << %| #{name}="1"|
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
self << ">" if close
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
return self
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Emit the end (closing) tag of an element.
|
|
56
|
-
|
|
57
|
-
def end_tag!(tag)
|
|
58
|
-
self << "</#{tag}>"
|
|
59
|
-
|
|
60
|
-
return self
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Emit a text string.
|
|
64
|
-
|
|
65
|
-
def text!(str)
|
|
66
|
-
self << str
|
|
67
|
-
|
|
68
|
-
return self
|
|
69
|
-
end
|
|
70
|
-
alias_method :print, :text!
|
|
71
|
-
|
|
72
|
-
# Emit a comment.
|
|
73
|
-
|
|
74
|
-
def comment!(str)
|
|
75
|
-
self << "<!-- #{str} -->"
|
|
76
|
-
|
|
77
|
-
return self
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Emit a processing instruction.
|
|
81
|
-
|
|
82
|
-
def processing_instruction!(name, attributes = nil)
|
|
83
|
-
unless attributes
|
|
84
|
-
self << "<?#{name} ?>"
|
|
85
|
-
else
|
|
86
|
-
self << "<?#{name} "
|
|
87
|
-
attributes.each do |a, v|
|
|
88
|
-
self << %[#{a}="#{v}" ]
|
|
89
|
-
end
|
|
90
|
-
self << "?>"
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
alias_method :pi!, :processing_instruction!
|
|
94
|
-
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# A String extension with XML generation
|
|
98
|
-
# functionality.
|
|
99
|
-
|
|
100
|
-
class XmlString < String
|
|
101
|
-
include XmlBuilderMixin
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# A class that encapsulats the XML generation
|
|
105
|
-
# functionality. Utilizes duck typing to redirect
|
|
106
|
-
# output to a target buffer.
|
|
107
|
-
|
|
108
|
-
class XmlBuilder
|
|
109
|
-
include XmlBuilderMixin
|
|
110
|
-
|
|
111
|
-
# The target receives the generated xml,
|
|
112
|
-
# should respond_to :<<
|
|
113
|
-
|
|
114
|
-
attr_accessor :target
|
|
115
|
-
|
|
116
|
-
def initialize(target = '')
|
|
117
|
-
@target = target
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def << (str)
|
|
121
|
-
@target << str
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def to_s
|
|
125
|
-
@target.to_s
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# * George Moschovitis <gm@navel.gr>
|