nitro 0.19.0 → 0.20.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 +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
|