nitro 0.20.0 → 0.21.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 (115) hide show
  1. data/CHANGELOG +752 -543
  2. data/INSTALL +38 -38
  3. data/README +264 -225
  4. data/Rakefile +48 -49
  5. data/bin/nitro +3 -3
  6. data/bin/nitrogen +6 -6
  7. data/doc/AUTHORS +10 -10
  8. data/doc/CHANGELOG.1 +1939 -1939
  9. data/doc/CHANGELOG.2 +954 -954
  10. data/doc/LICENSE +3 -3
  11. data/doc/MIGRATION +28 -0
  12. data/doc/RELEASES +814 -643
  13. data/doc/config.txt +5 -5
  14. data/install.rb +7 -17
  15. data/lib/nitro.rb +38 -9
  16. data/lib/nitro/adapter/cgi.rb +311 -312
  17. data/lib/nitro/adapter/fastcgi.rb +18 -25
  18. data/lib/nitro/adapter/webrick.rb +128 -137
  19. data/lib/nitro/adapter/wee.rb +51 -0
  20. data/lib/nitro/caching.rb +20 -20
  21. data/lib/nitro/caching/actions.rb +43 -43
  22. data/lib/nitro/caching/fragments.rb +46 -46
  23. data/lib/nitro/caching/invalidation.rb +11 -11
  24. data/lib/nitro/caching/output.rb +65 -65
  25. data/lib/nitro/caching/stores.rb +67 -67
  26. data/lib/nitro/compiler.rb +262 -0
  27. data/lib/nitro/compiler/elements.rb +0 -0
  28. data/lib/nitro/compiler/errors.rb +65 -0
  29. data/lib/nitro/compiler/localization.rb +25 -0
  30. data/lib/nitro/compiler/markup.rb +19 -0
  31. data/lib/nitro/compiler/shaders.rb +206 -0
  32. data/lib/nitro/compiler/squeeze.rb +20 -0
  33. data/lib/nitro/compiler/xslt.rb +61 -0
  34. data/lib/nitro/context.rb +87 -88
  35. data/lib/nitro/controller.rb +151 -158
  36. data/lib/nitro/cookie.rb +34 -34
  37. data/lib/nitro/dispatcher.rb +195 -186
  38. data/lib/nitro/element.rb +132 -126
  39. data/lib/nitro/element/java_script.rb +6 -6
  40. data/lib/nitro/flash.rb +66 -66
  41. data/lib/nitro/mail.rb +192 -192
  42. data/lib/nitro/mixin/buffer.rb +66 -0
  43. data/lib/nitro/mixin/debug.rb +16 -16
  44. data/lib/nitro/mixin/form.rb +88 -0
  45. data/lib/nitro/mixin/helper.rb +2 -2
  46. data/lib/nitro/mixin/javascript.rb +108 -108
  47. data/lib/nitro/mixin/markup.rb +144 -0
  48. data/lib/nitro/mixin/pager.rb +202 -202
  49. data/lib/nitro/mixin/rss.rb +67 -0
  50. data/lib/nitro/mixin/table.rb +63 -0
  51. data/lib/nitro/mixin/xhtml.rb +75 -0
  52. data/lib/nitro/mixin/xml.rb +124 -0
  53. data/lib/nitro/render.rb +183 -359
  54. data/lib/nitro/request.rb +140 -140
  55. data/lib/nitro/response.rb +27 -27
  56. data/lib/nitro/routing.rb +21 -21
  57. data/lib/nitro/scaffold.rb +124 -118
  58. data/lib/nitro/server.rb +117 -80
  59. data/lib/nitro/server/runner.rb +341 -0
  60. data/lib/nitro/service.rb +12 -12
  61. data/lib/nitro/service/xmlrpc.rb +22 -22
  62. data/lib/nitro/session.rb +122 -120
  63. data/lib/nitro/session/drb.rb +9 -9
  64. data/lib/nitro/session/drbserver.rb +34 -34
  65. data/lib/nitro/template.rb +171 -155
  66. data/lib/nitro/testing/assertions.rb +90 -90
  67. data/lib/nitro/testing/context.rb +16 -16
  68. data/lib/nitro/testing/testcase.rb +34 -34
  69. data/proto/conf/lhttpd.conf +9 -9
  70. data/proto/public/error.xhtml +75 -75
  71. data/proto/public/index.xhtml +18 -18
  72. data/proto/public/js/behaviour.js +65 -65
  73. data/proto/public/js/controls.js +1 -1
  74. data/proto/public/js/prototype.js +3 -3
  75. data/proto/public/settings.xhtml +61 -61
  76. data/proto/run.rb +1 -5
  77. data/test/nitro/adapter/raw_post1.bin +0 -0
  78. data/test/nitro/adapter/tc_cgi.rb +57 -57
  79. data/test/nitro/adapter/tc_webrick.rb +4 -4
  80. data/test/nitro/mixin/tc_pager.rb +25 -25
  81. data/test/nitro/mixin/tc_rss.rb +24 -0
  82. data/test/nitro/mixin/tc_table.rb +31 -0
  83. data/test/nitro/mixin/tc_xhtml.rb +13 -0
  84. data/test/nitro/tc_caching.rb +10 -10
  85. data/test/nitro/tc_context.rb +8 -8
  86. data/test/nitro/tc_controller.rb +48 -48
  87. data/test/nitro/tc_cookie.rb +6 -6
  88. data/test/nitro/tc_dispatcher.rb +64 -64
  89. data/test/nitro/tc_element.rb +27 -27
  90. data/test/nitro/tc_flash.rb +31 -31
  91. data/test/nitro/tc_mail.rb +63 -63
  92. data/test/nitro/tc_server.rb +26 -26
  93. data/test/nitro/tc_session.rb +9 -9
  94. data/test/nitro/tc_template.rb +19 -19
  95. data/test/public/blog/list.xhtml +1 -1
  96. metadata +31 -37
  97. data/lib/nitro/buffering.rb +0 -45
  98. data/lib/nitro/builder/form.rb +0 -104
  99. data/lib/nitro/builder/rss.rb +0 -104
  100. data/lib/nitro/builder/table.rb +0 -80
  101. data/lib/nitro/builder/xhtml.rb +0 -132
  102. data/lib/nitro/builder/xml.rb +0 -131
  103. data/lib/nitro/conf.rb +0 -36
  104. data/lib/nitro/environment.rb +0 -21
  105. data/lib/nitro/errors.rb +0 -69
  106. data/lib/nitro/localization.rb +0 -153
  107. data/lib/nitro/markup.rb +0 -147
  108. data/lib/nitro/output.rb +0 -24
  109. data/lib/nitro/runner.rb +0 -348
  110. data/lib/nitro/shaders.rb +0 -206
  111. data/test/nitro/builder/tc_rss.rb +0 -23
  112. data/test/nitro/builder/tc_table.rb +0 -30
  113. data/test/nitro/builder/tc_xhtml.rb +0 -39
  114. data/test/nitro/builder/tc_xml.rb +0 -56
  115. data/test/nitro/tc_localization.rb +0 -49
data/doc/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The BSD License
2
2
 
