nitro 0.20.0 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/request.rb
CHANGED
@@ -1,163 +1,163 @@
|
|
1
1
|
module Nitro
|
2
|
-
|
2
|
+
|
3
3
|
# Encapsulates a request. This is an abstract request
|
4
4
|
# typically extended by sub-classes. This module
|
5
5
|
# is included in Context
|
6
6
|
|
7
7
|
module Request
|
8
8
|
|
9
|
-
|
9
|
+
# The request input stream.
|
10
10
|
|
11
|
-
|
11
|
+
attr_accessor :in
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
# The request headers collection. Also called
|
14
|
+
# the request environment (env).
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
attr_accessor :headers
|
17
|
+
alias_method :env, :headers
|
18
|
+
alias_method :env=, :headers=
|
19
|
+
# for compatibility with cgi.rb
|
20
|
+
alias_method :env_table, :headers
|
21
21
|
|
22
|
-
|
22
|
+
# The parsed query parameters collection.
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
attr_accessor :params
|
25
|
+
alias_method :query, :params
|
26
26
|
|
27
|
-
|
27
|
+
# The request cookies.
|
28
28
|
|
29
|
-
|
29
|
+
attr_accessor :cookies
|
30
30
|
|
31
|
-
|
31
|
+
# The request protocol.
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def protocol
|
34
|
+
443 == port ? 'https://' : 'http://'
|
35
|
+
end
|
36
36
|
|
37
|
-
|
37
|
+
# Is this an ssl request?
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
39
|
+
def ssl?
|
40
|
+
443 == port
|
41
|
+
end
|
42
|
+
|
43
|
+
# The request uri.
|
44
|
+
|
45
|
+
def uri
|
46
|
+
@headers['REQUEST_URI']
|
47
|
+
end
|
48
|
+
|
49
|
+
# The path is the uri without the query string.
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
def path
|
52
|
+
path = uri ? uri.split('?').first : ''
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
55
|
+
def path_info
|
56
|
+
@headers['PATH_INFO']
|
57
|
+
end
|
58
|
+
|
59
|
+
# The request query string.
|
60
|
+
|
61
|
+
def query_string
|
62
|
+
@headers['QUERY_STRING']
|
63
|
+
end
|
64
|
+
|
65
|
+
# The request method.
|
66
|
+
|
67
|
+
def method
|
68
|
+
@headers['REQUEST_METHOD'].downcase.intern
|
69
|
+
end
|
70
|
+
|
71
|
+
# Is this a post method?
|
72
|
+
|
73
|
+
def post?
|
74
|
+
method == :post
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return the referer. For the initial page in the
|
78
|
+
# clickstream there is no referer, set "/" by default.
|
79
|
+
|
80
|
+
def referer
|
81
|
+
return @headers['HTTP_REFERER'] || '/'
|
82
|
+
end
|
83
|
+
|
84
|
+
# The content_length
|
85
|
+
|
86
|
+
def content_length
|
87
|
+
return @headers['CONTENT_LENGTH'].to_i
|
88
|
+
end
|
89
|
+
|
90
|
+
# The remote IP address. REMOTE_ADDR is the standard
|
91
|
+
# but will fail if the user is behind a proxy.
|
92
|
+
# HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by
|
93
|
+
# proxies so check for these before falling back to
|
94
|
+
# REMOTE_ADDR. HTTP_X_FORWARDED_FOR may be a comma-delimited
|
95
|
+
# list in the case of multiple chained proxies; the first
|
96
|
+
# is the originating IP.
|
97
|
+
|
98
|
+
def remote_ip
|
99
|
+
return @headers['HTTP_CLIENT_IP'] if @headers.include?('HTTP_CLIENT_IP')
|
100
|
+
|
101
|
+
if @headers.include?('HTTP_X_FORWARDED_FOR') then
|
102
|
+
remote_ips = @headers['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip|
|
103
|
+
ip =~ /^unknown$|^(10|172\.16|192\.168)\./i
|
104
|
+
end
|
105
|
+
|
106
|
+
return remote_ips.first.strip unless remote_ips.empty?
|
107
|
+
end
|
108
|
+
|
109
|
+
return @headers['REMOTE_ADDR']
|
110
|
+
end
|
111
|
+
|
112
|
+
# The server port.
|
113
|
+
|
114
|
+
def port
|
115
|
+
@headers['SERVER_PORT'].to_i
|
116
|
+
end
|
117
|
+
|
118
|
+
# The server host name.
|
119
|
+
# Also handles proxy forwarding.
|
120
|
+
|
121
|
+
def host
|
122
|
+
@headers['HTTP_X_FORWARDED_HOST'] || @headers['HTTP_HOST']
|
123
|
+
end
|
124
|
+
|
125
|
+
def host_url
|
126
|
+
"http://#{host}"
|
127
|
+
end
|
128
|
+
|
129
|
+
# The raw data of the request.
|
130
|
+
# Useful to implement Webservices.
|
131
|
+
#--
|
132
|
+
# FIXME: better name and implementation.
|
133
|
+
#++
|
134
|
+
|
135
|
+
def raw_body
|
136
|
+
unless @raw_body
|
137
|
+
@in.rewind
|
138
|
+
@raw_body = @in.read(content_length)
|
139
|
+
end
|
140
|
+
|
141
|
+
@raw_body
|
142
|
+
end
|
143
|
+
|
144
|
+
# Lookup a query parameter.
|
145
|
+
|
146
|
+
def [](param)
|
147
|
+
@params[param]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Set a query parameter.
|
151
|
+
|
152
|
+
def []=(param, value)
|
153
|
+
@params[param] = value
|
154
|
+
end
|
155
|
+
|
156
|
+
# Fetch a parameter with default value.
|
157
|
+
|
158
|
+
def fetch(param, default = nil)
|
159
|
+
@params.fetch(param, default)
|
160
|
+
end
|
161
161
|
end
|
162
162
|
|
163
163
|
end
|
data/lib/nitro/response.rb
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
module Nitro
|
2
|
-
|
2
|
+
|
3
3
|
# HTTP Response. This module is included in Context.
|
4
4
|
|
5
5
|
module Response
|
6
6
|
|
7
|
-
|
7
|
+
# The Response status.
|
8
8
|
|
9
|
-
|
9
|
+
attr_accessor :status
|
10
10
|
|
11
|
-
|
11
|
+
# The Response headers.
|
12
12
|
|
13
|
-
|
13
|
+
attr_accessor :response_headers
|
14
14
|
|
15
|
-
|
15
|
+
# The Response cookies.
|
16
16
|
|
17
|
-
|
17
|
+
attr_accessor :response_cookies
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def content_type=(ctype)
|
20
|
+
@response_headers['Content-Type'] = ctype
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
23
|
+
# Add a cookie to the response. Better use this
|
24
|
+
# method to avoid precreating the cookies array
|
25
|
+
# for every request.
|
26
|
+
#
|
27
|
+
# === Examples
|
28
|
+
#
|
29
|
+
# add_cookie('nsid', 'gmosx')
|
30
|
+
# add_cookie(Cookie.new('nsid', 'gmosx')
|
31
|
+
|
32
|
+
def add_cookie(cookie, value = nil)
|
33
|
+
if value
|
34
|
+
(@response_cookies ||= []) << Cookie.new(cookie, value)
|
35
|
+
else
|
36
|
+
(@response_cookies ||= []) << cookie
|
37
|
+
end
|
38
|
+
end
|
39
|
+
alias_method :send_cookie, :add_cookie
|
40
40
|
|
41
41
|
end
|
42
42
|
|
data/lib/nitro/routing.rb
CHANGED
@@ -3,28 +3,28 @@ module Nitro
|
|
3
3
|
# Router mixin. Typically used to generate 'nice' urls.
|
4
4
|
# Nice urls are considered (?) more Search Engine
|
5
5
|
# friendly.
|
6
|
-
|
6
|
+
|
7
7
|
module Router
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
8
|
+
|
9
|
+
# The route table maps 'nice URLs' to real URLs that
|
10
|
+
# can be handled by the Dispatcher.
|
11
|
+
|
12
|
+
attr_accessor :routes
|
13
|
+
|
14
|
+
# Apply routing rules to the path.
|
15
|
+
|
16
|
+
def route(path, context)
|
17
|
+
for rule, real_path, *params in @routes
|
18
|
+
if md = path.match(rule)
|
19
|
+
params.each_with_index do |p, idx|
|
20
|
+
context[p] = md.captures[idx]
|
21
|
+
end
|
22
|
+
return real_path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return path
|
27
|
+
end
|
28
28
|
|
29
29
|
end
|
30
30
|
|
data/lib/nitro/scaffold.rb
CHANGED
@@ -2,9 +2,13 @@ require 'facet/string/singular'
|
|
2
2
|
require 'facet/string/demodulize'
|
3
3
|
require 'facet/string/underscore'
|
4
4
|
|
5
|
+
require 'nitro/compiler'
|
6
|
+
|
5
7
|
module Nitro
|
6
8
|
|
7
9
|
# The scaffolder adds default actions to a Controller.
|
10
|
+
#
|
11
|
+
# WARNING: This code is slightly outdated.
|
8
12
|
#--
|
9
13
|
# FIXME: handle controller base in generated routes.
|
10
14
|
# FIXME: better handle templates (check if action exists).
|
@@ -12,124 +16,126 @@ module Nitro
|
|
12
16
|
|
13
17
|
module Scaffolding
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
19
|
+
def self.append_features(base) # :nodoc:
|
20
|
+
super
|
21
|
+
base.extend(ClassMethods)
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
|
26
|
+
# Enchant the caller with a number of default methods.
|
27
|
+
# Override the automatically generated methods as needed.
|
28
|
+
|
29
|
+
def scaffold(klass, options = {})
|
30
|
+
compiler = Compiler.new
|
31
|
+
|
32
|
+
oid = options[:oid] || 'oid'
|
33
|
+
name = options[:name] || klass.to_s.demodulize.underscore.downcase
|
34
|
+
list_name = options[:list_name] || name.plural
|
35
|
+
options[:nosuffix] ? suffix = nil : suffix = "_#{name}"
|
36
|
+
|
37
|
+
# Add methods to the scaffolded class.
|
38
|
+
|
39
|
+
klass.module_eval %{
|
40
|
+
def to_href
|
41
|
+
"view#{suffix}?oid=\#\{@oid\}"
|
42
|
+
# "view#{suffix}/\#\{@oid\}"
|
43
|
+
end
|
44
|
+
}
|
45
|
+
|
46
|
+
# Add methods to the service.
|
47
|
+
|
48
|
+
code = ''
|
49
|
+
|
50
|
+
if options[:index]
|
51
|
+
code << %{
|
52
|
+
def index
|
53
|
+
list#{suffix}
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
code << %{
|
59
|
+
def new#{suffix}
|
60
|
+
@#{name} = #{klass}.new
|
61
|
+
render '/form#{suffix}'
|
62
|
+
end
|
63
|
+
|
64
|
+
def edit#{suffix}
|
65
|
+
@#{name} = #{klass}[request['oid']]
|
66
|
+
render '/form#{suffix}'
|
67
|
+
end
|
68
|
+
}
|
69
|
+
|
70
|
+
unless compiler.template_for_action("form#{suffix}", self.template_root)
|
71
|
+
code << %{
|
72
|
+
def form#{suffix}
|
73
|
+
o << %|
|
74
|
+
<html>
|
75
|
+
<form action="save#{suffix}" method="post">
|
76
|
+
|
|
77
|
+
if @#{name}.oid
|
78
|
+
o << %|
|
79
|
+
<input type="hidden" name="oid" value="\#\{@#{name}\}" />
|
80
|
+
|
|
81
|
+
end
|
82
|
+
o.build_form(@#{name})
|
83
|
+
o << %|
|
84
|
+
<input type="submit" value="Save" />
|
85
|
+
</form>
|
86
|
+
</html>
|
87
|
+
|
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
code << %{
|
93
|
+
# TODO: add pager support here!
|
94
|
+
|
95
|
+
def list#{suffix}
|
96
|
+
@#{list_name} = #{klass}.all('ORDER BY oid')
|
97
|
+
}
|
98
|
+
unless compiler.template_for_action("list#{suffix}", self.template_root)
|
99
|
+
code << %{
|
100
|
+
o.ul {
|
101
|
+
for item in @#{list_name}
|
102
|
+
o.li(item.to_s)
|
103
|
+
end
|
104
|
+
}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
code << %{
|
108
|
+
end
|
109
|
+
|
110
|
+
def view#{suffix}
|
111
|
+
# @#{name} = #{klass}[@context['#{oid}']]
|
112
|
+
@#{name} = #{klass}[@#{oid}]
|
113
|
+
end
|
114
|
+
action :view#{suffix}, :route => \%r\{#{@base}/view#{suffix}/(.*)\}, 'oid' => 1
|
115
|
+
|
116
|
+
def save#{suffix}
|
117
|
+
if oid = request['oid']
|
118
|
+
@#{name} = request.fill(#{klass}[oid])
|
119
|
+
else
|
120
|
+
@#{name} = request.fill(#{klass}.new)
|
121
|
+
end
|
122
|
+
|
123
|
+
@#{name}.save
|
124
|
+
|
125
|
+
redirect 'list#{suffix}'
|
126
|
+
end
|
127
|
+
|
128
|
+
def del#{suffix}
|
129
|
+
#{klass}.delete(@context['#{oid}'])
|
130
|
+
redirect_referer
|
131
|
+
end
|
132
|
+
alias_method :delete#{suffix}, :del#{suffix}
|
133
|
+
}
|
134
|
+
|
135
|
+
class_eval(code)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
133
139
|
|
134
140
|
end
|
135
141
|
|