nitro 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG +187 -0
  2. data/INSTALL +5 -0
  3. data/README +11 -5
  4. data/doc/AUTHORS +11 -1
  5. data/doc/RELEASES +217 -0
  6. data/doc/tutorial.txt +1 -2
  7. data/lib/nitro.rb +9 -6
  8. data/lib/nitro/adapter/webrick.rb +13 -2
  9. data/lib/nitro/builder/form.rb +11 -9
  10. data/lib/nitro/builder/rss.rb +2 -2
  11. data/lib/nitro/builder/xhtml.rb +15 -0
  12. data/lib/nitro/caching.rb +15 -10
  13. data/lib/nitro/conf.rb +0 -5
  14. data/lib/nitro/controller.rb +118 -81
  15. data/lib/nitro/cookie.rb +6 -6
  16. data/lib/nitro/dispatcher.rb +62 -18
  17. data/lib/nitro/element.rb +4 -1
  18. data/lib/nitro/element/java_script.rb +15 -0
  19. data/lib/nitro/localization.rb +3 -4
  20. data/lib/nitro/markup.rb +4 -4
  21. data/lib/nitro/mixin/debug.rb +30 -0
  22. data/lib/nitro/mixin/helper.rb +14 -0
  23. data/lib/nitro/mixin/javascript.rb +137 -0
  24. data/lib/nitro/{ui → mixin}/pager.rb +110 -82
  25. data/lib/nitro/render.rb +20 -8
  26. data/lib/nitro/request.rb +6 -0
  27. data/lib/nitro/routing.rb +6 -5
  28. data/lib/nitro/runner.rb +21 -9
  29. data/lib/nitro/server.rb +95 -0
  30. data/lib/nitro/service.rb +0 -1
  31. data/lib/nitro/session.rb +4 -5
  32. data/lib/nitro/shaders.rb +2 -2
  33. data/lib/nitro/template.rb +1 -1
  34. data/lib/nitro/testing/assertions.rb +2 -4
  35. data/lib/nitro/testing/context.rb +4 -6
  36. data/proto/public/js/behaviour.js +254 -0
  37. data/proto/public/js/controls.js +446 -0
  38. data/proto/public/js/dragdrop.js +537 -0
  39. data/proto/public/js/effects.js +612 -0
  40. data/proto/public/js/prototype.js +644 -370
  41. data/proto/public/settings.xhtml +64 -0
  42. data/test/nitro/adapter/tc_cgi.rb +2 -2
  43. data/test/nitro/builder/tc_rss.rb +1 -1
  44. data/test/nitro/mixin/tc_pager.rb +35 -0
  45. data/test/nitro/tc_controller.rb +1 -1
  46. data/test/nitro/tc_cookie.rb +14 -0
  47. data/test/nitro/tc_dispatcher.rb +11 -6
  48. data/test/nitro/tc_server.rb +35 -0
  49. metadata +20 -15
  50. data/lib/nitro/builder/atom.rb +0 -74
  51. data/lib/nitro/part.rb +0 -22
  52. data/lib/nitro/simple.rb +0 -11
  53. data/lib/nitro/ui/popup.rb +0 -41
  54. data/lib/nitro/ui/tabs.rb +0 -25
  55. data/lib/nitro/uri.rb +0 -193
  56. data/test/nitro/builder/tc_atom.rb +0 -24
  57. data/test/nitro/tc_uri.rb +0 -97
  58. 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. In essence,
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 the Ruby language.
5
- # Nitro aims to provide a robust infrastructure for scalable
6
- # web applications that can be distributed over a server
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 even personal
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.19.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.
@@ -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.name}">#{p.name}</label></dt>
32
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
33
33
  <dd>
34
- <input type="text" id="#{p.name}" name="#{p.name}" value="#{obj.send(p.symbol)}" />
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.name}">#{p.name}</label></dt>
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.name}" name="#{p.name}">#{val}</textarea>
49
+ <textarea id="#{p.symbol}" name="#{p.symbol}">#{val}</textarea>
50
50
  }
51
51
  else
52
52
  str << %{
53
- <input type="text" id="#{p.name}" name="#{p.name}" value="#{val}" />
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.name}">#{p.name}</label></dt>
61
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
62
62
  <dd>
63
- <input type="checkbox" id="#{p.name}" name="#{p.name}" />
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.name}">#{p.name}</label></dt>
68
+ <dt><label for="#{p.symbol}">#{p.symbol}</label></dt>
69
69
  <dd>
70
- <input type="text" id="#{p.name}" name="#{p.name}" value="#{obj.send(p.symbol)}" />
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
@@ -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.view_uri}" if obj.respond_to?(:view_uri)
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
 
@@ -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
- mattr_accessor :caching_enabled, true
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.class_eval do
23
- cattr_accessor :caching_enabled, true
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
@@ -29,11 +29,6 @@ class Conf < Flexob
29
29
  super(hash)
30
30
  end
31
31
 
32
- def mount(name, options = {})
33
- $nitro_mount_options = options
34
- require_part(name)
35
- end
36
-
37
32
  end
38
33
 
39
34
  end
@@ -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
- ActionParam = Struct.new(:default, :format, :required)
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
- # The Controller part in the MVC paradigm.
75
- # A Controller encpsulates a set of actions.
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
- # A hash containing metadata for the action
85
- # methods.
81
+ module Publishable
82
+ def self.append_features(base)
86
83
 
87
- def self.action_metadata
88
- # FIXME: improve this.
89
- @action_metadata ||= {}
90
- @action_metadata
91
- end
92
-
93
- # The directory where the templates for this controller
94
- # reside.
95
-
96
- @template_root = File.join(Nitro::LibPath, '..', 'proto', 'public')
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
- class << self
115
- attr_accessor :template_root
97
+ # Define metadata for an action. This is a helper
98
+ # macro.
116
99
 
117
- alias __old_inherited inherited
118
-
119
- #--
120
- # gmosx, FIXME: the template_root hack is temporary.
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
- DEF_FILE = caller[3].to_s.strip.gsub( /:[0-9]+$/ , '')
105
+ action_metadata[name] = ActionMeta.new(options)
136
106
  end
137
- }
138
-
139
- __old_inherited(child)
107
+ end
140
108
  end
141
109
 
142
- # Define metadata for an action. This is a helper
143
- # macro.
110
+ # Aliases an action
111
+ #--
112
+ # gmosx, FIXME: better implementation needed.
113
+ #++
144
114
 
145
- def action(name, options)
146
- if meta = action_metadata[name]
147
- meta.update(options)
148
- else
149
- action_metadata[name] = ActionMeta.new(options)
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
- def action_methods
157
- classes = self.ancestors.reject do |a|
158
- [Object, Kernel, Render, Controller, Caching].include?(a)
159
- end
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
- classes.delete(PP::ObjectMixin) if defined?(PP::ObjectMixin)
162
-
163
- methods = classes.inject([]) do |action_methods, klass|
164
- action_methods + klass.public_instance_methods(false)
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
- end
209
+ class SimpleController < Controller
173
210
  end
174
211
 
175
212
  end