nitro 0.26.0 → 0.27.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.
Files changed (78) hide show
  1. data/CHANGELOG +312 -0
  2. data/INSTALL +3 -1
  3. data/ProjectInfo +6 -9
  4. data/README +32 -5
  5. data/Rakefile +5 -1
  6. data/bin/nitrogen +3 -60
  7. data/doc/MIGRATION +24 -0
  8. data/doc/RELEASES +141 -0
  9. data/doc/lhttpd.txt +3 -0
  10. data/lib/glue/magick.rb +38 -0
  11. data/lib/glue/thumbnails.rb +3 -0
  12. data/lib/glue/webfile.rb +137 -0
  13. data/lib/nitro.rb +1 -1
  14. data/lib/nitro/adapter/acgi.rb +235 -0
  15. data/lib/nitro/adapter/cgi.rb +16 -17
  16. data/lib/nitro/adapter/scgi.rb +4 -4
  17. data/lib/nitro/adapter/webrick.rb +9 -2
  18. data/lib/nitro/cgi.rb +49 -49
  19. data/lib/nitro/cgi/response.rb +4 -0
  20. data/lib/nitro/cgi/stream.rb +7 -7
  21. data/lib/nitro/cgi/utils.rb +2 -1
  22. data/lib/nitro/compiler.rb +47 -4
  23. data/lib/nitro/compiler/elements.rb +40 -20
  24. data/lib/nitro/compiler/layout.rb +21 -0
  25. data/lib/nitro/compiler/localization.rb +3 -1
  26. data/lib/nitro/compiler/markup.rb +2 -0
  27. data/lib/nitro/compiler/morphing.rb +16 -4
  28. data/lib/nitro/compiler/script.rb +109 -0
  29. data/lib/nitro/context.rb +10 -10
  30. data/lib/nitro/dispatcher.rb +4 -2
  31. data/lib/nitro/element.rb +107 -26
  32. data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
  33. data/lib/nitro/flash.rb +4 -1
  34. data/lib/nitro/helper.rb +15 -0
  35. data/lib/nitro/helper/benchmark.rb +8 -2
  36. data/lib/nitro/helper/form.rb +3 -3
  37. data/lib/nitro/helper/form/controls.rb +131 -29
  38. data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
  39. data/lib/nitro/helper/javascript.rb +69 -59
  40. data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
  41. data/lib/nitro/helper/javascript/morphing.rb +163 -0
  42. data/lib/nitro/helper/javascript/prototype.rb +96 -0
  43. data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
  44. data/lib/nitro/helper/layout.rb +42 -0
  45. data/lib/nitro/helper/table.rb +190 -27
  46. data/lib/nitro/{adapter → helper}/wee.rb +9 -3
  47. data/lib/nitro/render.rb +23 -17
  48. data/lib/nitro/scaffolding.rb +19 -2
  49. data/lib/nitro/server.rb +4 -8
  50. data/lib/nitro/server/runner.rb +28 -6
  51. data/lib/nitro/session.rb +7 -7
  52. data/lib/nitro_and_og.rb +2 -0
  53. data/proto/public/Makefile.acgi +40 -0
  54. data/proto/public/acgi.c +138 -0
  55. data/proto/public/js/builder.js +7 -3
  56. data/proto/public/js/controls.js +32 -12
  57. data/proto/public/js/dragdrop.js +4 -3
  58. data/proto/public/js/effects.js +111 -62
  59. data/proto/public/js/scriptaculous.js +10 -13
  60. data/proto/public/js/slider.js +88 -31
  61. data/proto/public/scaffold/new.xhtml +2 -2
  62. data/setup.rb +1585 -0
  63. data/src/part/admin.rb +6 -0
  64. data/src/part/admin/controller.rb +3 -3
  65. data/src/part/admin/skin.rb +1 -8
  66. data/test/nitro/adapter/tc_webrick.rb +2 -0
  67. data/test/nitro/tc_controller_aspect.rb +1 -1
  68. data/test/nitro/tc_element.rb +5 -6
  69. data/test/nitro/tc_table.rb +66 -0
  70. metadata +277 -271
  71. data/doc/architecture.txt +0 -2
  72. data/doc/bugs.txt +0 -15
  73. data/doc/tutorial.txt +0 -26
  74. data/install.rb +0 -37
  75. data/lib/nitro/compiler/script_generator.rb +0 -14
  76. data/lib/nitro/compiler/shaders.rb +0 -206
  77. data/lib/nitro/helper/prototype.rb +0 -49
  78. data/lib/nitro/scaffold/relations.rb +0 -54
