nitro 0.5.0 → 0.6.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 (50) hide show
  1. data/ChangeLog +4 -2201
  2. data/ChangeLog.1 +2344 -0
  3. data/README +4 -4
  4. data/RELEASES +22 -0
  5. data/bin/new_app.rb +17 -3
  6. data/bin/proto/README +34 -0
  7. data/bin/proto/apache.conf +1 -0
  8. data/bin/proto/app.rb +20 -0
  9. data/bin/proto/config.rb +77 -0
  10. data/bin/proto/root/index.xhtml +43 -0
  11. data/bin/proto/root/style.css +218 -0
  12. data/bin/proto/root/style.xsl +130 -0
  13. data/examples/blog/app.rb +1 -2
  14. data/examples/blog/config.rb +20 -18
  15. data/examples/blog/env.rb +22 -0
  16. data/examples/blog/lib/blog.rb +43 -15
  17. data/examples/blog/root/entry_form.xhtml +1 -1
  18. data/examples/blog/root/index.xhtml +5 -0
  19. data/examples/blog/root/login.xhtml +2 -0
  20. data/examples/blog/root/m/nitro.gif +0 -0
  21. data/examples/blog/root/style.css +83 -0
  22. data/examples/blog/root/style.xsl +7 -3
  23. data/examples/og/run.rb +41 -2
  24. data/examples/tiny/app.rb +1 -2
  25. data/examples/tiny/root/index.xhtml +8 -2
  26. data/examples/tiny/root/nitro-small.png +0 -0
  27. data/lib/glue.rb +1 -1
  28. data/lib/glue/property.rb +9 -3
  29. data/lib/nitro/application.rb +18 -1
  30. data/lib/nitro/builders/form.rb +84 -0
  31. data/lib/nitro/builders/rss.rb +4 -5
  32. data/lib/nitro/builders/table.rb +23 -0
  33. data/lib/nitro/filters.rb +157 -0
  34. data/lib/nitro/l10n.rb +11 -3
  35. data/lib/nitro/scaffold.rb +1 -1
  36. data/lib/nitro/server/render.rb +101 -4
  37. data/lib/nitro/server/shaders.rb +17 -5
  38. data/lib/nitro/service.rb +5 -5
  39. data/lib/nitro/ui/pager.rb +35 -11
  40. data/lib/nitro/version.rb +2 -2
  41. data/lib/og.rb +25 -17
  42. data/lib/og/backend.rb +15 -3
  43. data/lib/og/backends/mysql.rb +30 -3
  44. data/lib/og/backends/psql.rb +44 -3
  45. data/lib/og/meta.rb +117 -10
  46. data/lib/og/version.rb +1 -1
  47. data/lib/xsl/base.xsl +75 -6
  48. data/lib/xsl/ui.xsl +51 -0
  49. data/test/nitro/ui/tc_pager.rb +6 -0
  50. metadata +23 -2
data/lib/nitro/l10n.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  # = L10N, Localization support
2
2
  #
3
- # code: tml
3
+ # code: gmosx
4
4
  #
5
5
  # (c) 2002-2003 Navel, all rights reserved.
6
- # $Id: l10n.rb 152 2004-11-13 20:02:35Z gmosx $
6
+ # $Id: l10n.rb 185 2004-12-10 13:29:09Z gmosx $
7
+
8
+ require 'nitro/filters'
7
9
 
8
10
  $lc_en = {}
9
11
  $lc_el = {}
@@ -12,7 +14,6 @@ $lc_el = {}
12
14
  #
13
15
  # Override as needed in your application.
14
16
  #
