nitro 0.19.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +187 -0
- data/INSTALL +5 -0
- data/README +11 -5
- data/doc/AUTHORS +11 -1
- data/doc/RELEASES +217 -0
- data/doc/tutorial.txt +1 -2
- data/lib/nitro.rb +9 -6
- data/lib/nitro/adapter/webrick.rb +13 -2
- data/lib/nitro/builder/form.rb +11 -9
- data/lib/nitro/builder/rss.rb +2 -2
- data/lib/nitro/builder/xhtml.rb +15 -0
- data/lib/nitro/caching.rb +15 -10
- data/lib/nitro/conf.rb +0 -5
- data/lib/nitro/controller.rb +118 -81
- data/lib/nitro/cookie.rb +6 -6
- data/lib/nitro/dispatcher.rb +62 -18
- data/lib/nitro/element.rb +4 -1
- data/lib/nitro/element/java_script.rb +15 -0
- data/lib/nitro/localization.rb +3 -4
- data/lib/nitro/markup.rb +4 -4
- data/lib/nitro/mixin/debug.rb +30 -0
- data/lib/nitro/mixin/helper.rb +14 -0
- data/lib/nitro/mixin/javascript.rb +137 -0
- data/lib/nitro/{ui → mixin}/pager.rb +110 -82
- data/lib/nitro/render.rb +20 -8
- data/lib/nitro/request.rb +6 -0
- data/lib/nitro/routing.rb +6 -5
- data/lib/nitro/runner.rb +21 -9
- data/lib/nitro/server.rb +95 -0
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/session.rb +4 -5
- data/lib/nitro/shaders.rb +2 -2
- data/lib/nitro/template.rb +1 -1
- data/lib/nitro/testing/assertions.rb +2 -4
- data/lib/nitro/testing/context.rb +4 -6
- data/proto/public/js/behaviour.js +254 -0
- data/proto/public/js/controls.js +446 -0
- data/proto/public/js/dragdrop.js +537 -0
- data/proto/public/js/effects.js +612 -0
- data/proto/public/js/prototype.js +644 -370
- data/proto/public/settings.xhtml +64 -0
- data/test/nitro/adapter/tc_cgi.rb +2 -2
- data/test/nitro/builder/tc_rss.rb +1 -1
- data/test/nitro/mixin/tc_pager.rb +35 -0
- data/test/nitro/tc_controller.rb +1 -1
- data/test/nitro/tc_cookie.rb +14 -0
- data/test/nitro/tc_dispatcher.rb +11 -6
- data/test/nitro/tc_server.rb +35 -0
- metadata +20 -15
- data/lib/nitro/builder/atom.rb +0 -74
- data/lib/nitro/part.rb +0 -22
- data/lib/nitro/simple.rb +0 -11
- data/lib/nitro/ui/popup.rb +0 -41
- data/lib/nitro/ui/tabs.rb +0 -25
- data/lib/nitro/uri.rb +0 -193
- data/test/nitro/builder/tc_atom.rb +0 -24
- data/test/nitro/tc_uri.rb +0 -97
- data/test/nitro/ui/tc_pager.rb +0 -49
data/doc/tutorial.txt
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
Nitro is an elegant and efficient web application framework.
|
4
4
|
In the spirit of Ruby, Nitro supports multiple programming paradigms
|
5
5
|
and does not force design decisions to the developer. Nitro
|
6
|
-
provides an elegant solution to all problems.
|
7
|
-
Nitro is Ruby Web Development 'off rails'!
|
6
|
+
provides an elegant solution to all problems.
|
8
7
|
|
9
8
|
This tutorial presents a step by step guide for building
|
10
9
|
a simple blog using Nitro.
|
data/lib/nitro.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
# = Nitro
|
2
2
|
#
|
3
3
|
# Nitro is an efficient, yet simple engine for developing
|
4
|
-
# professional Web Applications using
|
5
|
-
# Nitro
|
6
|
-
#
|
4
|
+
# professional Web Applications using Ruby and Javascript.
|
5
|
+
# Nitro provides a robust infrastructure for scalable
|
6
|
+
# applications that can be distributed over a server
|
7
7
|
# cluster. However, Nitro can also power simple web
|
8
|
-
# applications for deployment on intranets or
|
9
|
-
# computers.
|
8
|
+
# applications for deployment on intranets or desktops.
|
10
9
|
#
|
11
10
|
# Nitro integrates the powerful Og Object-Relational mapping
|
12
11
|
# library.
|
@@ -25,7 +24,7 @@ module Nitro
|
|
25
24
|
|
26
25
|
# The version.
|
27
26
|
|
28
|
-
Version = '0.
|
27
|
+
Version = '0.20.0'
|
29
28
|
|
30
29
|
# Library path.
|
31
30
|
|
@@ -33,12 +32,16 @@ module Nitro
|
|
33
32
|
|
34
33
|
end
|
35
34
|
|
35
|
+
#--
|
36
36
|
# gmosx: leave them here.
|
37
|
+
#++
|
37
38
|
|
38
39
|
require 'nitro/context'
|
39
40
|
require 'nitro/controller'
|
40
41
|
require 'nitro/dispatcher'
|
41
42
|
require 'nitro/render'
|
43
|
+
|
44
|
+
require 'nitro/server'
|
42
45
|
require 'nitro/conf'
|
43
46
|
|
44
47
|
require 'nitro/runner'
|
@@ -51,6 +51,15 @@ class Webrick
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
+
# A special handler for Xhtml files.
|
55
|
+
|
56
|
+
class XhtmlFileHandler < WEBrick::HTTPServlet::DefaultFileHandler
|
57
|
+
def do_GET(req, res)
|
58
|
+
res['content-type'] = 'text/html'
|
59
|
+
res.body = '<html><body>Permission denied</body></html>'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
54
63
|
# A Webrick Adapter for Nitro.
|
55
64
|
#--
|
56
65
|
# TODO: optimize the conversion from WEBrick's
|
@@ -64,11 +73,13 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
|
|
64
73
|
|
65
74
|
def initialize(server, conf)
|
66
75
|
@conf = conf
|
76
|
+
@conf.webrick_options ||= {}
|
77
|
+
@conf.webrick_options[:HandlerTable] = { 'xhtml' => XhtmlFileHandler }
|
67
78
|
|
68
79
|
# Handles static resources. Useful when running
|
69
80
|
# a stand-alone webrick server.
|
70
|
-
|
71
|
-
@file_handler = WEBrick::HTTPServlet::FileHandler.new(server, conf.dispatcher.public_root, conf.webrick_options
|
81
|
+
|
82
|
+
@file_handler = WEBrick::HTTPServlet::FileHandler.new(server, conf.dispatcher.public_root, @conf.webrick_options)
|
72
83
|
end
|
73
84
|
|
74
85
|
# Handle a static file. Also handles cached pages.
|
data/lib/nitro/builder/form.rb
CHANGED
@@ -29,14 +29,14 @@ module FormBuilderMixin
|
|
29
29
|
if p.klass.ancestors.include?(Integer) or
|
30
30
|
p.klass.ancestors.include?(Float)
|
31
31
|
str << %{
|
32
|
-
<dt><label for="#{p.
|
32
|
+
<dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
|
33
33
|
<dd>
|
34
|
-
<input type="text" id="#{p.
|
34
|
+
<input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{obj.send(p.symbol)}" />
|
35
35
|
</dd>
|
36
36
|
}
|
37
37
|
elsif p.klass.ancestors.include?(String)
|
38
38
|
str << %{
|
39
|
-
<dt><label for="#{p.
|
39
|
+
<dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
|
40
40
|
<dd>
|
41
41
|
}
|
42
42
|
if p.meta[:markup]
|
@@ -46,11 +46,11 @@ module FormBuilderMixin
|
|
46
46
|
end
|
47
47
|
if :textarea == p.meta[:ui]
|
48
48
|
str << %{
|
49
|
-
<textarea id="#{p.
|
49
|
+
<textarea id="#{p.symbol}" name="#{p.symbol}">#{val}</textarea>
|
50
50
|
}
|
51
51
|
else
|
52
52
|
str << %{
|
53
|
-
<input type="text" id="#{p.
|
53
|
+
<input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{val}" />
|
54
54
|
}
|
55
55
|
end
|
56
56
|
str << %{
|
@@ -58,16 +58,16 @@ module FormBuilderMixin
|
|
58
58
|
}
|
59
59
|
elsif p.klass.ancestors.include?(TrueClass)
|
60
60
|
str << %{
|
61
|
-
<dt><label for="#{p.
|
61
|
+
<dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
|
62
62
|
<dd>
|
63
|
-
<input type="checkbox" id="#{p.
|
63
|
+
<input type="checkbox" id="#{p.symbol}" name="#{p.symbol}" />
|
64
64
|
</dd>
|
65
65
|
}
|
66
66
|
elsif p.klass.ancestors.include?(Time)
|
67
67
|
str << %{
|
68
|
-
<dt><label for="#{p.
|
68
|
+
<dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
|
69
69
|
<dd>
|
70
|
-
<input type="text" id="#{p.
|
70
|
+
<input type="text" id="#{p.symbol}" name="#{p.symbol}" value="#{obj.send(p.symbol)}" />
|
71
71
|
</dd>
|
72
72
|
}
|
73
73
|
=begin
|
@@ -100,3 +100,5 @@ class FormBuilder
|
|
100
100
|
end
|
101
101
|
|
102
102
|
end
|
103
|
+
|
104
|
+
# * George Moschovitis
|
data/lib/nitro/builder/rss.rb
CHANGED
@@ -44,8 +44,8 @@ module RssBuilderMixin
|
|
44
44
|
for obj in objects
|
45
45
|
item = RSS::Rss::Channel::Item.new
|
46
46
|
item.title = obj.title if obj.respond_to?(:title)
|
47
|
-
item.description = Glue::StringUtils.head(obj.body, 256) if obj.respond_to?(:body)
|
48
|
-
item.link = "#{c[:base]}/#{obj.
|
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
49
|
channel.items << item
|
50
50
|
end
|
51
51
|
|
data/lib/nitro/builder/xhtml.rb
CHANGED
@@ -115,3 +115,18 @@ end
|
|
115
115
|
end
|
116
116
|
|
117
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/caching.rb
CHANGED
@@ -9,27 +9,32 @@ require 'nitro/caching/fragments'
|
|
9
9
|
module Nitro
|
10
10
|
|
11
11
|
# Adds support for caching.
|
12
|
+
#--
|
13
|
+
# TODO: add per controller caching_enabled.
|
14
|
+
#++
|
12
15
|
|
13
16
|
module Caching
|
14
17
|
|
15
18
|
# Globaly enable/disable caching.
|
16
19
|
|
17
|
-
|
20
|
+
setting :caching_enabled, :default => true, :doc => 'Globaly enable/disable caching'
|
18
21
|
|
19
22
|
def self.append_features(base) #:nodoc:
|
20
23
|
super
|
21
24
|
base.send :include, Output, Actions, Fragments
|
22
|
-
base.
|
23
|
-
|
25
|
+
base.module_eval do
|
26
|
+
# @caching_enabled = true
|
27
|
+
def self.caching_enabled?
|
28
|
+
Caching.caching_enabled # and @caching_enabled
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def caching_enabled?
|
34
|
+
Caching.caching_enabled # and self.class.get_instance_variable(:caching_enabled)
|
35
|
+
end
|
24
36
|
end
|
25
37
|
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def caching_enabled?
|
30
|
-
Caching.caching_enabled and self.class.caching_enabled
|
31
|
-
end
|
32
|
-
|
33
38
|
end
|
34
39
|
|
35
40
|
end
|
data/lib/nitro/conf.rb
CHANGED
data/lib/nitro/controller.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'glue/aspects'
|
2
|
+
require 'glue/helper'
|
2
3
|
|
3
4
|
require 'nitro'
|
4
5
|
require 'nitro/render'
|
@@ -20,8 +21,10 @@ module Nitro
|
|
20
21
|
# [+required+]
|
21
22
|
# Is this parameter required?
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
unless const_defined? :ActionParam
|
25
|
+
ActionParam = Struct.new(:default, :format, :required)
|
26
|
+
end
|
27
|
+
|
25
28
|
# Encapsulates metadata that describe an action.
|
26
29
|
|
27
30
|
class ActionMeta < Hash
|
@@ -71,105 +74,139 @@ class ActionMeta < Hash
|
|
71
74
|
|
72
75
|
end
|
73
76
|
|
74
|
-
#
|
75
|
-
#
|
76
|
-
|
77
|
-
class Controller
|
78
|
-
include Render
|
79
|
-
include Glue::Aspects
|
80
|
-
include Scaffolding
|
81
|
-
include Caching
|
82
|
-
include Flashing
|
77
|
+
# Include this Mixin to a class to make objects of this class
|
78
|
+
# publishable, ie accessible through a standard web (REST)
|
79
|
+
# interface.
|
83
80
|
|
84
|
-
|
85
|
-
|
81
|
+
module Publishable
|
82
|
+
def self.append_features(base)
|
86
83
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def initialize(context, base = nil)
|
99
|
-
super
|
100
|
-
# self.class.template_root ||= "#{@context.dispatcher.template_root}#{base}"
|
101
|
-
end
|
102
|
-
|
103
|
-
# Use the method_missing hook to compile the actions
|
104
|
-
# for this controller.
|
105
|
-
|
106
|
-
def method_missing(action, *args)
|
107
|
-
if Rendering.compile_action(self.class, action)
|
108
|
-
send(action, *args)
|
109
|
-
else
|
110
|
-
super
|
84
|
+
base.module_eval do
|
85
|
+
include Render
|
86
|
+
include Glue::Aspects
|
87
|
+
include Flashing
|
88
|
+
include Glue::Helpers
|
89
|
+
|
90
|
+
class << self
|
91
|
+
attr_accessor :template_root
|
92
|
+
end
|
93
|
+
|
94
|
+
@template_root = 'public'
|
111
95
|
end
|
112
|
-
end
|
113
96
|
|
114
|
-
|
115
|
-
|
97
|
+
# Define metadata for an action. This is a helper
|
98
|
+
# macro.
|
116
99
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
# this should be moved to the render.
|
122
|
-
#++
|
123
|
-
|
124
|
-
def inherited(child)
|
125
|
-
# child.template_root = template_root
|
126
|
-
child.template_root = 'public'
|
127
|
-
|
128
|
-
# Calculate the name of the file where this controller
|
129
|
-
# is defined. Currently used for reloading.
|
130
|
-
|
131
|
-
child.class_eval %{
|
132
|
-
if caller[2].to_s.split(':').last =~ /[0-9]+/
|
133
|
-
DEF_FILE = caller[2].to_s.strip.gsub( /:[0-9]+$/ , '')
|
100
|
+
base.module_eval do
|
101
|
+
def self.action(name, options)
|
102
|
+
if meta = action_metadata[name]
|
103
|
+
meta.update(options)
|
134
104
|
else
|
135
|
-
|
105
|
+
action_metadata[name] = ActionMeta.new(options)
|
136
106
|
end
|
137
|
-
|
138
|
-
|
139
|
-
__old_inherited(child)
|
107
|
+
end
|
140
108
|
end
|
141
109
|
|
142
|
-
#
|
143
|
-
|
110
|
+
# Aliases an action
|
111
|
+
#--
|
112
|
+
# gmosx, FIXME: better implementation needed.
|
113
|
+
#++
|
144
114
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
115
|
+
base.module_eval do
|
116
|
+
def self.alias_action(new, old)
|
117
|
+
alias_method new, old
|
118
|
+
md = action_metadata[old] || ActionMetadata.new
|
119
|
+
md[:view] = old
|
120
|
+
action_metadata[new] = md
|
150
121
|
end
|
151
122
|
end
|
152
123
|
|
153
124
|
# Return the 'action' methods for this Controller.
|
154
125
|
# Some dangerous methods from ancestors are removed.
|
126
|
+
# All private methods are ignored.
|
155
127
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
128
|
+
base.module_eval do
|
129
|
+
def self.action_methods
|
130
|
+
classes = self.ancestors.reject do |a|
|
131
|
+
[Object, Kernel, Render, Controller, Caching].include?(a)
|
132
|
+
end
|
160
133
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
134
|
+
classes.delete(PP::ObjectMixin) if defined?(PP::ObjectMixin)
|
135
|
+
|
136
|
+
methods = classes.inject([]) do |action_methods, klass|
|
137
|
+
action_methods + klass.public_instance_methods(false)
|
138
|
+
end
|
139
|
+
|
140
|
+
# gmosx: add the default action (leave this?)
|
141
|
+
# methods << 'index'
|
142
|
+
|
143
|
+
return methods
|
165
144
|
end
|
166
|
-
|
167
|
-
# methods.delete('method_missing')
|
168
|
-
|
169
|
-
return methods
|
170
145
|
end
|
146
|
+
|
147
|
+
# A hash containing metadata for the action
|
148
|
+
# methods.
|
149
|
+
|
150
|
+
base.module_eval do
|
151
|
+
def self.action_metadata
|
152
|
+
# FIXME: improve this.
|
153
|
+
@action_metadata ||= {}
|
154
|
+
@action_metadata
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
base.module_eval do
|
159
|
+
def initialize(context, base = nil)
|
160
|
+
super
|
161
|
+
self.class.template_root ||= 'public'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Use the method_missing hook to compile the actions
|
166
|
+
# for this controller.
|
167
|
+
|
168
|
+
base.module_eval do
|
169
|
+
def method_missing(action, *args)
|
170
|
+
if Rendering.compile_action(self.class, action)
|
171
|
+
send(action, *args)
|
172
|
+
else
|
173
|
+
super
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# The Controller part in the MVC paradigm. The controller's
|
182
|
+
# published methods are called actrions. The controller class
|
183
|
+
# contains the Publishable mixin and additional helper mixins.
|
184
|
+
|
185
|
+
class Controller
|
186
|
+
include Publishable
|
187
|
+
include Scaffolding
|
188
|
+
include Caching
|
189
|
+
|
190
|
+
# The default action.
|
191
|
+
=begin
|
192
|
+
def index
|
193
|
+
print %{
|
194
|
+
This is the placeholder action is provided as a default for #{self.class.name}.<br />
|
195
|
+
You probably want to <b>implement your custom action</b> here.
|
196
|
+
}
|
197
|
+
end
|
198
|
+
=end
|
199
|
+
end
|
200
|
+
|
201
|
+
# A simple controller, only handles templates.
|
202
|
+
# Useful to implement php/asp/jsp style applications.
|
203
|
+
# The Dispatcher uses this as the default Controller.
|
204
|
+
#--
|
205
|
+
# gmosx: At the moment used to have a separate
|
206
|
+
# template_root.
|
207
|
+
#++
|
171
208
|
|
172
|
-
|
209
|
+
class SimpleController < Controller
|
173
210
|
end
|
174
211
|
|
175
212
|
end
|