@@ -0,0 +1,42 @@
1
+ require 'nano/string/camelize'
2
+
3
+ require 'nitro/element'
4
+
5
+ module Nitro
6
+
7
+ # This helper uses Nitro's powerfull Elements mechanism to
8
+ # implement a simple Rails style Layout helper. Perhaps this
9
+ # may be useful for people coming over from Rails.
10
+ #
11
+ # WARNING: This is not enabled by default. You have to insert
12
+ # the LayoutCompiler before the ElementsCompiler for layout to
13
+ # work.
14
+
15
+ module LayoutHelper
16
+
17
+ def self.included(base)
18
+ base.module_eval do
19
+ # Enclose all templates of this controller with the
20
+ # given element.
21
+
22
+ def self.layout(name = nil)
23
+ klass = name.to_s.camelize
24
+
25
+ unless klass
26
+ if defined? 'Nitro::Element::Layout'
27
+ klass = Nitro::Element::Layout
28
+ end
29
+ end
30
+
31
+ if klass
32
+ ann self, :layout => klass
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ # * George Moschovitis <gm@navel.gr>
@@ -1,3 +1,6 @@
1
+ require 'glue/uri'
2
+ require 'glue/configuration'
3
+
1
4
  module Nitro
2
5
 
3
6
  # The TableBuilder is a helper class that automates the creation
@@ -14,11 +17,37 @@ module Nitro
14
17
  # <div class="custom-table-class">
15
18
  # #{table :values => users, :headers => header}
16
19
  # </div>
20
+ #
21
+ #
22
+ # === Extended Example
23
+ #
24
+ # <?r
25
+ # users = User.all.map { |u| [u.name, u.first_name, u.last_name, u.email] }
26
+ # headers = ['Username', 'First name', 'Last name', 'Email']
27
+ # order_opts = { :right => true, # right align the order controls
28
+ # :values => [nil, 'first_name', 'last_name'], # column names from DB
29
+ # :asc_pic => "/images/asc.png",
30
+ # :desc_pic => "/images/desc.png" }
31
+ # ?>
32
+ #
33
+ # <div class="custom-table-class">
34
+ # #{table :values => users, :headers => header,
35
+ # :order => order_opts, :alternating_rows => true }
36
+ # </div>
37
+ #
17
38
  #--
18
- # TODO: sorting, thead/tbody/legend etc, verbose...
39
+ # TODO: legend, verbose... ?
19
40
  #++
20
41
 
21
42
  module TableHelper
43
+
44
+ # The order by key.
45
+
46
+ setting :order_by_key, :default => '_order_by', :doc => 'The order key'
47
+
48
+ # The order by key.
49
+
50
+ setting :order_direction_key, :default => '_order_direction', :doc => 'The order direction key'
22
51
 
23
52
  # [+options+]
24
53
  # A hash of options.
@@ -26,55 +55,189 @@ module TableHelper
26
55
  # :id = id of the component.
27
56
  # :headers = an array of the header values
28
57
  # :values = an array of arrays.
29
-
58
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
59
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
60
+ # :footers = an array of tfooter values
61
+
30
62
  def table(options)
31
- c = options
32
-
33
63
  str = '<table'
34
- str << %| id="#{c[:id]}"| if c[:id]
64
+ str << %| id="#{options[:id]}"| if options[:id]
35
65
  str << '>'
36
-
66
+
37
67
  str << table_rows(options)
38
68
 
39
69
  str << '</table>'
40
70
  end
41
71
  alias_method :build_table, :table
42
-
72
+
43
73
  # [+options+]
44
74
  # A hash of options.
45
75
  #
46
76
  # :id = id of the component.
47
77
  # :headers = an array of the header values
48
78
  # :values = an array of arrays.
49
-
79
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
80
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
81
+ # :footers = an array of tfooter values
82
+
50
83
  def table_rows(options)
51
- c = options
52
-
53
- str = '<tr>'
54
-
55
- for h in c[:headers]
56
- str << %|<th>#{h}</th>|
84
+ # also accept :items, :rows
85
+ options[:values] = options[:values] || options[:items] || options[:rows]
86
+
87
+ str = ''
88
+ str << table_header(options)
89
+ str << table_footer(options) if options[:footers]
90
+
91
+ items = options[:values]
92
+
93
+ row_state = 'odd' if options[:alternating_rows]
94
+
95
+ # when items is an array of arrays of arrays (meaning, several
96
+ # arrays deviding the table into several table parts (tbodys))
97
+
98
+ if create_tbody?(options)
99
+ for body in items
100
+ str << '<tbody>'
101
+
102
+ for row in body
103
+ str << '<tr'
104
+
105
+ if options[:alternating_rows]
106
+ str << %| class="row_#{row_state}"|
107
+ row_state = (row_state == "odd" ? "even" : "odd")
108
+ end
109
+
110
+ str << '>'
111
+
112
+ for value in row
113
+ str << %|<td>#{value}</td>|
114
+ end
115
+
116
+ str << '</tr>'
117
+ end
118
+
119
+ str << '</tbody>'
120
+ end
121
+ else
122
+ for row in items
123
+ str << '<tr'
124
+
125
+ if options[:alternating_rows]
126
+ str << %| class="row_#{row_state}"|
127
+ row_state = (row_state == "odd" ? "even" : "odd")
128
+ end
129
+
130
+ str << '>'
131
+
132
+ for value in row
133
+ str << %|<td>#{value}</td>|
134
+ end
135
+
136
+ str << '</tr>'
137
+ end
57
138
  end