15
-
16
17
  $lc_map = {
17
18
  "en" => $lc_en,
18
19
  "el" => $lc_el
@@ -20,3 +21,10 @@ $lc_map = {
20
21
 
21
22
  # The locales to use for this application.
22
23
  $lc_use = %w{lc-en lc-el}
24
+
25
+ module LocalizationFilter
26
+ def localize
27
+ @lc = @session[:LC] || $lc_en
28
+ end
29
+ end
30
+
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id$
5
+ # $Id: scaffold.rb 175 2004-11-26 16:11:27Z gmosx $
6
6
 
7
7
  require 'glue/inflector'
8
8
 
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: render.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: render.rb 185 2004-12-10 13:29:09Z gmosx $
6
6
 
7
7
  module N
8
8
 
@@ -105,7 +105,15 @@ module RenderUtils
105
105
  @response.header['Content-Type'] = 'text/html'
106
106
  @out ||= ''
107
107
  }
108
+
109
+ # call 'before' filter chain.
110
+ if klass.respond_to?(:before_filters)
111
+ code << %{
112
+ #{klass.gen_filters_call_code(klass.before_filters)}
113
+ }
114
+ end
108
115
 
116
+ # call the action
109
117
  if klass.instance_methods.include?(meth)
110
118
  valid = true
111
119
  code << %{
@@ -113,6 +121,7 @@ module RenderUtils
113
121
  }
114
122
  end
115
123
 
124
+ # call the programmatically generated template if exists.
116
125
  if klass.instance_methods.include?("#{meth}__xhtml")
117
126
  valid = true
118
127
  code << %{
@@ -120,6 +129,7 @@ module RenderUtils
120
129
  }
121
130
  end
122
131
 
132
+ # call the template
123
133
  if template = template_for_method(base, meth)
124
134
  valid = true
125
135
  code << %{
@@ -128,6 +138,13 @@ module RenderUtils
128
138
  end
129
139
 
130
140
  raise "Invalid method '#{meth}' for service '#{klass}'!" unless valid
141
+
142
+ # call 'after' filter chain.
143
+ if klass.respond_to?(:after_filters)
144
+ code << %{
145
+ #{klass.gen_filters_call_code(klass.after_filters)}
146
+ }
147
+ end
131
148
 
132
149
  code << %{
133
150
  redirect_referer if @out.empty?
@@ -142,6 +159,8 @@ module RenderUtils
142
159
  }
143
160
  end
144
161
 
162
+ # puts '++', code, '++'
163
+
145
164
  klass.class_eval(code)
146
165
 
147
166
  return "__#{meth}"
@@ -160,6 +179,14 @@ module RenderUtils
160
179
  @out ||= ''
161
180
  }
162
181
 
182
+ # call 'before' filter chain.
183
+ if klass.respond_to?(:before_filters)
184
+ code << %{
185
+ #{klass.gen_filters_call_code(klass.before_filters)}
186
+ }
187
+ end
188
+
189
+ # call the action
163
190
  if klass.instance_methods.include?(meth)
164
191
  valid = true
165
192
  code << %{
@@ -167,6 +194,7 @@ module RenderUtils
167
194
  }
168
195
  end
169
196
 
197
+ # call the programmatically generated template if exists.
170
198
  if klass.instance_methods.include?("#{meth}__xml")
171
199
  valid = true
172
200
  code << %{
@@ -174,6 +202,7 @@ module RenderUtils
174
202
  }
175
203
  end
176
204
 
205
+ # call the template
177
206
  if template = template_for_method(base, meth, 'xml')
178
207
  valid = true
179
208
  code << %{
@@ -182,7 +211,14 @@ module RenderUtils
182
211
  end
183
212
 
184
213
  raise "Invalid method '#{meth}' for service #{klass}!" unless valid
185
-
214
+
215
+ # call 'after' filter chain.
216
+ if klass.respond_to?(:after_filters)
217
+ code << %{
218
+ #{klass.gen_filters_call_code(klass.after_filters)}
219
+ }
220
+ end
221
+
186
222
  code << %{
187
223
  end
188
224
  }
@@ -200,6 +236,17 @@ module RenderUtils
200
236
  return "__rest_#{meth}"
201
237
  end
202
238
 
239
+ #
240
+ #
241
+ def load_statically_included(filename)
242
+ $log.debug "Statically including '#{filename}'" if $DBG
243
+
244
+ text = File.read(filename)
245
+ text.gsub!(/<\?xml.*\?>/, '')
246
+ text.gsub!(/<\/?root(.*?)>/m, ' ');
247
+
248
+ return text
249
+ end
203
250
 
204
251
  end
205
252
 
@@ -234,6 +281,8 @@ module Render
234
281
  @response = response
235
282
  @session = session
236
283
  @params = request.query
284
+
285
+ @out_buffers = nil
237
286
  end
238
287
 
239
288
  # Returns the output of the rendering as string.
@@ -268,6 +317,9 @@ module Render
268
317
  if self.class == render_class
269
318
  self.send(meth)
270
319
  else
320
+ if $reload_scripts and defined?(render_class::SOURCE_FILE)
321
+ load(render_class::SOURCE_FILE)
322
+ end
271
323
  r = render_class.new(base, @request, @response, @session)
272
324
  r.send(meth)
273
325
  @out = r.out
@@ -276,7 +328,7 @@ module Render
276
328
  log_error "error while handling '#{path}'."
277
329
  log_error pp_exception(e)
278
330
  # more fault tolerant, only flags the erroneous box with
279
- # errorm not the full page.
331
+ # error not the full page.
280
332
  @out << '(error)'
281
333
  end
282
334
 
@@ -311,12 +363,57 @@ module Render
311
363
  end
312
364
 
313
365
  # Log a rendering error.
314
- #
366
+ #--
367
+ # FIXME: find a better name
368
+ #++
315
369
  def log_error(str)
316
370
  @rendering_errors ||= []
317
371
  @rendering_errors << str
318
372
  $log.error str
319
373
  end
374
+
375
+ # --------------------------------------------------------------------
376
+ # Output buffering methods.
377
+
378
+ # Start (push) a new output buffer.
379
+ #
380
+ def ob_start
381
+ @out_buffers = [] unless @out_buffers
382
+ @out_buffers.push(@out)
383
+ @out = ''
384
+ end
385
+
386
+ # End (pop) the current output buffer.
387
+ #
388
+ def ob_end
389
+ @out = @out_buffers.pop
390
+ end
391
+
392
+ # End (pop) the current output buffer and write to the parent.
393
+ #
394
+ def ob_write_end
395
+ nested_buffer = @out
396
+ @out = @out_buffers.pop
397
+ @out << nested_buffer
398
+ end
399
+ # --------------------------------------------------------------------
400
+ # Caching methods.
401
+
402
+ #--
403
+ # FIXME: pseudocode, not working.
404
+ #++
405
+ def cache_start
406
+ valid?
407
+ ob_start
408
+ end
409
+
410
+ #--
411
+ # FIXME: pseudocode, not working.
412
+ #++
413
+ def cache_end
414
+ save_fragment(@out)
415
+ ob_write_end
416
+ end
320
417
  end
321
418
 
322
419
  end # module
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: shaders.rb 152 2004-11-13 20:02:35Z gmosx $
5
+ # $Id: shaders.rb 188 2004-12-10 14:14:17Z gmosx $
6
6
 
7
7
  module N
8
8
 
@@ -66,6 +66,9 @@ class RubyShader < N::Shader
66
66
  # strip the xml header! (interracts with the following gsub!)
67
67
  text.gsub!(/<\?xml.*\?>/, "")
68
68
 
69
+ # statically include files.
70
+ # TODO: Add here!
71
+
69
72
  # xform include instructions <include href="xxx" />
70
73
  # must be transformed before the processinc instructions.
71
74
  text.gsub!(/<include href="(.*?)"(.*)(.?)\/>/) { |match|
@@ -75,19 +78,28 @@ class RubyShader < N::Shader
75
78
  # remove <root> elements. typically removed by xslt but lets
76
79
  # play it safe.
77
80
  text.gsub!(/<(\/)?root>/, '')
78
-
81
+
82
+ # runtime ruby code.
83
+
79
84
  # xform the processing instructions, use <?r as
80
85
  # a marker.
81
86
  text.gsub!(/\?>/, "\n@out << %^")
82
- text.gsub!(/<\?r /, "^\n")
87
+ text.gsub!(/<\?r(\s?)/, "^\n")
83
88
 
84
- # xform alternative code tags (used in xsl stylesheets)
89
+ # xform alternative code tags (very useful in xsl stylesheets)
85
90
  #
86
91
  text.gsub!(/<\/ruby>/, "\n@out << %^")
87
92
  text.gsub!(/<ruby>/, "^\n")
88
93
 
89
- text = "@out << %^" + text + "^"
94
+ # compile time ruby code.
95
+ # Usefull for example to prevaluate localization.
90
96
 
97
+ text.gsub!(/\#\[(.*?)\]/) { |match|
98
+ eval($1)
99
+ }
100
+
101
+ text = "@out << %^" + text + "^"
102
+
91
103
  process_next(hash, text)
92
104
  end
93
105
 
data/lib/nitro/service.rb CHANGED
@@ -2,25 +2,25 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: service.rb 159 2004-11-18 10:18:30Z gmosx $
5
+ # $Id: service.rb 185 2004-12-10 13:29:09Z gmosx $
6
6
 
7
7
  require 'nitro/server/render'
8
8
  require 'nitro/scaffold'
9
+ require 'nitro/filters'
9
10
 
10
11
  module N
11
12
 
12
13
  # = Service
13
14
  #
14
- # An Application Server service.
15
+ # Defines an application service.
15
16
  #
16
17
  class Service
17
18
  include N::Render
19
+ include N::Scaffolding
20
+ include N::Filtering
18
21
 
19
22
  # The base path of the service, essentially the mount point.
20
23
  attr :base_path
21
24
  end
22
25
 
23
- class Methods
24
- end
25
-
26
26
  end # module
@@ -2,7 +2,9 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: pager.rb 152 2004-11-13 20:02:35Z gmosx $
5
+ # $Id: pager.rb 185 2004-12-10 13:29:09Z gmosx $
6
+
7
+ require 'nitro/uri'
6
8
 
7
9
  module N; module UI
8
10
 
@@ -20,11 +22,28 @@ module N; module UI
20
22
  # The pager does not extend Array (it includes an Array instead) to
21
23
  # avoid a concat() in the initialization step.
22
24
  #
23
- # TODO:
24
- # - Extend from array? (would be more elegant)
25
25
  #
26
26
  # === Example:
27
27
  #
28
+ # @pager = N::UI::Pager.new('entries', @request, 5)
29
+ # @entries = N::BlogEntry.all("ORDER BY oid #{@pager.sql_limit}")
30
+ # @pager.set(N::BlogEntry.count)
31
+ #
32
+ # default navigation (customize with css):
33
+ # <div class="pager">#{@pager.navigation}</div>
34
+ #
35
+ # custom navigation:
36
+ #
37
+ # <table cellspacing="0" width="100%" border="1">
38
+ # <tr>
39
+ # <td width="64"><x:pager-prev>Previous</x:pager-prev></td>
40
+ # <td width="100%"></td>
41
+ # <td width="64"><x:pager-next>Next</x:pager-next></td>
42
+ # </tr>
43
+ # </table>
44
+ #
45
+ # === Investigate:
46
+ #
28
47
  # INVESTIGATE:
29
48
  # mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
30
49
  # -> WHERE id > 100 LIMIT 10;
@@ -39,11 +58,11 @@ class Pager < Array
39
58
  # read needed variables from the request.
40
59
  attr_accessor :request
41
60
 
42
- def initialize(name, request, items_per_page, items = nil)
61
+ def initialize(name, request, items_per_page = 10, items = nil)
43
62
  raise "items_per_page should be > 0" unless items_per_page > 0
44
63
 
45
64
  @request, @name = request, name
46
- @page = request.get("__pg#{@name}", 1)
65
+ @page = request.query.fetch("__pg#{@name}", 1).to_i
47
66
  @items_per_page = items_per_page
48
67
  @start_idx = (@page - 1) * items_per_page
49
68
 
@@ -131,15 +150,15 @@ class Pager < Array
131
150
 
132
151
  unless @page == first_page()
133
152
  nav << %{
134
- <div class="first"><a href="#{target_uri(first_page())}">����</a></div>
135
- <div class="previous"><a href="#{target_uri(previous_page())}">�����������</a></div>
153
+ <div class="first"><a href="#{target_uri(first_page())}">First</a></div>
154
+ <div class="previous"><a href="#{target_uri(previous_page())}">Previous</a></div>
136
155
  }
137
156
  end
138
157
 
139
158
  unless @page == last_page()
140
159
  nav << %{
141
- <div class="last"><a href="#{target_uri(last_page())}">�����</a></div>
142
- <div class="next"><a href="#{target_uri(next_page())}">�������</a></div>
160
+ <div class="last"><a href="#{target_uri(last_page())}">Last</a></div>
161
+ <div class="next"><a href="#{target_uri(next_page())}">Next</a></div>
143
162
  }
144
163
  end
145
164
 
@@ -174,15 +193,20 @@ class Pager < Array
174
193
  end
175
194
  end
176
195
 
196
+ # Returns the current offset. The offset is zero-based.
197
+ #
198
+ def offset
199
+ (@page-1) * @items_per_page
200
+ end
201
+
177
202
  # ------------------------------------------------------------------
178
203
 
179
204
  # Generate the target URI.
180
205
  #
181
206
  def target_uri(page)
182
207
  params = {"__pg#{@name}" => page}
183
- return N::UriUtils.update_query_string(@request.uri, params)
208
+ return N::UriUtils.update_query_string(@request.request_uri.to_s, params)
184
209
  end
185
- private :target_uri
186
210
 
187
211
  end
188
212
 
data/lib/nitro/version.rb CHANGED
@@ -2,10 +2,10 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: version.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: version.rb 185 2004-12-10 13:29:09Z gmosx $
6
6
 
7
7
  # The name of the server.
8
8
  $srv_name = 'Nitro'
9
9
 
10
10
  # The version of the server.
11
- $srv_version = '0.5.0'
11
+ $srv_version = '0.6.0'
data/lib/og.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: og.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: og.rb 185 2004-12-10 13:29:09Z gmosx $
6
6
 
7
7
  require "glue/property"
8
8
  require "glue/array"
@@ -10,6 +10,24 @@ require "glue/hash"
10
10
  require "glue/time"
11
11
  require "glue/pool"
12
12
 
13
+ # If true, only allow reading from the database. Usefull
14
+ # for maintainance.
15
+ #
16
+ $og_read_only_mode = false
17
+
18
+ # If true, the library automatically 'enchants' managed classes.
19
+ # In enchant mode, special db aware methods are added to
20
+ # managed classes and instances.
21
+ #
22
+ $og_enchant_managed_classes = true
23
+
24
+ # If true, use Ruby's advanced introspection capabilities to
25
+ # automatically manage classes tha define properties.
26
+ $og_auto_manage_classes = true
27
+
28
+ # If true, automatically include the Og meta-language into Module.
29
+ $og_include_meta_language = true
30
+
13
31
  require "og/meta"
14
32
 
15
33
  # = Og
@@ -93,21 +111,6 @@ require "og/meta"
93
111
  #
94
112
  module Og
95
113
 
96
- # If true, only allow reading from the database. Usefull
97
- # for maintainance.
98
- #
99
- $og_read_only_mode = false
100
-
101
- # If true, the library automatically 'enchants' managed classes.
102
- # In enchant mode, special db aware methods are added to
103
- # managed classes and instances.
104
- #
105
- $og_enchant_managed_classes = true
106
-
107
- # If true, use Ruby's advanced introspection capabilities to
108
- # automatically manage classes tha define properties.
109
- $og_auto_manage_classes = true
110
-
111
114
  # = Unmanageable
112
115
  #
113
116
  # Marker module. If included this in a class, the Og automanager
@@ -328,7 +331,11 @@ class Database
328
331
  def self.all(extra_sql = nil)
329
332
  $og.load_all(#{klass}, extra_sql)
330
333
  end
331
-
334
+
335
+ def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
336
+ $og.count(sql, #{klass})
337
+ end
338
+
332
339
  def self.select(sql)
333
340
  $og.select(sql, #{klass})
334
341
  end
@@ -343,6 +350,7 @@ class Database
343
350
 
344
351
  def save
345
352
  $og << self
353
+ return self
346
354
  end
347
355
  alias_method :save!, :save
348
356