nitro 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +150 -0
- data/README +1 -1
- data/RELEASES +89 -0
- data/Rakefile +3 -3
- data/{AUTHORS → doc/AUTHORS} +0 -0
- data/{LICENSE → doc/LICENSE} +0 -0
- data/doc/bugs.txt +2 -1
- data/examples/README.windows +2 -2
- data/examples/blog/lib/blog/controller.rb +9 -8
- data/examples/blog/log/apache.error_log +71 -0
- data/{lib/xsl → examples/blog/root}/base.xsl +0 -0
- data/examples/blog/root/error.xhtml +56 -0
- data/examples/blog/root/index.xhtml +2 -2
- data/examples/blog/root/recent_posts.xhtml +1 -1
- data/examples/blog/root/style.xsl +4 -4
- data/examples/blog/run.rb +1 -2
- data/examples/no_xsl_blog/root/index.xhtml +2 -2
- data/examples/no_xsl_blog/root/recent_posts.xhtml +1 -1
- data/examples/why_wiki/run.rb +19 -19
- data/lib/nitro.rb +2 -21
- data/lib/nitro/adapters/webrick.rb +19 -3
- data/lib/nitro/context.rb +15 -1
- data/lib/nitro/controller.rb +84 -49
- data/lib/nitro/dispatcher.rb +30 -6
- data/lib/nitro/markup.rb +4 -2
- data/lib/nitro/render.rb +15 -11
- data/lib/nitro/routing.rb +33 -0
- data/lib/nitro/runner.rb +38 -3
- data/lib/nitro/scaffold.rb +7 -4
- data/lib/nitro/shaders.rb +11 -4
- data/lib/nitro/template.rb +140 -0
- data/lib/og.rb +25 -11
- data/lib/og/adapter.rb +141 -7
- data/lib/og/adapters/mysql.rb +41 -3
- data/lib/og/adapters/oracle.rb +4 -3
- data/lib/og/adapters/psql.rb +3 -3
- data/lib/og/adapters/sqlite.rb +3 -3
- data/lib/og/connection.rb +5 -1
- data/lib/og/database.rb +26 -12
- data/lib/og/enchant.rb +50 -16
- data/lib/og/meta.rb +15 -15
- data/lib/og/observer.rb +53 -0
- data/test/glue/tc_property_type_checking.rb +3 -0
- data/test/nitro/tc_controller.rb +1 -1
- data/test/nitro/tc_dispatcher.rb +1 -1
- data/test/nitro/tc_template.rb +32 -0
- data/test/og/tc_many_to_many.rb +62 -0
- data/test/og/tc_observer.rb +85 -0
- data/test/tc_og.rb +16 -2
- metadata +12 -14
- data/bin/cluster +0 -218
- data/examples/why_wiki/wiki.yml +0 -6
- data/examples/wiki.yml +0 -1
- data/lib/nitro/ui/select.rb +0 -40
- data/lib/nitro/ui/sitemap.rb +0 -183
- data/test/nitro/ui/tc_sitemap.rb +0 -37
data/lib/nitro/dispatcher.rb
CHANGED
@@ -3,14 +3,16 @@
|
|
3
3
|
# $Id$
|
4
4
|
|
5
5
|
module N
|
6
|
-
|
6
|
+
|
7
7
|
require 'nitro/controller'
|
8
|
+
require 'nitro/routing'
|
8
9
|
require 'nitro/simple'
|
9
10
|
|
10
11
|
# The Dispatcher manages a set of controllers.
|
11
12
|
|
12
13
|
class Dispatcher
|
13
|
-
|
14
|
+
include Router
|
15
|
+
|
14
16
|
# The root directory.
|
15
17
|
|
16
18
|
attr_accessor :root
|
@@ -34,15 +36,17 @@ class Dispatcher
|
|
34
36
|
# [+apis+]
|
35
37
|
# A hash of apis supported by the Dispatcher.
|
36
38
|
|
37
|
-
def initialize(controllers = nil, apis = nil)
|
39
|
+
def initialize(controllers = nil, apis = nil, routes = nil)
|
38
40
|
@root = 'root'
|
39
41
|
|
40
42
|
if controllers and controllers.is_a?(Class) and controllers.ancestors.include?(Controller)
|
41
|
-
|
43
|
+
controllers = { :root => controllers }
|
42
44
|
else
|
43
|
-
|
45
|
+
controllers ||= { :root => SimpleController }
|
44
46
|
end
|
45
47
|
|
48
|
+
mount(controllers)
|
49
|
+
|
46
50
|
@apis = apis || {}
|
47
51
|
end
|
48
52
|
|
@@ -62,9 +66,11 @@ class Dispatcher
|
|
62
66
|
# 'users' => UsersController # mounts /users
|
63
67
|
# }
|
64
68
|
|
65
|
-
def
|
69
|
+
def add_controller(controllers)
|
66
70
|
(@controllers ||= {}).update(controllers)
|
71
|
+
update_routes
|
67
72
|
end
|
73
|
+
alias_method :mount, :add_controller
|
68
74
|
|
69
75
|
# Add a new api to the dispatcher
|
70
76
|
#
|
@@ -81,6 +87,21 @@ class Dispatcher
|
|
81
87
|
(@apis ||= {})[api] = data
|
82
88
|
end
|
83
89
|
|
90
|
+
# Update the routes. Typically called after a new
|
91
|
+
# Controller is mounted.
|
92
|
+
|
93
|
+
def update_routes
|
94
|
+
@routes = []
|
95
|
+
@controllers.each do |base, c|
|
96
|
+
base = (base == :root ? '' : "/#{base}")
|
97
|
+
c.action_metadata.each do |action, meta|
|
98
|
+
if route = meta[:route]
|
99
|
+
@routes << [route, "#{base}/#{action}", *meta.params.keys]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
84
105
|
# Processes the path and dispatches to the corresponding
|
85
106
|
# controller/action pair.
|
86
107
|
# The base returned contains a trailing '/'.
|
@@ -94,7 +115,10 @@ class Dispatcher
|
|
94
115
|
def dispatch(path, context = nil)
|
95
116
|
api = :xhtml
|
96
117
|
|
118
|
+
path = route(path, context)
|
119
|
+
|
97
120
|
if @apis
|
121
|
+
# OPTIMIZE: check only if lookup fails.
|
98
122
|
@apis.each { |k, v| api = k if path.slice!(/#{k}\//) }
|
99
123
|
end
|
100
124
|
|
data/lib/nitro/markup.rb
CHANGED
@@ -52,8 +52,6 @@ module PropertyUtils
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
# = Markup
|
56
|
-
#
|
57
55
|
# Generalised Markup transformations.
|
58
56
|
#
|
59
57
|
# The expand methods evaluate (expand) the markup
|
@@ -76,6 +74,8 @@ module Markup
|
|
76
74
|
return unless str
|
77
75
|
str.gsub!(/"/, '"')
|
78
76
|
str.gsub!(/'/, ''')
|
77
|
+
str.gsub!(/</, '<')
|
78
|
+
str.gsub!(/>/, '>')
|
79
79
|
str.gsub!(/\r\n/, ' <br />')
|
80
80
|
return str
|
81
81
|
end
|
@@ -84,6 +84,8 @@ module Markup
|
|
84
84
|
return unless str
|
85
85
|
str.gsub!(/"/, '"')
|
86
86
|
str.gsub!(/'/, "'")
|
87
|
+
str.gsub!(/</, '<')
|
88
|
+
str.gsub!(/>/, '>')
|
87
89
|
# gmosx: SOS! double quotes ARE needed for \r\n!!
|
88
90
|
str.gsub!(/\s<br \/>/, "\r\n")
|
89
91
|
return str
|
data/lib/nitro/render.rb
CHANGED
@@ -4,8 +4,6 @@
|
|
4
4
|
|
5
5
|
require 'sync'
|
6
6
|
|
7
|
-
require 'nitro'
|
8
|
-
|
9
7
|
require 'glue/attribute'
|
10
8
|
require 'glue/misc'
|
11
9
|
require 'glue/object'
|
@@ -118,10 +116,14 @@ module Rendering
|
|
118
116
|
if klass.action_methods.include?(action)
|
119
117
|
valid = true
|
120
118
|
|
121
|
-
|
119
|
+
if meta = klass.action_metadata[action.intern]
|
120
|
+
params = meta.params.keys
|
121
|
+
params = params.collect { |p| "@#{p} = @context['#{p}']" }
|
122
|
+
code << "#{params.join(';')}"
|
123
|
+
end
|
122
124
|
|
123
125
|
code << %{
|
124
|
-
#{action}
|
126
|
+
#{action}
|
125
127
|
}
|
126
128
|
end
|
127
129
|
|
@@ -166,7 +168,9 @@ module Rendering
|
|
166
168
|
end
|
167
169
|
}
|
168
170
|
end
|
169
|
-
|
171
|
+
|
172
|
+
# puts '---', code, '---'
|
173
|
+
|
170
174
|
klass.class_eval(code)
|
171
175
|
end
|
172
176
|
|
@@ -235,9 +239,8 @@ module Render
|
|
235
239
|
# For example called by redirects.
|
236
240
|
|
237
241
|
rescue Exception, StandardError => e
|
238
|
-
log_error
|
239
|
-
|
240
|
-
|
242
|
+
log_error(e, path)
|
243
|
+
|
241
244
|
# More fault tolerant, only flags the erroneous box with
|
242
245
|
# error not the full page.
|
243
246
|
|
@@ -264,14 +267,15 @@ private
|
|
264
267
|
|
265
268
|
# Log a rendering error.
|
266
269
|
|
267
|
-
def log_error(
|
270
|
+
def log_error(error, path)
|
268
271
|
@rendering_errors ||= []
|
269
|
-
@rendering_errors <<
|
272
|
+
@rendering_errors << [error, path]
|
270
273
|
|
271
274
|
# gmosx: Hmm perhaps this should not be logged
|
272
275
|
# to avoid DOS attacks.
|
273
276
|
|
274
|
-
Logger.error
|
277
|
+
Logger.error "Error while handling '#{path}'."
|
278
|
+
Logger.error pp_exception(error)
|
275
279
|
end
|
276
280
|
|
277
281
|
# Convenience method to lookup the session.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# * George Moschovitis <gm@navel.gr>
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
+
# $Id: routing.rb 271 2005-03-07 17:56:45Z gmosx $
|
4
|
+
|
5
|
+
module N
|
6
|
+
|
7
|
+
# Router mixin.
|
8
|
+
|
9
|
+
module Router
|
10
|
+
|
11
|
+
# The route table maps 'nice URLs' to real URLs that
|
12
|
+
# can be handled by the Dispatcher.
|
13
|
+
|
14
|
+
attr_accessor :routes
|
15
|
+
|
16
|
+
# Apply routing rules to the path.
|
17
|
+
|
18
|
+
def route(path, context)
|
19
|
+
for rule, real_path, *params in @routes
|
20
|
+
if md = path.match(rule)
|
21
|
+
params.each_with_index do |p, idx|
|
22
|
+
context[p] = md.captures[idx]
|
23
|
+
end
|
24
|
+
return real_path
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return path
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/nitro/runner.rb
CHANGED
@@ -44,19 +44,28 @@ class Runner
|
|
44
44
|
#
|
45
45
|
# The default mode is :debug
|
46
46
|
|
47
|
-
|
47
|
+
attr :mode
|
48
48
|
|
49
49
|
# :start, :stop, :restart
|
50
50
|
|
51
|
-
|
51
|
+
attr :action
|
52
52
|
|
53
53
|
# The server used to run this web application.
|
54
54
|
# :webrick, :nitro, :lhttp, :apache, :mod_apache
|
55
55
|
#
|
56
56
|
# At the moment only :webrick and :lhttp are available.
|
57
57
|
|
58
|
-
|
58
|
+
attr :server
|
59
59
|
|
60
|
+
# Run as daemon.
|
61
|
+
|
62
|
+
attr :daemon
|
63
|
+
|
64
|
+
# Spidering mode. Acceptable values are :crawl, :render
|
65
|
+
# and false.
|
66
|
+
|
67
|
+
attr :spider
|
68
|
+
|
60
69
|
# Parse the command line arguments and the environment
|
61
70
|
# parameters to setup the application.
|
62
71
|
|
@@ -66,6 +75,7 @@ class Runner
|
|
66
75
|
@action = :start
|
67
76
|
@server = :webrick
|
68
77
|
@daemon = false
|
78
|
+
@spider = false
|
69
79
|
|
70
80
|
parser = OptionParser.new do |opts|
|
71
81
|
|
@@ -127,6 +137,16 @@ class Runner
|
|
127
137
|
exit
|
128
138
|
end
|
129
139
|
|
140
|
+
opts.on('--crawl', 'Crawl the application.') do
|
141
|
+
@server = :webrick
|
142
|
+
@spider = :crawl
|
143
|
+
end
|
144
|
+
|
145
|
+
opts.on('--render', 'Crawl the application and render all pages as static html files.') do
|
146
|
+
@server = :webrick
|
147
|
+
@spider = :render
|
148
|
+
end
|
149
|
+
|
130
150
|
opts.on_tail('-v', '--version', 'Show version.') do
|
131
151
|
puts "Nitro #{Nitro::Version}"
|
132
152
|
exit
|
@@ -202,9 +222,24 @@ class Runner
|
|
202
222
|
end
|
203
223
|
|
204
224
|
def invoke_server(conf)
|
225
|
+
spider_thread = nil
|
226
|
+
|
205
227
|
case @action
|
206
228
|
when :start
|
207
229
|
|
230
|
+
case @spider
|
231
|
+
when :render
|
232
|
+
spider_thread = Thread.new do
|
233
|
+
sleep(6)
|
234
|
+
`wget -k -m -p #{conf.host}:#{conf.port} -directory-prefix=rendered`
|
235
|
+
end
|
236
|
+
when :crawl
|
237
|
+
spider_thread = Thread.new do
|
238
|
+
sleep(6)
|
239
|
+
`wget -m --spider #{conf.host}:#{conf.port}`
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
208
243
|
puts "\n==> Application listening at #{conf.host}:#{conf.port}.\n\n"
|
209
244
|
|
210
245
|
case @server
|
data/lib/nitro/scaffold.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: scaffold.rb
|
3
|
+
# $Id: scaffold.rb 270 2005-03-07 17:52:16Z gmosx $
|
4
4
|
|
5
5
|
require 'glue/inflector'
|
6
6
|
|
@@ -26,14 +26,15 @@ module Scaffolding
|
|
26
26
|
oid = options[:oid] || 'oid'
|
27
27
|
name = options[:name] || N::Inflector.name(klass.name)
|
28
28
|
list_name = options[:list_name] || N::Inflector.plural_name(name)
|
29
|
-
suffix = "_#{name}"
|
29
|
+
options[:nosuffix] ? suffix = nil : suffix = "_#{name}"
|
30
30
|
|
31
31
|
# Add methods to the scaffolded class.
|
32
32
|
|
33
33
|
klass.module_eval <<-"end_eval", __FILE__, __LINE__
|
34
34
|
|
35
35
|
def view_uri
|
36
|
-
"view#{suffix}?oid=\#\{@oid\}"
|
36
|
+
# "view#{suffix}?oid=\#\{@oid\}"
|
37
|
+
"view#{suffix}/\#\{@oid\}"
|
37
38
|
end
|
38
39
|
|
39
40
|
end_eval
|
@@ -59,8 +60,10 @@ module Scaffolding
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def view#{suffix}
|
62
|
-
@#{name} = #{klass}[@context['#{oid}']]
|
63
|
+
# @#{name} = #{klass}[@context['#{oid}']]
|
64
|
+
@#{name} = #{klass}[@#{oid}]
|
63
65
|
end
|
66
|
+
action :view#{suffix}, :route => \%r\{view#{suffix}/(.*)\}, 'oid' => 1
|
64
67
|
|
65
68
|
def save#{suffix}
|
66
69
|
end
|
data/lib/nitro/shaders.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#--
|
2
1
|
# George Moschovitis <gm@navel.gr>
|
3
2
|
# (c) 2004-2005 Navel, all rights reserved.
|
4
3
|
# $Id: shaders.rb 202 2005-01-17 10:44:13Z gmosx $
|
5
|
-
|
4
|
+
|
5
|
+
require 'nitro/template'
|
6
6
|
|
7
7
|
module N
|
8
8
|
|
@@ -56,6 +56,7 @@ end
|
|
56
56
|
# evaluated.
|
57
57
|
|
58
58
|
class RubyShader < Shader
|
59
|
+
include TemplateMixin
|
59
60
|
|
60
61
|
# Convert the xhtml script to actual Ruby code, ready to be
|
61
62
|
# evaluated.
|
@@ -65,10 +66,16 @@ class RubyShader < Shader
|
|
65
66
|
# perhaps xl:href should be used to be XLink compatible?
|
66
67
|
#++
|
67
68
|
|
69
|
+
def process(hash, text)
|
70
|
+
text = compile_template(text)
|
71
|
+
process_next(hash, text)
|
72
|
+
end
|
73
|
+
|
74
|
+
=begin
|
68
75
|
def process(hash, text)
|
69
76
|
# strip the xml header! (interracts with the following gsub!)
|
70
77
|
text.gsub!(/<\?xml.*\?>/, "")
|
71
|
-
|
78
|
+
|
72
79
|
# Statically include sub script files.
|
73
80
|
# The target file is included at compile time.
|
74
81
|
#
|
@@ -134,6 +141,7 @@ class RubyShader < Shader
|
|
134
141
|
|
135
142
|
process_next(hash, text)
|
136
143
|
end
|
144
|
+
=end
|
137
145
|
|
138
146
|
# Loads and statically includes a file.
|
139
147
|
|
@@ -223,4 +231,3 @@ class CompressShader < Shader
|
|
223
231
|
end
|
224
232
|
|
225
233
|
end
|
226
|
-
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# * George Moschovitis <gm@navel.gr>
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
+
# $Id: template.rb 271 2005-03-07 17:56:45Z gmosx $
|
4
|
+
|
5
|
+
module N
|
6
|
+
|
7
|
+
# A template is a text file with embeded Ruby code. The template
|
8
|
+
# processor converts the original text file to ruby code and
|
9
|
+
# then evaluates this code to produce the result of the
|
10
|
+
# template transformation.
|
11
|
+
|
12
|
+
module TemplateMixin
|
13
|
+
|
14
|
+
# Convert a template to actual Ruby code, ready to be
|
15
|
+
# evaluated.
|
16
|
+
#
|
17
|
+
# [+template+]
|
18
|
+
# The template as a String.
|
19
|
+
#
|
20
|
+
# [+buffer+]
|
21
|
+
# The variable to act as a buffer where the ruby code
|
22
|
+
# for this template will be generated. Passed as a|
|
23
|
+
# String.
|
24
|
+
#
|
25
|
+
# [+base_dir+]
|
26
|
+
# The base directory where the templates reside.
|
27
|
+
|
28
|
+
def compile_template(template, buffer = '@out', base_dir = Dir.pwd)
|
29
|
+
text = template.dup
|
30
|
+
|
31
|
+
# Strip the xml header! (interracts with the following gsub!)
|
32
|
+
text.gsub!(/<\?xml.*\?>/, "")
|
33
|
+
|
34
|
+
# Statically include sub-template files.
|
35
|
+
# The target file is included at compile time.
|
36
|
+
#
|
37
|
+
# gmosx: must be xformed before the <?r pi.
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
# <?include href="root/myfile.sx" ?>
|
41
|
+
|
42
|
+
text.gsub!(/<\?include href="(.*?)"(.*)\?>/) do |match|
|
43
|
+
text = File.read("#{base_dir}/#$1")
|
44
|
+
text.gsub!(/<\?xml.*\?>/, '')
|
45
|
+
text.gsub!(/<\/?root(.*?)>/m, ' ');
|
46
|
+
text
|
47
|
+
end
|
48
|
+
|
49
|
+
# Transform include instructions <include href="xxx" />
|
50
|
+
# must be transformed before the processinc instructions.
|
51
|
+
# Useful to include fragments cached on disk
|
52
|
+
#
|
53
|
+
# gmosx, FIXME: NOT TESTED! test and add caching.
|
54
|
+
# add load_statically_included fixes.
|
55
|
+
|
56
|
+
text.gsub!(/<include href="(.*?)"(.*)(.?)\/>/) do |match|
|
57
|
+
"<?r File.read( '\#\{@dispatcher.root\}/#$1' ?>"
|
58
|
+
end
|
59
|
+
|
60
|
+
# xform render/inject instructions <render href="xxx" />
|
61
|
+
# must be transformed before the processinc instructions.
|
62
|
+
|
63
|
+
text.gsub!(/<inject href="(.*?)"(.*)(.?)\/>/) do |match|
|
64
|
+
"<?r render '/#$1' ?>"
|
65
|
+
end
|
66
|
+
|
67
|
+
text.gsub!(/<render href="(.*?)"(.*)(.?)\/>/) do |match|
|
68
|
+
"<?r render '/#$1' ?>"
|
69
|
+
end
|
70
|
+
|
71
|
+
# Remove <root> elements. typically removed by xslt but lets
|
72
|
+
# play it safe. The <root> element is typically added to
|
73
|
+
# template files to make them XHTML valid.
|
74
|
+
|
75
|
+
text.gsub!(/<(\/)?root>/, '')
|
76
|
+
|
77
|
+
# Transform the processing instructions, use <?r as
|
78
|
+
# a marker.
|
79
|
+
|
80
|
+
text.gsub!(/\?>/, "\n#{buffer} << %^")
|
81
|
+
text.gsub!(/<\?r(\s?)/, "^\n")
|
82
|
+
|
83
|
+
# Transform alternative code tags.
|
84
|
+
# (very useful in xsl stylesheets)
|
85
|
+
|
86
|
+
text.gsub!(/<\/ruby>/, "\n#{buffer} << %^")
|
87
|
+
text.gsub!(/<ruby>/, "^\n")
|
88
|
+
|
89
|
+
# Alterative versions of interpolation.
|
90
|
+
# (very useful in xsl stylesheets)
|
91
|
+
|
92
|
+
text.gsub!(/\#\((.*?)\)/, '#{\1}')
|
93
|
+
|
94
|
+
# Compile time ruby code. This code is evaluated when
|
95
|
+
# compiling the template and the result injected directly
|
96
|
+
# into the result. Usefull for example to prevaluate
|
97
|
+
# localization.
|
98
|
+
|
99
|
+
text.gsub!(/\#\[(.*?)\]/) do |match|
|
100
|
+
eval($1)
|
101
|
+
end
|
102
|
+
|
103
|
+
text = "#{buffer} << %^" + text + "^"
|
104
|
+
|
105
|
+
return text
|
106
|
+
end
|
107
|
+
|
108
|
+
# Render the template.
|
109
|
+
#
|
110
|
+
# [+ruby+]
|
111
|
+
# A String containing the compiled template
|
112
|
+
# code.
|
113
|
+
#
|
114
|
+
# [+binding+]
|
115
|
+
# The evaluation binding for the rendering.
|
116
|
+
|
117
|
+
def render_template(ruby, the_binding = nil)
|
118
|
+
eval(ruby, the_binding)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Compile and render the template.
|
122
|
+
|
123
|
+
def process_template(template, buffer = '@out', the_binding = nil)
|
124
|
+
render_template(compile_template(template, buffer), the_binding)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
# A template class implementing the Template mixin.
|
130
|
+
|
131
|
+
class Template
|
132
|
+
class << self
|
133
|
+
include TemplateMixin
|
134
|
+
alias_method :compile, :compile_template
|
135
|
+
alias_method :render, :render_template
|
136
|
+
alias_method :process, :process_template
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|