58
-
59
- str << "</tr>"
60
-
61
- items = c[:values] || c[:items] || c[:rows]
62
-
63
- for row in c[:values]
64
- str << "<tr>"
65
-
66
- for v in row
67
- str << %|<td>#{v}</td>|
139
+
140
+ return str
141
+ end
142
+
143
+ private
144
+
145
+ # [+options+]
146
+ # A hash of options.
147
+ #
148
+ # :id = id of the component.
149
+ # :headers = an array of the header values
150
+ # :values = an array of arrays.
151
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
152
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
153
+ # :footers = an array of tfooter values
154
+
155
+ def table_header(options)
156
+ str = ''
157
+ str << '<thead>' if create_tbody?(options) || options[:footers]
158
+ str << '<tr>'
159
+
160
+ options[:headers].each_with_index do |header, index|
161
+ if (options[:order] && options[:order][:values] &&
162
+ options[:order][:values][index])
163
+ order_by = options[:order][:values][index]
164
+
165
+ asc_val = if options[:order][:asc_pic]
166
+ %|<img src="#{options[:order][:asc_pic]}" alt="asc" />|
167
+ else
168
+ '^'
169
+ end
170
+ desc_val = if options[:order][:desc_pic]
171
+ %|<img src="#{options[:order][:desc_pic]}" alt="desc" />|
172
+ else
173
+ 'v'
174
+ end
175
+
176
+ order_asc = "<a href='#{target_uri(order_by, 'ASC')}'>#{asc_val}</a>"
177
+ order_desc = "<a href='#{target_uri(order_by, 'DESC')}'>#{desc_val}</a>"
178
+
179
+ str << '<th><table width="100%" cellspacing="0" cellpadding="0"><tr>'
180
+
181
+ if options[:order][:left] || !options[:order][:right]
182
+ str << "<th>#{order_asc}<br />#{order_desc}</th>"
183
+ end
184
+
185
+ str << %|<th>#{header}</th>|
186
+
187
+ if options[:order][:right]
188
+ str << "<th>#{order_asc}<br />#{order_desc}</th>"
189
+ end
190
+
191
+ str << '</tr></table></th>'
192
+ else
193
+ str << %|<th>#{header}</th>|
68
194
  end
69
-
70
- str << "</tr>"
71
195
  end
72
-
196
+
197
+ str << '</tr>'
198
+ str << '</thead>' if create_tbody?(options) || options[:footers]
199
+
73
200
  return str
74
201
  end
202
+
203
+ # [+options+]
204
+ # A hash of options.
205
+ #
206
+ # :id = id of the component.
207
+ # :headers = an array of the header values
208
+ # :values = an array of arrays.
209
+ # :order = options hash (:left, :right, :asc_pic, :desc_pic, :values)
210
+ # :alternating_rows = alternating rows, use css to color row_even / row_odd
211
+ # :footers = an array of tfooter values
212
+
213
+ def table_footer(options)
214
+ str = '<tfoot><tr>'
215
+
216
+ for footer in options[:footers]
217
+ str << %|<td>#{footer}</td>|
218
+ end
219
+
220
+ str << '</tr></tfoot>'
221
+
222
+ return str
223
+ end
224
+
225
+ # Generate the target URI.
226
+
227
+ def target_uri(order_by, direction)
228
+ params = { TableHelper.order_by_key => order_by,
229
+ TableHelper.order_direction_key => direction }
230
+
231
+ return UriUtils.update_query_string(request.uri.to_s, params)
232
+ end
233
+
234
+ def create_tbody?(options)
235
+ options[:values][0][0].respond_to?(:to_ary)
236
+ end
75
237
 
76
238
  end
77
239
 
78
240
  end
79
241
 
80
242
  # * George Moschovitis <gm@navel.gr>
243
+ # * Kashia Buch <kashia@vfemail.net>
@@ -5,7 +5,10 @@ require 'wee/adaptors/nitro'
5
5
 
6
6
  module Nitro
7
7
 
8
- module WeeMixin
8
+ # Include this mixin to the standard Controller to have easy
9
+ # access to Wee Components.
10
+
11
+ module WeeHelper
9
12
  include Wee::Nitro::ControllerMixin
10
13
 
11
14
  # Returns the output of the component.
