nitro 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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