3
- Copyright (c) 2004-2005, George 'tml' Moschovitis.
3
+ Copyright (c) 2004-2005, George 'gmosx' Moschovitis. (http://www.gmosx.com)
4
4
  Copyright (c) 2004-2005, Navel Ltd. (http://www.navel.gr)
5
5
  All rights reserved.
6
6
 
@@ -10,11 +10,11 @@ met:
10
10
 
11
11
  * Redistributions of source code must retain the above copyright
12
12
  notice, this list of conditions and the following disclaimer.
13
-
13
+
14
14
  * Redistributions in binary form must reproduce the above copyright
15
15
  notice, this list of conditions and the following disclaimer in the
16
16
  documentation and/or other materials provided with the distribution.
17
-
17
+
18
18
  * Neither the name of Navel nor the names of its contributors may be
19
19
  used to endorse or promote products derived from this software
20
20
  without specific prior written permission.
data/doc/MIGRATION ADDED
@@ -0,0 +1,28 @@
1
+ = Migration
2
+
3
+ Nitro and Og are under constant development. Some times we
4
+ really have to introduce features that break the compatibility
5
+ with older versions. This documents describes the required
6
+ steps to port your application to the latest Nitro version.
7
+
8
+ For more help, send your question to the mailing list:
9
+
10
+ http://rubyforge.org/mailman/listinfo/nitro-general
11
+
12
+ == 0.21.0 <- 0.20.0
13
+
14
+ 1. The helper methods for starting the application and defining
15
+ the compilation pipeline have changed. Have a look at
16
+ 'examples/blog/run.rb' for an example.
17
+
18
+ 2. The conventions for the generated join table for many_to_many
19
+ have changed, you may have to regenerate your schema.
20
+
21
+ 3. The builder functionality is provided by mixins now.
22
+
23
+ 4. The markup interpolators have changed. Instead of {{..}} use
24
+ #(..) (sanitize) or #|..| (full markup). For details have a look
25
+ at lib/nitro/compiler/markup.rb
26
+
27
+ 5. Actions no longer automatically redirect to the referer if the
28
+ output buffer is empty. You have to manually redirect. There is an option to switch on the old behaviour though.
data/doc/RELEASES CHANGED
@@ -1,4 +1,175 @@
1
- == Version 0.20.0
1
+ == Version 0.21.0
2
+
3
+ Nitro goes from strength to strength as the community gets bigger.
4
+ Great new features were introduced and a lot of effort
5
+ was spend on cleaning up Nitro's implementation and polishing
6
+ 'little things'. Many patches were contributed by the community
7
+ to make this is a release you will love!
8
+
9
+ Some notable changes:
10
+
11
+ * New compiler pipeline replaces the obscure shader mechanism. A
12
+ compiler object is responsible for transforming a controller action
13
+ and or the associated xhtml templates to a special ruby method
14
+ that will respond to given urls with the action output. Using
15
+ the aspect oriented features of Nitro or the specialized pipeline
16
+ setup method a developer can easily customize the compilation
17
+ stage to meet his needs. Here are some examples:
18
+
19
+ Compiler.setup_template_transformation do |template|
20
+ template = Elements.transform(template)
21
+ template = Localization.transform(template)
22
+ template = Markup.transform(template)
23
+ template = Template.transform(template)
24
+ end
25
+
26
+ or
27
+
28
+ Compiler.before "puts 'Compiling'", :on => :compile
29
+ Compiler.after "puts 'Template processed'", :on => :transform_template
30
+ Compiler.wrap Benchmark, :on => compile
31
+ Compiler.before :my_method, :on => compile
32
+
33
+ Special rendering effects where never easier. If you need run
34
+ time effects, just intercept the Render object.
35
+
36
+ * Integrated the new configuration system that was previewed in
37
+ the last release. All the configuration settings are now accessible
38
+ either through the owner class or from the global Configuration
39
+ variable using Ruby's metaprogramming features.
40
+
41
+ Moreover, Nitro now dynamically decides the configuration mode
42
+ (debug, stage, live/production) from environment variables or
43
+ command line arguments so depolying your application is easier
44
+ than ever: just run svn update on the live server, the application
45
+ will grab the correct configuration parameters automatically.
46
+ Of course you can use svn's advanced features to rollback to
47
+ earlier versions if you experience problems. The mode specific
48
+ configuration settings are defined either on ruby files or
49
+ yaml files or both.
50
+
51
+ Point your browser to http:://my.app.com/settings to browse
52
+ the settings for your application.
53
+
54
+ * Og dynamic queries. You can inject caclulated or join attributes
55
+ to your objects. Here is an example:
56
+
57
+ class Item
58
+ property :quantity, Fixnum
59
+ property :unit_price, Float
60
+
61
+ def initialize(quantity, unit_price)
62
+ @quantity = quantity
63
+ @unit_price = unit_price
64
+ end
65
+ end
66
+
67
+ Item.create 2, 3.0
68
+ item = Item.find_one :select => 'quantity*unit_price as total_price'
69
+ item.total_price # => 6.0
70
+
71
+ Please note that total_price is a dynamically injected
72
+ attribute. Now you can combine SQL's powerful query features
73
+ with the simplicity and elegance of Og.
74
+
75
+ * Og customized join tables allows you to use any Ruby object
76
+ as the join relation between other objects. Here comes an
77
+ example:
78
+
79
+ class Category
80
+ property :title, String
81
+ end
82
+
83
+ class Article
84
+ property :title, String
85
+ end
86
+
87
+ class ArticleToCategory
88
+ property :rate, Float
89
+ has_one Article
90
+ has_one Category
91
+ end
92
+
93
+ c1 = Category.create
94
+ c2 = Category.create
95
+
96
+ a = Article.create
97
+ a.categories.add(c1, :rate => 2.3)
98
+ a.categories.add(c2, :rate => 1.2)
99
+
100
+ for c in a.categories
101
+ p a.category_join_data(c).rate
102
+ end
103
+
104
+ * Og collections size() is now optimized.
105
+
106
+ * Og join code support refactoring. The new code is easier to read,
107
+ more customizable and generates more efficient code by default.
108
+
109
+ * Nitro automatically assings reasonable template_roots on
110
+ Controllers based on mount points. Moreover, the template_root
111
+ overloading feature was improved. If you cant to reuse an
112
+ existing controller but customize the view rendering by using
113
+ different templates for some actions, just assign a different
114
+ template root for this controller, and put the custom templates
115
+ inside that dir. The custom templates 'override' the templates
116
+ of the parent controller (templates for non customized actions
117
+ come from the parent's controller template_root). Creating
118
+ a library of reusable controllers (parts) was never easier.
119
+
120
+ * Major cleanup of the nitro source code, removed many files.
121
+
122
+ * Greatly improved Wee integration makes Nitro the premium
123
+ container for Wee components. Have a look at the updated
124
+ wee example.
125
+
126
+ * Improved builder mechanism for programmatic rendering. The new
127
+ builder resuses the controller helper mixins thanks to extensive
128
+ refactoring of the implementation. Here is an example:
129
+
130
+ class MyController
131
+ def index
132
+ build do
133
+ labels = ['George', 'Stella', 'Renos']
134
+ html {
135
+ head {
136
+ title 'A simple test'
137
+ }
138
+ body {
139
+ 10.times {
140
+ strong 'Hello World'
141
+ i 'Hello World222'
142
+ }
143
+ select(:id => 'names') {
144
+ options :labels => labels, :selected => 1
145
+ }
146
+ }
147
+ }
148
+ end
149
+ end
150
+
151
+ * Improved helper integration. Helpers are now accessed either
152
+ as mixins or through the builder mechanism.
153
+
154
+ #{form entity}
155
+ #{options :labels => [..], :values => [..], :selected => 1}
156
+
157
+ or
158
+
159
+ #{emit :form entity}
160
+ #{emit :options :labels => [..] ...}
161
+
162
+ * Reimplemented the markup mixin to make this more flexible. You
163
+ can easily customize the markup logic that is applied by the
164
+ markup macros.
165
+
166
+ * Updated the documentation.
167
+
168
+ * Fixed all reported or discovered bugs, many smaller
169
+ improvements.
170
+
171
+
172
+ == Version 0.20.0 was released on 12-07-2005
2
173
 
3
174
  Another superb release! State of the art AJAX/Javascript support,
4
175
  Wee components / programmatic renderer integration, a beginners
@@ -9,91 +180,91 @@ http://www.nitrohq.com
9
180
  Some notable changes:
10
181
 
11
182
  * Ajax is THE buzzword at the moment, and Nitro provides the
12
- best support you can find. Nitro fully separates the behaviour
13
- from the template using the behaviour.js library and allowing
14
- for dynamic injection of ajax functionality. The generated code
15
- contains clean html and all the javascript organized in a
16
- single <script> block. Here is an example:
17
-
18
- in the Controller:
19
-
20
- def index
21
- # Inject functionality to the DOM elements of the template.
22
-
23
- behaviour '#alert', %{
24
- el.onclick = function() {
25
- alert('Hello world');
26
- }
27
- }
28
- auto_complete :country # convert to autocomplete field
29
- live :live # convert to async link!
30
- draggable :dragger, :revert => false
31
- end
32
-
33
- def a_simple_action
34
- puts 'LIVE!'
35
- end
36
-
37
- def country_auto_complete # data for auto complete.
38
- %{
39
- <ul>
40
- <li>Greece</li>
41
- <li>England</li>
42
- ...
43
- </ul>
44
- }
45
- end
46
-
47
- in the Template:
48
-
49
- <label>Enter a country:</label>
50
- <input type="text" id="country" />
51
- <div id="country_auto_complete" class="auto_complete"> </div>
52
-
53
- Behaviour example:<br />
54
- <button id="alert">Click to alert</button>
55
-
56
- Drag and Drop example:<br />
57
- <div id="dragger">DRAG ME</div>
58
-
59
- Live/Asynchonous request (AJAX) example:<br />
60
- Here comes a <a id="live" href="a_simple_action">live link</a>.<br />
61
- (Check out the log to see the action called in the background!)
62
-
63
- All you have to do is define id's for your DOM elements. Here
64
- comes the generated code:
65
-
66
- <label>Enter a country:</label>
67
- ...
68
- (Check out the log to see the action called in the background!)
69
-
70
- <script type="text/javascript">
71
- var _behaviours = {
72
- '#alert': function(el) {
73
- el.onclick = function() {
74
- alert('Hello world');
75
- }
76
- },'#country': function(el) {
77
- el.autocomplete = 'off';
78
-
79
- },'#live': function(el) {
80
- el.onclick = function() {
81
- new Ajax.Request(el.href, {});
82
- return false;
83
- }
84
- }
85
- }
86
- Behaviour.register(_behaviours);
87
-
88
- new Ajax.Autocompleter('country', 'country_auto_complete', 'country_auto_complete');
89
- new Draggable('dragger', {revert:false});
90
- </script>
91
-
92
- See how a normal <a> tag is converted transparently to an Ajax request.
93
- The prototype, scriptacoulous and behaviour js libraries are used.
94
-
95
- The ajax support in this release is a PREVIEW. Stay tuned for
96
- major improvements (and some surprises) in the next version.
183
+ best support you can find. Nitro fully separates the behaviour
184
+ from the template using the behaviour.js library and allowing
185
+ for dynamic injection of ajax functionality. The generated code
186
+ contains clean html and all the javascript organized in a
187
+ single <script> block. Here is an example:
188
+
189
+ in the Controller:
190
+
191
+ def index
192
+ # Inject functionality to the DOM elements of the template.
193
+
194
+ behaviour '#alert', %{
195
+ el.onclick = function() {
196
+ alert('Hello world');
197
+ }
198
+ }
199
+ auto_complete :country # convert to autocomplete field
200
+ live :live # convert to async link!
201
+ draggable :dragger, :revert => false
202
+ end
203
+
204
+ def a_simple_action
205
+ puts 'LIVE!'
206
+ end
207
+
208
+ def country_auto_complete # data for auto complete.
209
+ %{
210
+ <ul>
211
+ <li>Greece</li>
212
+ <li>England</li>
213
+ ...
214
+ </ul>
215
+ }
216
+ end
217
+
218
+ in the Template:
219
+
220
+ <label>Enter a country:</label>
221
+ <input type="text" id="country" />
222
+ <div id="country_auto_complete" class="auto_complete"> </div>
223
+
224
+ Behaviour example:<br />
225
+ <button id="alert">Click to alert</button>
226
+
227
+ Drag and Drop example:<br />
228
+ <div id="dragger">DRAG ME</div>
229
+
230
+ Live/Asynchonous request (AJAX) example:<br />
231
+ Here comes a <a id="live" href="a_simple_action">live link</a>.<br />
232
+ (Check out the log to see the action called in the background!)
233
+
234
+ All you have to do is define id's for your DOM elements. Here
235
+ comes the generated code:
236
+
237
+ <label>Enter a country:</label>
238
+ ...
239
+ (Check out the log to see the action called in the background!)
240
+
241
+ <script type="text/javascript">
242
+ var _behaviours = {
243
+ '#alert': function(el) {
244
+ el.onclick = function() {
245
+ alert('Hello world');
246
+ }
247
+ },'#country': function(el) {
248
+ el.autocomplete = 'off';
249
+
250
+ },'#live': function(el) {
251
+ el.onclick = function() {
252
+ new Ajax.Request(el.href, {});
253
+ return false;
254
+ }
255
+ }
256
+ }
257
+ Behaviour.register(_behaviours);
258
+
259
+ new Ajax.Autocompleter('country', 'country_auto_complete', 'country_auto_complete');
260
+ new Draggable('dragger', {revert:false});
261
+ </script>
262
+
263
+ See how a normal <a> tag is converted transparently to an Ajax request.
264
+ The prototype, scriptacoulous and behaviour js libraries are used.
265
+
266
+ The ajax support in this release is a PREVIEW. Stay tuned for
267
+ major improvements (and some surprises) in the next version.
97
268
 
98
269
  * Wee Components integration. Nitro now transparently integrates
99
270
  Wee components. This is truly a win-win situation. Wee applications
@@ -115,7 +286,7 @@ Some notable changes:
115
286
  end
116
287
 
117
288
  module MyControlllerMixin
118
- # gets automatically mixed in
289
+ # gets automatically mixed in
119
290
  end
120
291
 
121
292
  This works just like Og Mixins.
@@ -126,11 +297,11 @@ Some notable changes:
126
297
  Here is an example:
127
298
 
128
299
  class Render
129
- setting :template_extension, :default => 'xhtml', :doc => 'The default template extension'
300
+ setting :template_extension, :default => 'xhtml', :doc => 'The default template extension'
130
301
  end
131
302
 
132
303
  class Session
133
- setting :store, :default => 'memory', :doc => 'The session store'
304
+ setting :store, :default => 'memory', :doc => 'The session store'
134
305
  end
135
306
 
136
307
  You can configure the Application using ruby code or yaml files:
@@ -141,10 +312,10 @@ Some notable changes:
141
312
  or
142
313
 
143
314
  Render:
144
- template_extension: xhtml
315
+ template_extension: xhtml
145
316
  Session:
146
- store: drb
147
-
317
+ store: drb
318
+
148
319
  You can access all defined settings:
149
320
 
150
321
  Configuration.settings.each { |s| ... }
@@ -162,58 +333,58 @@ Some notable changes:
162
333
 
163
334
  class HelloWorld
164
335
  def index
165
- print 'Hello World'
336
+ print 'Hello World'
166
337
  end
167
338
 
168
339
  def add(val)
169
- print "added: #{val + 2}"
340
+ print "added: #{val + 2}"
170
341
  end
171
- end
172
-
173
- App.start(HelloWorld)
342
+ end
343
+
344
+ App.start(HelloWorld)
174
345
 
175
- Now, point your browser to localhost:/ or localhost/add?val=2
176
-
177
- If you need the advanced controller functionality just extend
178
- your published object from the Controller base class. The normal
179
- heuristics to decide which method is safe to publish are aplied.
346
+ Now, point your browser to localhost:/ or localhost/add?val=2
347
+
348
+ If you need the advanced controller functionality just extend
349
+ your published object from the Controller base class. The normal
350
+ heuristics to decide which method is safe to publish are aplied.
180
351
 
181
352
  * CherryPy-style dispatcher configuration, provides another way
182
- to define mounting points for Controllers and published objects.
183
- Here is an example:
184
-
185
- server = Server.new
186
- server.root = MainController # /
187
- server.root.fora = ForaController # /fora
188
- server.root.wiki = WikiController # /wiki
189
- server.root.really.deep = DeepController # /really/deap
353
+ to define mounting points for Controllers and published objects.
354
+ Here is an example:
355
+
356
+ server = Server.new
357
+ server.root = MainController # /
358
+ server.root.fora = ForaController # /fora
359
+ server.root.wiki = WikiController # /wiki
360
+ server.root.really.deep = DeepController # /really/deap
190
361
 
191
362
  * Improved pager interface. Thanks to the new PagerMixin, presenting
192
- paged lists is easier (and as efficient) than ever:
193
-
194
- items, pager = paginate(Article, :per_page => 5, :order => 'date DESC')
195
-
363
+ paged lists is easier (and as efficient) than ever:
364
+
365
+ items, pager = paginate(Article, :per_page => 5, :order => 'date DESC')
366
+
196
367
  * Added better sql injection protection in Og sql stores.
197
368
 
198
369
  * Fixed Mysql store reconnect bug.
199
370
 
200
371
  * Og falls back to pure ruby adapters for Mysql and Postgres, to
201
- make it easier to run out of the box. Please, don't forget to
202
- switch to the natively compiled adapters for production sites.
372
+ make it easier to run out of the box. Please, don't forget to
373
+ switch to the natively compiled adapters for production sites.
203
374
 
204
375
  * This is surely the most request feature: Nitro Step by Step
205
- by James Britt, a beginers guide to Nitro. Available in the
206
- brand-new, Nitro-powered, www.nitrohq.com Community wiki.
376
+ by James Britt, a beginers guide to Nitro. Available in the
377
+ brand-new, Nitro-powered, www.nitrohq.com Community wiki.
207
378
 
208
379
  * New examples: The totaly recoded and ultra cool ajax example,
209
- a Wee/Nitro example and the new Hello world example.
380
+ a Wee/Nitro example and the new Hello world example.
210
381
 
211
382
  * Cleaned up a lot of source files.
212
-
383
+
213
384
  * Many, many, many bug fixes and small improvements. This release
214
- fixes all reported bugs in the spirit of out zero-bug tolerance
215
- philosophy.
216
-
385
+ fixes all reported bugs in the spirit of out zero-bug tolerance
386
+ philosophy.
387
+
217
388
 
218
389
  == Version 0.19.0
219
390
 
@@ -224,141 +395,141 @@ fixes.
224
395
  Some notable changes:
225
396
 
226
397
  * Og polymorphic relations. A groundbreaking feature made possible
227
- by Og's unique design and Ruby's power. Let's use an example
228
- to explain the concept:
229
-
230
- class Comment
231
- ...
232
- belongs_to Object # polymorphic marker
233
- end
234
-
235
- class User
236
- ...
237
- has_many Comment
238
- end
239
-
240
- class Article
241
- ...
242
- has_many Comment
243
- end
244
-
245
- u = User.new
246
- u.comments << User::Comment('Hello')
247
-
248
- a = Article.new
249
- a.comments << Article::Comment('Wow!')
250
-
251
- User::Comment and Article::Comment where automatically created
252
- by Og and are serialized in different tables (also automatically
253
- created by Og). This is the next step in DRY!
398
+ by Og's unique design and Ruby's power. Let's use an example
399
+ to explain the concept:
400
+
401
+ class Comment
402
+ ...
403
+ belongs_to Object # polymorphic marker
404
+ end
405
+
406
+ class User
407
+ ...
408
+ has_many Comment
409
+ end
410
+
411
+ class Article
412
+ ...
413
+ has_many Comment
414
+ end
415
+
416
+ u = User.new
417
+ u.comments << User::Comment('Hello')
418
+
419
+ a = Article.new
420
+ a.comments << Article::Comment('Wow!')
421
+
422
+ User::Comment and Article::Comment where automatically created
423
+ by Og and are serialized in different tables (also automatically
424
+ created by Og). This is the next step in DRY!
254
425
 
255
426
  * Og now supports inheritance using the well known Single Table
256
- Inheritance pattern. Thanks to Og's advanced design the pattern
257
- is fully encapsulated:
258
-
259
- class Document
260
- ...
261
- schema_inheritance
262
- end
263
-
264
- class Article < Document
265
- ..
266
- end
267
-
268
- class Photo < Document
269
- ..
270
- end
271
-
272
- Document.all # => includes Articles and Photos
273
- Article.all # => only Articles
274
-
275
- User.documents # => Articles and Photos
276
- User.documents(:type => Photo) # => only photos.
277
-
278
- Btw, this feature is orthogonal to the polymorphic relations
279
- feature just described, giving the developer great
280
- flexibility.
427
+ Inheritance pattern. Thanks to Og's advanced design the pattern
428
+ is fully encapsulated:
429
+
430
+ class Document
431
+ ...
432
+ schema_inheritance
433
+ end
434
+
435
+ class Article < Document
436
+ ..
437
+ end
438
+
439
+ class Photo < Document
440
+ ..
441
+ end
442
+
443
+ Document.all # => includes Articles and Photos
444
+ Article.all # => only Articles
445
+
446
+ User.documents # => Articles and Photos
447
+ User.documents(:type => Photo) # => only photos.
448
+
449
+ Btw, this feature is orthogonal to the polymorphic relations
450
+ feature just described, giving the developer great
451
+ flexibility.
281
452
 
282
453
  * Added SUPERB support for auto reloading, the new system
283
- can detect source changes everywhere! Based on original
284
- code by Michael Neumann.
285
-
454
+ can detect source changes everywhere! Based on original
455
+ code by Michael Neumann.
456
+
286
457
  * Introduced the concept of Flash, a temporal store where
287
- objects that should be kept alive for the next request are
288
- saved.
458
+ objects that should be kept alive for the next request are
459
+ saved.
289
460
 
290
461
  * Recoded the Blog example to use the Elements system for
291
- shading instead of XSLT. The new code runs easier under Windows
292
- (so the no_xsl_blog example is now removed). Here comes an
293
- example:
294
-
295
- <Page>
296
- <Box>
297
- Please login as an author by entering the blog password.
298
- <br />
299
- The password is: <b>#{Blog.password}</b>.
300
- </Box>
301
-
302
- <Error>#@error</Error>
303
- ...
304
- </Page>
305
-
306
- The <Page> tag is supported by the Page Ruby class to do the
307
- programmatic rendering of templates or logic code:
308
-
309
- class Page
310
- def render
311
- ...
312
- end
313
- end
314
-
315
- This system can be used to create a library of useful
316
- components to abstract common tasks.
317
-
462
+ shading instead of XSLT. The new code runs easier under Windows
463
+ (so the no_xsl_blog example is now removed). Here comes an
464
+ example:
465
+
466
+ <Page>
467
+ <Box>
468
+ Please login as an author by entering the blog password.
469
+ <br />
470
+ The password is: <b>#{Blog.password}</b>.
471
+ </Box>
472
+
473
+ <Error>#@error</Error>
474
+ ...
475
+ </Page>
476
+
477
+ The <Page> tag is supported by the Page Ruby class to do the
478
+ programmatic rendering of templates or logic code:
479
+
480
+ class Page
481
+ def render
482
+ ...
483
+ end
484
+ end
485
+
486
+ This system can be used to create a library of useful
487
+ components to abstract common tasks.
488
+
318
489
  * The updated Blog example demonstrates how easy it is to write
319
- webservices using Nitro and the experimental Service feature.
320
- The code is so short, so lets paste it here:
321
-
322
- module BloggerApi
323
- SBlog = Struct.new(:url, :blogid, :blogName)
324
-
325
- def blogger__getUsersBlogs(appkey, username, password)
326
- Blog.all.collect { |b| SBlog.new('http://www.gmosx.com', b.oid, b.title) }
327
- end
328
- end
329
-
330
- module MetaWeblogApi
331
- def metaWeblog__newPost(blogid, username, password, content, publish)
332
- entry = BlogEntry.new(content['title'], content['description'])
333
- entry.blog = Blog[blogid]
334
- entry.save
335
- entry.oid
336
- end
337
- end
338
-
339
- module MovableTypeApi
340
- SCategory = Struct.new(:categoryId, :categoryName)
341
-
342
- def mt__getCategoryList(blogid, username, password)
343
- blog = Blog[blogid]
344
- blog.categories.collect { |c| SCategory.new(c.oid, c.title) }
345
- end
346
-
347
- def mt__setPostCategories(postid, username, password, categories)
348
- cid = categories.first['categoryId']
349
- BlogEntry.update(postid, "category_oid=#{cid}")
350
- true
351
- end
352
- end
353
-
354
- class ApiController < Nitro::XmlRpcService
355
- include BloggerApi
356
- include MovableTypeApi
357
- include MetaWeblogApi
358
- end
359
-
360
- That's all!
361
-
490
+ webservices using Nitro and the experimental Service feature.
491
+ The code is so short, so lets paste it here:
492
+
493
+ module BloggerApi
494
+ SBlog = Struct.new(:url, :blogid, :blogName)
495
+
496
+ def blogger__getUsersBlogs(appkey, username, password)
497
+ Blog.all.collect { |b| SBlog.new('http://www.gmosx.com', b.oid, b.title) }
498
+ end
499
+ end
500
+
501
+ module MetaWeblogApi
502
+ def metaWeblog__newPost(blogid, username, password, content, publish)
503
+ entry = BlogEntry.new(content['title'], content['description'])
504
+ entry.blog = Blog[blogid]
505
+ entry.save
506
+ entry.oid
507
+ end
508
+ end
509
+
510
+ module MovableTypeApi
511
+ SCategory = Struct.new(:categoryId, :categoryName)
512
+
513
+ def mt__getCategoryList(blogid, username, password)
514
+ blog = Blog[blogid]
515
+ blog.categories.collect { |c| SCategory.new(c.oid, c.title) }
516
+ end
517
+
518
+ def mt__setPostCategories(postid, username, password, categories)
519
+ cid = categories.first['categoryId']
520
+ BlogEntry.update(postid, "category_oid=#{cid}")
521
+ true
522
+ end
523
+ end
524
+
525
+ class ApiController < Nitro::XmlRpcService
526
+ include BloggerApi
527
+ include MovableTypeApi
528
+ include MetaWeblogApi
529
+ end
530
+
531
+ That's all!
532
+
362
533
  * Integrated an SQLite3 patch by Ghislain Mary.
363
534
 
364
535
  * Integrated PostgreSQL binary data patch by Michael Neumann.
@@ -377,41 +548,41 @@ patches.
377
548
  Some notable changes:
378
549
 
379
550
  * Some changes to make Webrick a valid solution for powering
380
- a production server. The full page output caching was improved
381
- and support for daemonizing the server was added. Support
382
- for running as a proxy target (behind an apache server) was also
383
- added.
384
-
551
+ a production server. The full page output caching was improved
552
+ and support for daemonizing the server was added. Support
553
+ for running as a proxy target (behind an apache server) was also
554
+ added.
555
+
385
556
  * Thread safe mode was added again in Og. This works nice with
386
- the Webrick server.
387
-
557
+ the Webrick server.
558
+
388
559
  * New order macro in Og to set default ordering for each
389
- entity. The has_many collections respects the order setting.
390
-
560
+ entity. The has_many collections respects the order setting.
561
+
391
562
  * Improved error reporting.
392
563
 
393
564
  * Support for template_root overloading. Lets say you have
394
- the following Controller hierarchy:
395
-
396
- Controller > MyController > SpecificController.
397
-
398
- The template roots of the 3 controller are searched in reverse
399
- order. So by adding a template file in the SpecificController
400
- template root you can override a default action in the base
401
- Controller. For convienience the base Controller points to
402
- the Proto directory. This is experimental.
565
+ the following Controller hierarchy:
566
+
567
+ Controller > MyController > SpecificController.
568
+
569
+ The template roots of the 3 controller are searched in reverse
570
+ order. So by adding a template file in the SpecificController
571
+ template root you can override a default action in the base
572
+ Controller. For convienience the base Controller points to
573
+ the Proto directory. This is experimental.
403
574
 
404
575
  * Provide the examples as a separate distribution to make it
405
- easier for Ruby newbies to find them.
576
+ easier for Ruby newbies to find them.
406
577
 
407
578
  * Bug fixes in the Elements system.
408
579
 
409
580
  * Improved the nitrogen generator command. Just run
410
581
 
411
- nitrogen app ~/the/target/path
412
-
413
- to create a skeleton application.
414
-
582
+ nitrogen app ~/the/target/path
583
+
584
+ to create a skeleton application.
585
+
415
586
  * Cleaned up some source files.
416
587
 
417
588
 
@@ -427,132 +598,132 @@ list for ideas and suggestions that made this version possible.
427
598
  Most notable Og additions:
428
599
 
429
600
  * Extremely clean source code. Better names are used thorougout.
430
- Extra care was taken to make all features more orthogonal.
431
-
601
+ Extra care was taken to make all features more orthogonal.
602
+
432
603
  * Brand new relation mechanism. The 'enchanting' of entities
433
- (managed classes) happens in multiple passes to be more
434
- flexible. Totaly separated graph/metadata creation and serialization
435
- code generation. The Graph metadata can be used for advanced
436
- scaffolding, testing and more.
604
+ (managed classes) happens in multiple passes to be more
605
+ flexible. Totaly separated graph/metadata creation and serialization
606
+ code generation. The Graph metadata can be used for advanced
607
+ scaffolding, testing and more.
437
608
 
438
609
  * Support for fully customizable primary keys. You are no longer
439
- forced to use xxx_oid primary keys. Appart from the extra
440
- flexibility this feature provides, this is an essential step
441
- towards the planed 'reverse engineering' mode that will allow the
442
- use of existing schemas with Og.
443
-
610
+ forced to use xxx_oid primary keys. Appart from the extra
611
+ flexibility this feature provides, this is an essential step
612
+ towards the planed 'reverse engineering' mode that will allow the
613
+ use of existing schemas with Og.
614
+
444
615
  * More elegant inspection mechanism. Example:
445
616
 
446
- Article.relation(:user) # => Og::BelongsTo(...)
447
- Article.relations # => [...]
448
- Article.properties # => [...]
617
+ Article.relation(:user) # => Og::BelongsTo(...)
618
+ Article.relations # => [...]
619
+ Article.properties # => [...]
449
620
 
450
621
  * Joins_many relation, as an alias for one way, join table relations.
451
622
 
452
623
  * Support for 'active' collections. Active collection are
453
- synchronized with the backend Store and provide a more elegant
454
- interface and the opportunity for 'session' caching:
455
-
456
- article.comments << Comment.new
457
-
458
- instead of
459
-
460
- article.add_comment(Comment.new) # this is also allowed though.
461
-
462
- p article.comments
463
- p article.comments.size # the results of the first query is cached
624
+ synchronized with the backend Store and provide a more elegant
625
+ interface and the opportunity for 'session' caching:
626
+
627
+ article.comments << Comment.new
628
+
629
+ instead of
630
+
631
+ article.add_comment(Comment.new) # this is also allowed though.
632
+
633
+ p article.comments
634
+ p article.comments.size # the results of the first query is cached
464
635
 
465
636
  * Eager relations.
466
637
 
467
- comments = Article.comments(:include => User)
638
+ comments = Article.comments(:include => User)
468
639
 
469
- for comment in comments
470
- p comment.user.name
471
- end
472
-
473
- Elegantly solves the N+1 query problem by using one join
474
- query.
640
+ for comment in comments
641
+ p comment.user.name
642
+ end
643
+
644
+ Elegantly solves the N+1 query problem by using one join
645
+ query.
475
646
 
476
647
  * No need for forward references when defining relations. Now,
477
- the following code magically works:
478
-
479
- class User
480
- has_many Comment # works even though Comment is not defined!
481
- end
482
-
483
- class Comment
484
- belongs_to User
485
- end
486
-
648
+ the following code magically works:
649
+
650
+ class User
651
+ has_many Comment # works even though Comment is not defined!
652
+ end
653
+
654
+ class Comment
655
+ belongs_to User
656
+ end
657
+
487
658
  * Use inflection where possible to infer missing configuration
488
- options. For example
489
-
490
- class Article
491
- belongs_to User # infects relation name :user
492
- ...
493
-
659
+ options. For example
660
+
661
+ class Article
662
+ belongs_to User # infects relation name :user
663
+ ...
664
+
494
665
  * New, lean and mean Store interface. The code needed to teach
495
- Og how to serialize objects to backend store is dramatically
496
- reduced. The new interface is SQL agnostic, so non SQL-RDBM's
497
- stores are possible.
498
-
666
+ Og how to serialize objects to backend store is dramatically
667
+ reduced. The new interface is SQL agnostic, so non SQL-RDBM's
668
+ stores are possible.
669
+
499
670
  * SQL agnostic querying interface, compatible with non-sql
500
- Stores. Here is an example:
501
-
502
- Article.find(
503
- :condition => 'hits > 2 AND rate > 3',
504
- :order => 'title',
505
- :offset => 30,
506
- :limit => 10
507
- )
671
+ Stores. Here is an example:
672
+
673
+ Article.find(
674
+ :condition => 'hits > 2 AND rate > 3',
675
+ :order => 'title',
676
+ :offset => 30,
677
+ :limit => 10
678
+ )
508
679
 
509
680
  * More elegant (and non-sql store compatible) way for selective
510
- updates:
681
+ updates:
511
682
 
512
- article.title = 'Changed'
513
- article.hits += 1
514
- article.update(:title, :hits)
683
+ article.title = 'Changed'
684
+ article.hits += 1
685
+ article.update(:title, :hits)
515
686
 
516
687
  * New, in-memory store that support all features. This is a pure
517
- ruby solution useful for experimentation. It will also serve
518
- as the base for the forthcoming madeleine Store implementation.
688
+ ruby solution useful for experimentation. It will also serve
689
+ as the base for the forthcoming madeleine Store implementation.
519
690
 
520
691
  * Allow for multiple stores in one application. A great example,
521
- mysql_to_psql is provided. This example uses Og's powerfull
522
- features to automatically convert a Mysql database to a
523
- PostgreSQL database. Database migration was never easier.
524
-
692
+ mysql_to_psql is provided. This example uses Og's powerfull
693
+ features to automatically convert a Mysql database to a
694
+ PostgreSQL database. Database migration was never easier.
695
+
525
696
  * Uses the excellent Facets utility collection to further
526
- clenup and minimize the code.
697
+ clenup and minimize the code.
527
698
 
528
699
  * Managed classes or Entities should include the EntityMixin
529
- or extend the Entity class. Example:
530
-
531
- class Article < Entity
532
- ..
533
- end
534
-
535
- class Article
536
- include EntityMixin
537
- end
538
-
539
- This is done to avoid the Module module like in earlier
540
- versions of Og. However, Og is can infer the need to include
541
- the Managed mixin in typical cases:
542
-
543
- class Article
544
- property :title, String
545
- # when a property is defined Og automatically converts the
546
- # class to an Entity
547
- end
548
-
549
- class Article < AnExistingManagedEntity
550
- # also includes the mixin
551
- ...
552
-
553
- class Article
554
- include AModuleThatDefinesProperties
555
- ...
700
+ or extend the Entity class. Example:
701
+
702
+ class Article < Entity
703
+ ..
704
+ end
705
+
706
+ class Article
707
+ include EntityMixin
708
+ end
709
+
710
+ This is done to avoid the Module module like in earlier
711
+ versions of Og. However, Og is can infer the need to include
712
+ the Managed mixin in typical cases:
713
+
714
+ class Article
715
+ property :title, String
716
+ # when a property is defined Og automatically converts the
717
+ # class to an Entity
718
+ end
719
+
720
+ class Article < AnExistingManagedEntity
721
+ # also includes the mixin
722
+ ...
723
+
724
+ class Article
725
+ include AModuleThatDefinesProperties
726
+ ...
556
727
 
557
728
  * Improved support for og_delete interception.
558
729
 
@@ -564,35 +735,35 @@ the new features.
564
735
  And some Nitro additions:
565
736
 
566
737
  * Integrated the Facets library, and started donating some Glue
567
- code to this project.
568
-
738
+ code to this project.
739
+
569
740
  * Integrated the Prototype object oriented javascript library.
570
741
 
571
742
  * Included a preview implementation of the new tag library
572
- system, called Elements. This is based on an original idea
573
- by Dan Yoder. This feature is expected to change substantially
574
- in the next version. In the meantime here is an example:
575
-
576
- <Page>
577
- Here is a <b>nice</b> page.
578
- <br />
579
- <Box>
580
- This is #{variable}.
581
- <?r if admin ?>
582
- hello admin
583
- <?r end ?>
584
- </Box>
585
- </Page>
586
-
587
- The tags <Page> and <Box> automatically instantiate objects
588
- of class Page and Box that handle the rendering. This is an
589
- alternative to the XSLT templating system and can also be used
590
- to implement some reusable components. The hierarchical structure
591
- of the elements is available to each object to facilitate
592
- advanced rendering tricks. Just like the XSLT shader the Elements
593
- transformation is preapplied to the page to avoid the overhead
594
- at runtime.
595
-
743
+ system, called Elements. This is based on an original idea
744
+ by Dan Yoder. This feature is expected to change substantially
745
+ in the next version. In the meantime here is an example:
746
+
747
+ <Page>
748
+ Here is a <b>nice</b> page.
749
+ <br />
750
+ <Box>
751
+ This is #{variable}.
752
+ <?r if admin ?>
753
+ hello admin
754
+ <?r end ?>
755
+ </Box>
756
+ </Page>
757
+
758
+ The tags <Page> and <Box> automatically instantiate objects
759
+ of class Page and Box that handle the rendering. This is an
760
+ alternative to the XSLT templating system and can also be used
761
+ to implement some reusable components. The hierarchical structure
762
+ of the elements is available to each object to facilitate
763
+ advanced rendering tricks. Just like the XSLT shader the Elements
764
+ transformation is preapplied to the page to avoid the overhead
765
+ at runtime.
766
+
596
767
  * Fixed many reported bugs.
597
768
 
598
769
 
@@ -605,45 +776,45 @@ James Britt for significantly contributing to this release.
605
776
  Most notable additions:
606
777
 
607
778
  * Aspect Oriented Programming support. This new system
608
- is used to reimplement features such as Controller filters,
609
- Og callbacks and Og observers. By using this unified
610
- system you can now add Observers to controllers and use
611
- a metalanguage for wraping Og object callbacks:
612
-
613
- class Controller
614
- pre :force_login, :where => :prepend
615
- wrap Benchmark, :on => :index
616
- post :taraa, :on => login
617
- end
779
+ is used to reimplement features such as Controller filters,
780
+ Og callbacks and Og observers. By using this unified
781
+ system you can now add Observers to controllers and use
782
+ a metalanguage for wraping Og object callbacks:
783
+
784
+ class Controller
785
+ pre :force_login, :where => :prepend
786
+ wrap Benchmark, :on => :index
787
+ post :taraa, :on => login
788
+ end
618
789
 
619
- module Timestamped
620
- pre :on => :og_insert { |this| this.create_time = Time.now }
621
- pre :on => :og_update { |this| this.update_time = Time.now }
622
- pre :on => [:og_insert, :og_update] { |this| this.create_time = Time.now }
623
- end
790
+ module Timestamped
791
+ pre :on => :og_insert { |this| this.create_time = Time.now }
792
+ pre :on => :og_update { |this| this.update_time = Time.now }
793
+ pre :on => [:og_insert, :og_update] { |this| this.create_time = Time.now }
794
+ end
624
795
 
625
- This feature will be used extensivelly in future versions
626
- to improve logging, the shaders and more.
796
+ This feature will be used extensivelly in future versions
797
+ to improve logging, the shaders and more.
627
798
 
628
799
  * Added support for Test Driven Development. Many helpers
629
- and utility methods are added to the standard TestCase
630
- class, more will come in a future version:
631
-
632
- handle(
633
- '/login',
634
- request = { 'password' => Blog.password }
635
- )
636
- assert_redirect
637
- assert_session_has(:owner)
638
- assert_session_equal(:username, 'George Moschovitis')
639
- assert_has_cookie('nauth')
640
- assert_has_no_cookie('wow')
641
- assert_cookie_equal('nauth', 'just an example, not used :)')
800
+ and utility methods are added to the standard TestCase
801
+ class, more will come in a future version:
802
+
803
+ handle(
804
+ '/login',
805
+ request = { 'password' => Blog.password }
806
+ )
807
+ assert_redirect
808
+ assert_session_has(:owner)
809
+ assert_session_equal(:username, 'George Moschovitis')
810
+ assert_has_cookie('nauth')
811
+ assert_has_no_cookie('wow')
812
+ assert_cookie_equal('nauth', 'just an example, not used :)')
642
813
 
643
814
  * CGI adapter (by James Britt)
644
815
 
645
816
  * Major cleanup of the source. Converted the N namespace to
646
- Nitro, to be more compatible with other Ruby projects.
817
+ Nitro, to be more compatible with other Ruby projects.
647
818
 
648
819
  * Add Og Timestamped mixin.
649
820
 
@@ -668,17 +839,17 @@ Most notable additions:
668
839
 
669
840
  * Advanced localization support:
670
841
 
671
- locale_en = {
672
- 'See you' => 'See you',
673
- :long_paragraph => 'The best new books, up to 30% reduced price',
674
- :price => 'Price: %d %s',
675
- :proc_price => proc { |value, cur| "Price: #{value} #{cur}" }
676
- }
842
+ locale_en = {
843
+ 'See you' => 'See you',
844
+ :long_paragraph => 'The best new books, up to 30% reduced price',
845
+ :price => 'Price: %d %s',
846
+ :proc_price => proc { |value, cur| "Price: #{value} #{cur}" }
847
+ }
677
848
 
678
- locale_de = {
679
- 'See you' => 'Auf wieder sehen',
680
- ...
681
- }
849
+ locale_de = {
850
+ 'See you' => 'Auf wieder sehen',
851
+ ...
852
+ }
682
853
 
683
854
  lc = Localization.get
684
855
  lc['See you'] -> See you
@@ -688,8 +859,8 @@ Most notable additions:
688
859
 
689
860
  Using the LocalizationShader you can have templates like this:
690
861
 
691
- <h1>[[This is a localized]] String</h1>
692
- <p>
862
+ <h1>[[This is a localized]] String</h1>
863
+ <p>
693
864
  do you [[:like]] this?
694
865
  </p>
695
866
 
@@ -698,12 +869,12 @@ Most notable additions:
698
869
  blog example.
699
870
 
700
871
  * Dynamic/Parametrised mixins. A great extension to Ruby's mixin
701
- feature. The Og::list implementation is replaced with the new
872
+ feature. The Og::list implementation is replaced with the new
702
873
  Orderable dynamic mixin, here is an example:
703
874
 
704
875
  class Comment
705
876
  property :body, String
706
- belongs_to :article, Article
877
+ belongs_to :article, Article
707
878
  include Orderable, :scope => article
708
879
  end
709
880
 
@@ -716,22 +887,22 @@ Most notable additions:
716
887
  * NestedSets mixin:
717
888
 
718
889
  class Comment
719
- include NestedSets
720
- end
890
+ include NestedSets
891
+ end
721
892
 
722
- or
893
+ or
723
894
 
724
- class Comment
725
- include Hierarchical, :method => :nested_sets
726
- end
895
+ class Comment
896
+ include Hierarchical, :method => :nested_sets
897
+ end
727
898
 
728
- c.add_comment(child_comment)
729
- c.full_children
730
- c.direct_children
731
- c.children
899
+ c.add_comment(child_comment)
900
+ c.full_children
901
+ c.direct_children
902
+ c.children
732
903
 
733
- this is a reimplementation of the SqlTraversable mixin
734
- available in older versions.
904
+ this is a reimplementation of the SqlTraversable mixin
905
+ available in older versions.
735
906
 
736
907
  * Improved templating system. Now allows <% %> intrerpolators
737
908
  and provides a number of html morphing effects:
@@ -742,9 +913,9 @@ Most notable additions:
742
913
 
743
914
  <ul>
744
915
  <li each="u in @users">#{u.first_name} #{u.last_name}
745
- </ul>
916
+ </ul>
746
917
 
747
- and more...
918
+ and more...
748
919
 
749
920
  * Og provides an SqlServer adapter out of the box.
750
921
 
@@ -770,65 +941,65 @@ Most notable additions:
770
941
  whole pages (output caching), actions and fine-grained
771
942
  fragments.
772
943
 
773
- class MyController < Controller
774
- cache_output :my_action
944
+ class MyController < Controller
945
+ cache_output :my_action
775
946
 
776
- def my_action
777
- end
778
- end
947
+ def my_action
948
+ end
949
+ end
779
950
 
780
- Stores the whole page created by the my_action method
781
- to the disk to be displayed by the web server thus completely
782
- Nitro and Ruby.
951
+ Stores the whole page created by the my_action method
952
+ to the disk to be displayed by the web server thus completely
953
+ Nitro and Ruby.
783
954
 
784
- or
955
+ or
785
956
 
786
- <strong>Here is some cached code</strong>
787
- <cache>
788
- <ul>
789
- <?r for a in Article.all ?>
790
- <li>#{a.title}: #{a.body}</li>
791
- <?r end ?>
792
- </ul>
793
- </cache>
957
+ <strong>Here is some cached code</strong>
958
+ <cache>
959
+ <ul>
960
+ <?r for a in Article.all ?>
961
+ <li>#{a.title}: #{a.body}</li>
962
+ <?r end ?>
963
+ </ul>
964
+ </cache>
794
965
 
795
- or
966
+ or
796
967
 
797
- <strong>Another one</strong>
798
- <?r cache('variant', :admin => session[:admin]) do ?>
799
- ...
800
- <?r end ?>
968
+ <strong>Another one</strong>
969
+ <?r cache('variant', :admin => session[:admin]) do ?>
970
+ ...
971
+ <?r end ?>
801
972
 
802
- Cached fragments can be stored in memory, filesystem.
973
+ Cached fragments can be stored in memory, filesystem.
803
974
 
804
- While this feature is fully operational, the API will be finalised in
805
- the next version.
975
+ While this feature is fully operational, the API will be finalised in
976
+ the next version.
806
977
 
807
978
  * Introduced support for Og mixins. In this version a List
808
- mixin is provided:
979
+ mixin is provided:
809
980
 
810
981
  class Article
811
- has_many :comments, Comment, :order => 'position DESC'
812
- end
982
+ has_many :comments, Comment, :order => 'position DESC'
983
+ end
813
984
 
814
- class Comment
815
- belongs_to :article, Article
816
- acts_as_list :scope => :article
817
- end
985
+ class Comment
986
+ belongs_to :article, Article
987
+ acts_as_list :scope => :article
988
+ end
818
989
 
819
- An AR compatible API is provided. An alternative
820
- API is planned for the near future to give you more choice.
990
+ An AR compatible API is provided. An alternative
991
+ API is planned for the near future to give you more choice.
821
992
 
822
993
  * Reimplemented filtering infrastructure, allows
823
994
  for inheritance, conditional application of filters
824
995
  (:only/:except) modifiers, more performant Filters
825
- as Strings and more.
996
+ as Strings and more.
826
997
 
827
998
  * Fixed multipart support in fastcgi, added file upload
828
999
  example (tiny example).
829
1000
 
830
1001
  * The webrick adapter reuses the fastcgi infrastructure, making
831
- the adapters more compatible with each other.
1002
+ the adapters more compatible with each other.
832
1003
 
833
1004
  * Added many useful Og enchant methods.
834
1005
 
@@ -850,35 +1021,35 @@ and an AJAX example are also included.
850
1021
 
851
1022
  * Introduced Mailer subsystem:
852
1023
 
853
- class MyMailer < Mailer
854
- def registration_email(to, username, password)
855
- @from = 'system@navel.gr'
856
- @to = to
857
- @subject = 'Registration information'
858
- @body.username = username
859
- @body.password = password
860
- end
861
- end
1024
+ class MyMailer < Mailer
1025
+ def registration_email(to, username, password)
1026
+ @from = 'system@navel.gr'
1027
+ @to = to
1028
+ @subject = 'Registration information'
1029
+ @body.username = username
1030
+ @body.password = password
1031
+ end
1032
+ end
862
1033
 
863
1034
  the tempate (registration_email.xhtml):
864
1035
 
865
- Hello #{username}
1036
+ Hello #{username}
866
1037
 
867
1038
  Thanks for registering, your password is '#{password}'
868
1039
 
869
- Then use it like this:
1040
+ Then use it like this:
870
1041
 
871
- MyMailer.deliver_registration_email('gmosx@navel.gr', 'gmosx', 'rulez')
1042
+ MyMailer.deliver_registration_email('gmosx@navel.gr', 'gmosx', 'rulez')
872
1043
 
873
- For more information, check out the updated blog example.
1044
+ For more information, check out the updated blog example.
874
1045
 
875
1046
  * AJAX example, demonstrates how to use ajax techniques with
876
- Nitro. A simple Google Suggest style UI is implemented.
1047
+ Nitro. A simple Google Suggest style UI is implemented.
877
1048
 
878
1049
  * Use a Rails compatible directory structure. Check out
879
- the updated blog example. Please note that Nitro does not
880
- force a directory structure (see an alternative structure
881
- in the no_xsl_blog example).
1050
+ the updated blog example. Please note that Nitro does not
1051
+ force a directory structure (see an alternative structure
1052
+ in the no_xsl_blog example).
882
1053
 
883
1054
  * Optional separate template_root/public_root for extra security.
884
1055
 
@@ -894,82 +1065,82 @@ fixed aswell.
894
1065
  Most notable additions:
895
1066
 
896
1067
  * Nitro allows the definition of metadata for each action.
897
- Routing (rewrite) rules, parameter constrains, hierarchy information
898
- and custom data can easily be attached to actions:
1068
+ Routing (rewrite) rules, parameter constrains, hierarchy information
1069
+ and custom data can easily be attached to actions:
899
1070
 
900
- def view
901
- @entry = Article[@oid]
902
- end
903
- action :view, :route => /view\/(.*)/, 'oid' => 1
1071
+ def view
1072
+ @entry = Article[@oid]
1073
+ end
1074
+ action :view, :route => /view\/(.*)/, 'oid' => 1
904
1075
 
905
- just browse
1076
+ just browse
906
1077
 
907
- view/1
1078
+ view/1
908
1079
 
909
- and @oid is automatically initialized with request['oid']
1080
+ and @oid is automatically initialized with request['oid']
910
1081
 
911
- Browse the source to see how to add additional constrains,
912
- more is comming in the next version. This feature replaces
913
- the non portable ParseTree implementation. The scaffolder
914
- is updated to generate routings for nice urls.
1082
+ Browse the source to see how to add additional constrains,
1083
+ more is comming in the next version. This feature replaces
1084
+ the non portable ParseTree implementation. The scaffolder
1085
+ is updated to generate routings for nice urls.
915
1086
 
916
1087
  * Og automatically generates finders for all properties, for
917
- even easier (and portable) querying:
1088
+ even easier (and portable) querying:
918
1089
 
919
- class Article
920
- property :title, :body, String
921
- property :hits, Fixnum
922
- property :create_time, Time
923
- end
1090
+ class Article
1091
+ property :title, :body, String
1092
+ property :hits, Fixnum
1093
+ property :create_time, Time
1094
+ end
924
1095
 
925
- you get the finders:
1096
+ you get the finders:
926
1097
 
927
- Article.find_by_title
928
- Article.find_by_body
929
- Article.find_by_hits
930
- Article.find_by_create_time
1098
+ Article.find_by_title
1099
+ Article.find_by_body
1100
+ Article.find_by_hits
1101
+ Article.find_by_create_time
931
1102
 
932
- The finders take into account the unique constrain, to return
933
- an array or just an object as needed.
1103
+ The finders take into account the unique constrain, to return
1104
+ an array or just an object as needed.
934
1105
 
935
1106
  * Og introduces lifecycle observers to avoid 'poluting' the model
936
- objects with excess functionality. You can use every object
937
- as observer (duck typing) or extend from an AR style Observer
938
- class. The observer callbacks are precompiled in the lifecycle
939
- methods only if defined, so the perfomance is not affected
940
- in the general case.
1107
+ objects with excess functionality. You can use every object
1108
+ as observer (duck typing) or extend from an AR style Observer
1109
+ class. The observer callbacks are precompiled in the lifecycle
1110
+ methods only if defined, so the perfomance is not affected
1111
+ in the general case.
941
1112
 
942
1113
  * Factored out templating engine, can now be used in stand-alone
943
- mode. Usefull for example to render email templates etc:
1114
+ mode. Usefull for example to render email templates etc:
944
1115
 
945
- template = %q{
946
- Hello #{user}
1116
+ template = %q{
1117
+ Hello #{user}
947
1118
 
948
- dont forget the following facts:
949
-
950
- <?r for item in items ?>
951
- <li>#{item}</li>
952
- <?r end ?>
953
- }
1119
+ dont forget the following facts:
1120
+
1121
+ <?r for item in items ?>
1122
+ <li>#{item}</li>
1123
+ <?r end ?>
1124
+ }
954
1125
 
955
- user = 'gmosx'
956
- items = %w{ nitro is really great }
957
- out = '' # the rendered template comes here.
1126
+ user = 'gmosx'
1127
+ items = %w{ nitro is really great }
1128
+ out = '' # the rendered template comes here.
958
1129
 
959
- Template.process(template, :out, binding)
1130
+ Template.process(template, :out, binding)
960
1131
 
961
1132
  * New options in the default runner:
962
-
963
- --render crawls a web application and renders all pages
964
- as static html files. Allows you to leverage Nitro's
965
- advanced templating features to generate static sites.
1133
+
1134
+ --render crawls a web application and renders all pages
1135
+ as static html files. Allows you to leverage Nitro's
1136
+ advanced templating features to generate static sites.
966
1137
 
967
- --crawl spiders the application, useful for testing.
1138
+ --crawl spiders the application, useful for testing.
968
1139
 
969
1140
  * Better error page, with more information (see blog example).
970
1141
 
971
1142
  * Fixed Og bug: multiple many_to_many relations with the
972
- same target class.
1143
+ same target class.
973
1144
 
974
1145
  * further code cleanup, improved examples and more.
975
1146
 
@@ -988,73 +1159,73 @@ Most notable additions:
988
1159
  * Configuration files for Apache/FastCGI.
989
1160
 
990
1161
  * Og documentation (doc/og_tutorial.txt, doc/og_config.txt)
991
-
1162
+
992
1163
  * Actions with parameters:
993
1164
 
994
1165
  def list(username, oid)
995
- ...
996
- end
1166
+ ...
1167
+ end
997
1168
 
998
- http://www.mysite.com/list?username=tml;oid=2
1169
+ http://www.mysite.com/list?username=tml;oid=2
999
1170
 
1000
1171
  calls list() with the correct parameters, no need to
1001
- use request['oid'], just use oid.
1172
+ use request['oid'], just use oid.
1002
1173
 
1003
- def list(username, oid)
1004
- puts oid # oid == request['oid']
1005
- end
1174
+ def list(username, oid)
1175
+ puts oid # oid == request['oid']
1176
+ end
1006
1177
 
1007
- WARNING: this feature requires the ParseTree library which
1008
- is not compatible with Windows. For the moment, this feature
1009
- is dissabled by default. To enable this feature, set
1010
- Nitro.resolve_action_arguments = true.
1178
+ WARNING: this feature requires the ParseTree library which
1179
+ is not compatible with Windows. For the moment, this feature
1180
+ is dissabled by default. To enable this feature, set
1181
+ Nitro.resolve_action_arguments = true.
1011
1182
 
1012
1183
  * New session store system, DRb sessions (stored in an independent
1013
- DRb server) are reimplemented.
1184
+ DRb server) are reimplemented.
1014
1185
 
1015
- Session.store_type = :drb
1186
+ Session.store_type = :drb
1016
1187
 
1017
1188
  * TableBuilder helps in creating html tables.
1018
1189
 
1019
1190
  * Integrated builders with the programmatic render. For example:
1020
1191
 
1021
- <div class="mytable">
1022
- #{o.build_table(:id => 'my_tab', :headers => headers, :values => values)
1023
- </div>
1192
+ <div class="mytable">
1193
+ #{o.build_table(:id => 'my_tab', :headers => headers, :values => values)
1194
+ </div>
1024
1195
 
1025
- or
1026
-
1027
- <p>
1028
- <b>Object Form</b>
1029
- #{o.build_form(obj)}
1030
- </p>
1196
+ or
1197
+
1198
+ <p>
1199
+ <b>Object Form</b>
1200
+ #{o.build_form(obj)}
1201
+ </p>
1031
1202
 
1032
1203
  * Og Oracle adapter.
1033
1204
 
1034
1205
  * Og provides advanced metadata for the managed objects
1035
1206
 
1036
- class Article
1037
- property :title, String
1038
- property :body, String
1039
- has_many :comments, Comment
1040
- end
1207
+ class Article
1208
+ property :title, String
1209
+ property :body, String
1210
+ has_many :comments, Comment
1211
+ end
1041
1212
 
1042
- par = Article.properties_and_relations
1043
- => [Property(:title), Property(:body), Og::HasMany(:comments)]
1213
+ par = Article.properties_and_relations
1214
+ => [Property(:title), Property(:body), Og::HasMany(:comments)]
1044
1215
 
1045
- par[2].klass
1046
- => Comment
1216
+ par[2].klass
1217
+ => Comment
1047
1218
 
1048
- par[2].meta[:linkback]
1049
- => :article_oid
1219
+ par[2].meta[:linkback]
1220
+ => :article_oid
1050
1221
 
1051
1222
  * Og Typemacros, here is an example:
1052
1223
 
1053
- def VarChar(size)
1054
- return String, :sql => "NOT NULL VARCHAR(#{size})"
1055
- end
1224
+ def VarChar(size)
1225
+ return String, :sql => "NOT NULL VARCHAR(#{size})"
1226
+ end
1056
1227
 
1057
- property :title, VarChar(30)
1228
+ property :title, VarChar(30)
1058
1229
 
1059
1230
  * Option for faster startup, skip schema check.
1060
1231
 
@@ -1083,31 +1254,31 @@ Most notable additions:
1083
1254
  adapter subsystem.
1084
1255
 
1085
1256
  * New SQLite3 Og adapter, improvements in MySQL and PostgreSQL
1086
- adapters (WARNING: needs version 1.1.0 of Sqlite3-Ruby).
1257
+ adapters (WARNING: needs version 1.1.0 of Sqlite3-Ruby).
1087
1258
 
1088
1259
  * Added install.rb for easier installation of the tar.gz distribution.
1089
1260
 
1090
1261
  * Better GemSpec for easier installation by RubyGems.
1091
1262
 
1092
1263
  * Action/template/xsl auto-reloading system in debug mode,
1093
- new implementation, works again.
1264
+ new implementation, works again.
1094
1265
 
1095
1266
  * New Nitro configuration system, with rational default
1096
- parameters.
1267
+ parameters.
1097
1268
 
1098
1269
  * --console option attaches an irb session to a running
1099
- instace of an application (works again).
1270
+ instace of an application (works again).
1100
1271
 
1101
1272
  * Og supports optional typechecking by using property metadata.
1102
1273
 
1103
1274
  * request alias for context to be compatible with older
1104
- versions of nitro and Webrick/jsp and other frameworks.
1275
+ versions of nitro and Webrick/jsp and other frameworks.
1105
1276
 
1106
1277
  * Improved the examples, cleaner code, work from any
1107
- directory.
1278
+ directory.
1108
1279
 
1109
1280
  * Removed more obsolete code and improved directory
1110
- structure.
1281
+ structure.
1111
1282
 
1112
1283
  * and many more smaller fixes.
1113
1284
 
@@ -1150,27 +1321,27 @@ Most notable additions:
1150
1321
  * Drastically improved source code readability.
1151
1322
 
1152
1323
  * New abstract rendering pipeline. Benefits:
1153
-
1154
- * multiple adaptors.
1155
- * better unit tests.
1156
- * optimized memory allocation.
1157
- * more modular desing.
1324
+
1325
+ * multiple adaptors.
1326
+ * better unit tests.
1327
+ * optimized memory allocation.
1328
+ * more modular desing.
1158
1329
 
1159
1330
  * FastCGI support (tested with Lighttpd).
1160
1331
 
1161
1332
  * no_xsl_blog example.
1162
1333
 
1163
- This new example is easier to setup, even on Windows.
1164
- This also demonstrates that Nitro does NOT force
1165
- the use of XSLT.
1334
+ This new example is easier to setup, even on Windows.
1335
+ This also demonstrates that Nitro does NOT force
1336
+ the use of XSLT.
1166
1337
 
1167
1338
  * No global variables used for nitro configuration.
1168
1339
 
1169
1340
  * Updated the docs to better reflect the rappidly
1170
- evolving codebase.
1341
+ evolving codebase.
1171
1342
 
1172
1343
  * Og metalanguage relations insert metadata into
1173
- the target class, useful for advanced scaffolders.
1344
+ the target class, useful for advanced scaffolders.
1174
1345
 
1175
1346
  * Og refer_to meta-language command.
1176
1347
 
@@ -1190,43 +1361,43 @@ Most notable additions:
1190
1361
 
1191
1362
  * New automatic validation system:
1192
1363
 
1193
- class User
1194
- prop_accessor :name, :password, String
1195
- validate_confirmation :password
1196
- validate_length :name, :range => 2..12
1197
- end
1198
-
1199
- u = User.new(...)
1200
- unless u.valid?
1201
- p u.errors.on(:name)
1202
- p u.errors[:password]
1203
- end
1204
-
1364
+ class User
1365
+ prop_accessor :name, :password, String
1366
+ validate_confirmation :password
1367
+ validate_length :name, :range => 2..12
1368
+ end
1369
+
1370
+ u = User.new(...)
1371
+ unless u.valid?
1372
+ p u.errors.on(:name)
1373
+ p u.errors[:password]
1374
+ end
1375
+
1205
1376
  * Programmatic xhtml rendering. This is an alternative
1206
- method of rendering that is usefull in building
1207
- components and helpers. This is a preview implementation.
1377
+ method of rendering that is usefull in building
1378
+ components and helpers. This is a preview implementation.
1208
1379
 
1209
- options = ['Male', 'Female']
1210
- o.select(:name => 'sex') {
1211
- o.options(options, selected = 1)
1212
- }
1380
+ options = ['Male', 'Female']
1381
+ o.select(:name => 'sex') {
1382
+ o.options(options, selected = 1)
1383
+ }
1213
1384
 
1214
- options = { 'Male' => 'm', 'Female' => 'f' }
1215
- o.select(:name => 'sex') {
1216
- o.options(options, selected = 1)
1217
- }
1385
+ options = { 'Male' => 'm', 'Female' => 'f' }
1386
+ o.select(:name => 'sex') {
1387
+ o.options(options, selected = 1)
1388
+ }
1218
1389
 
1219
- o.html {
1220
- o.p(:class => 'header') { o.b('Hello') }
1221
- }
1390
+ o.html {
1391
+ o.p(:class => 'header') { o.b('Hello') }
1392
+ }
1222
1393
 
1223
1394
  * No global variables in Og.
1224
1395
 
1225
1396
  * Recoded Og to allow for future support of multiple databases
1226
- (even on different RDBMS systems) on a single application.
1397
+ (even on different RDBMS systems) on a single application.
1227
1398
 
1228
1399
  * Improved Blog example demonstrates latest advancements.
1229
- (You have to drop the database of earlier versions!)
1400
+ (You have to drop the database of earlier versions!)
1230
1401
 
1231
1402
  * More unit tests.
1232
1403
 
@@ -1238,7 +1409,7 @@ Most notable additions:
1238
1409
 
1239
1410
  * And many IMPORTANT bug fixes.
1240
1411
 
1241
-
1412
+
1242
1413
  == Version 0.7 was released on 27/12/2004.
1243
1414
 
1244
1415
  A snapshot of the latest code. Many fixes and new features result
@@ -1252,7 +1423,7 @@ Most notable additions:
1252
1423
  * Totaly recoded prop_accessor mechanism, avoids polution of the Module
1253
1424
  class.
1254
1425
  * prop_accessors for Modules, allows synthesizing of managed objects
1255
- from Mixins.
1426
+ from Mixins.
1256
1427
  * new automatically generated methods in Og.
1257
1428
  * MockDatabase leverages the FlexMock object for easier unit testing.
1258
1429
  * Integrated the cool Breakpointer library by Florian Gross.