@@ -38,11 +41,14 @@ module WeeMixin
38
41
  end
39
42
  end
40
43
 
41
- # Add Wee-related helper methods to published objects.
44
+ #--
45
+ # Add Wee-related helper methods to the default Nitro
46
+ # controller.
47
+ #++
42
48
 
43
49
  class Controller
44
50
  include Wee::Nitro::ControllerMixin
45
- include WeeMixin
51
+ include WeeHelper
46
52
  end
47
53
 
48
54
  end
data/lib/nitro/render.rb CHANGED
@@ -27,7 +27,9 @@ class ActionExit < Exception; end
27
27
 
28
28
  class RenderExit < Exception; end
29
29
 
30
- # The output buffer.
30
+ # The output buffer. The output of a contoller action is
31
+ # accumulated in this buffer before sending this to the client
32
+ # as a HTTP Response.
31
33
  #--
32
34
  # TODO: Implement a FAST string (maybe in C)
33
35
  #++
@@ -125,18 +127,19 @@ module Render
125
127
  klass.new(@context, base).send(action)
126
128
  end
127
129
 
128
- rescue RenderExit, ActionExit => e
130
+ rescue NoActionError => e1
131
+ log_error(e1, path, false)
132
+ print '(error)'
129
133
 
130
- # Just stop rendering.
131
- # For example called by redirects.
132
-
133
- rescue Exception, StandardError => e
134
- log_error(e, path)
134
+ rescue RenderExit, ActionExit => e2
135
135
 
136
- # More fault tolerant, only flags the erroneous box with
137
- # error not the full page.
136
+ # Just stop rendering. For example called by redirects.
138
137
 
139
- @out << '(error)'
138
+ rescue Exception, StandardError => e3
139
+ # More fault tolerant, only flags the erroneous box with
140
+ # error not the full page.
141
+ log_error(e3, path)
142
+ print '(error)'
140
143
  end
141
144
 
142
145
  private
@@ -191,15 +194,18 @@ private
191
194
 
192
195
  # Log a rendering error.
193
196
 
194
- def log_error(error, path)
195
- @rendering_errors ||= []
196
- @rendering_errors << [error, path]
197
+ def log_error(error, path, full = true)
198
+ (@rendering_errors ||= []) << [error, path]
197
199
 
198
- # gmosx: Hmm perhaps this should not be logged
199
- # to avoid DOS attacks.
200
+ if full
201
+ # gmosx: Hmm perhaps this should not be logged
202
+ # to avoid DOS attacks.
200
203
 
201
- Logger.error "Error while handling '#{path}'."
202
- Logger.error pp_exception(error)
204
+ Logger.error "Error while handling '#{path}'."
205
+ Logger.error pp_exception(error)
206
+ else
207
+ Logger.error error.to_s
208
+ end
203
209
  end
204
210
 
205
211
  # Convenience method to lookup the session.
@@ -4,6 +4,11 @@ require 'nitro/helper/pager'
4
4
 
5
5
  module Nitro
6
6
 
7
+ # Scaffolding is a feature of Nitro that automatically generates
8
+ # maintenance methods for you. It is typically used in the
9
+ # early stages of development or by the auto administration
10
+ # part.
11
+ #
7
12
  # This module is applied to controllers to provide
8
13
  # automatically generated CRUD methods.
9
14
  #--
@@ -60,6 +65,10 @@ module Scaffolding
60
65
  klass.to_s.demodulize.underscore.downcase
61
66
  end
62
67
 
68
+ #--
69
+ # A helper that defines a class method.
70
+ #++
71
+
63
72
  def define_class_method(meth, code)
64
73
  unless @klass.instance_methods.include?(meth.to_s)
65
74
  @klass.module_eval %{
@@ -69,10 +78,18 @@ module Scaffolding
69
78
  }
70
79
  end
71
80
  end
72
-
81
+
82
+ #--
83
+ # A helper that defines a controller action.
84
+ #++
85
+
73
86
  def define_controller_action(definition, code, template = nil)
74
87
  sym, args = definition.to_s.split(/\(|\)/)
75
88
 
89
+ # Access Namespace::Klass.action as namespace/klass/action.
90
+
91
+ sym.gsub!(/::/, '__')
92
+
76
93
  if sym == 'index'
77
94
  action = "#{@base__}index"
78
95
  else
@@ -167,7 +184,7 @@ module Scaffolding
167
184
  # FIXME: investigate save, improve.
168
185
 
169
186
  define_controller_action 'save', %{
170
- if oid = request['#@oid']
187
+ if oid = request.fetch('#@oid', nil)
171
188
  oid = oid.to_s # fix StringIO (post).
172
189
  obj = request.fill(@klass[oid], :assign_relations => true, :force_boolean => true, :preprocess => true)
173
190
  else