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
@@ -14,180 +14,180 @@ module Nitro
14
14
  # interaction.
15
15
 
16
16
  class Pager
17
- # Items per page.
18
-
19
- setting :per_page, :default => 10, :doc => 'Items per page'
20
-
21
- # The request key.
22
-
23
- setting :key, :default => '_page', :doc => 'The request key'
24
-
25
- # The current page.
26
-
27
- attr_accessor :page
28
-
29
- # Items per page.
30
-
31
- attr_accessor :per_page
32
-
33
- # The total number of pages.
34
-
35
- attr_accessor :page_count
36
-
37
- # Total count of items.
38
-
39
- attr_accessor :total_count
40
-
41
- def initialize(request, per_page, total_count, key = Pager.key)
42
- raise 'per_page should be > 0' unless per_page > 0
43
-
44
- @request, @key = request, key
45
- @page = request.query.fetch(key, 1).to_i
46
- @per_page = per_page
47
- set_count(total_count)
48
- @start_idx = (@page - 1) * per_page
49
- end
50
-
51
- def set_count(total_count)
52
- @total_count = total_count
53
- @page_count = (@total_count.to_f / @per_page).ceil
54
- end
55
-
56
- def first_page
57
- return 1
58
- end
59
-
60
- def last_page
61
- return @page_count
62
- end
63
-
64
- def previous_page
65
- return [@page - 1, 1].max()
66
- end
67
-
68
- def next_page
69
- return [@page + 1, @page_count].min()
70
- end
71
-
72
- # Iterator
73
-
74
- def each(&block)
75
- @page_items.each(&block)
76
- end
77
-
78
- # Iterator
79
- # Returns 1-based index.
80
-
81
- def each_with_index
82
- idx = @start_idx
83
- for item in @page_items
84
- yield(idx + 1, item)
85
- idx += 1
86
- end
87
- end
88
-
89
- def empty?
90
- return @items.empty?
91
- end
92
-
93
- def size
94
- return @items.size()
95
- end
96
-
97
- # Returns the range of the current page.
98
-
99
- def page_range
100
- s = @idx
101
- e = [@idx + @items_per_page - 1, all_total_count].min
102
-
103
- return [s, e]
104
- end
105
-
106
- # Override if needed.
107
-
108
- def nav_range
109
- # effective range = 10 pages.
110
- s = [@page - 5, 1].max()
111
- e = [@page + 9, @page_count].min()
112
-
113
- d = 9 - (e - s)
114
- e += d if d < 0
115
-
116
- return (s..e)
117
- end
118
-
119
- # To be used with Og queries.
120
-
121
- def limit
122
- { :limit => @per_page, :offset => @start_idx }
123
- end
124
-
125
- def offset
126
- @start_idx
127
- end
128
-
129
- # Create an appropriate SQL limit clause.
130
- # Returns postgres/mysql compatible limit.
131
-
132
- def to_sql
133
- if @start_idx > 0
134
- return "LIMIT #{@per_page} OFFSET #{@start_idx}"
135
- else
136
- # gmosx: perhaps this is optimized ? naaaaaah...
137
- return "LIMIT #{@per_page}"
138
- end
139
- end
140
-
141
- # Override this method in your application if needed.
142
- #--
143
- # TODO: better markup.
144
- #++
145
-
146
- def navigation
147
- nav = ""
148
-
149
- unless @page == first_page()
150
- nav << %{
151
- <div class="first"><a href="#{target_uri(first_page())}">First</a></div>
152
- <div class="previous"><a href="#{target_uri(previous_page())}">Previous</a></div>
153
- }
154
- end
155
-
156
- unless @page == last_page()
157
- nav << %{
158
- <div class="last"><a href="#{target_uri(last_page())}">Last</a></div>
159
- <div class="next"><a href="#{target_uri(next_page())}">Next</a></div>
160
- }
161
- end
162
-
163
- nav << %{<ul>}
164
-
165
- for i in nav_range()
166
- if i == @page
167
- nav << %{
168
- <li class="active">#{i}</li>
169
- }
170
- else
171
- nav << %{
172
- <li><a href="#{target_uri(i)}">#{i}</a></li>
173
- }
174
- end
175
- end
176
-
177
- nav << %{</ul>}
178
-
179
- return nav
180
- end
181
- alias_method :links, :navigation
17
+ # Items per page.
18
+
19
+ setting :per_page, :default => 10, :doc => 'Items per page'
20
+
21
+ # The request key.
22
+
23
+ setting :key, :default => '_page', :doc => 'The request key'
24
+
25
+ # The current page.
26
+
27
+ attr_accessor :page
28
+
29
+ # Items per page.
30
+
31
+ attr_accessor :per_page
32
+
33
+ # The total number of pages.
34
+
35
+ attr_accessor :page_count
36
+
37
+ # Total count of items.
38
+
39
+ attr_accessor :total_count
40
+
41
+ def initialize(request, per_page, total_count, key = Pager.key)
42
+ raise 'per_page should be > 0' unless per_page > 0
43
+
44
+ @request, @key = request, key
45
+ @page = request.query.fetch(key, 1).to_i
46
+ @per_page = per_page
47
+ set_count(total_count)
48
+ @start_idx = (@page - 1) * per_page
49
+ end
50
+
51
+ def set_count(total_count)
52
+ @total_count = total_count
53
+ @page_count = (@total_count.to_f / @per_page).ceil
54
+ end
55
+
56
+ def first_page
57
+ return 1
58
+ end
59
+
60
+ def last_page
61
+ return @page_count
62
+ end
63
+
64
+ def previous_page
65
+ return [@page - 1, 1].max()
66
+ end
67
+
68
+ def next_page
69
+ return [@page + 1, @page_count].min()
70
+ end
71
+
72
+ # Iterator
73
+
74
+ def each(&block)
75
+ @page_items.each(&block)
76
+ end
77
+
78
+ # Iterator
79
+ # Returns 1-based index.
80
+
81
+ def each_with_index
82
+ idx = @start_idx
83
+ for item in @page_items
84
+ yield(idx + 1, item)
85
+ idx += 1
86
+ end
87
+ end
88
+
89
+ def empty?
90
+ return @items.empty?
91
+ end
92
+
93
+ def size
94
+ return @items.size()
95
+ end
96
+
97
+ # Returns the range of the current page.
98
+
99
+ def page_range
100
+ s = @idx
101
+ e = [@idx + @items_per_page - 1, all_total_count].min
102
+
103
+ return [s, e]
104
+ end
105
+
106
+ # Override if needed.
107
+
108
+ def nav_range
109
+ # effective range = 10 pages.
110
+ s = [@page - 5, 1].max()
111
+ e = [@page + 9, @page_count].min()
112
+
113
+ d = 9 - (e - s)
114
+ e += d if d < 0
115
+
116
+ return (s..e)
117
+ end
118
+
119
+ # To be used with Og queries.
120
+
121
+ def limit
122
+ { :limit => @per_page, :offset => @start_idx }
123
+ end
124
+
125
+ def offset
126
+ @start_idx
127
+ end
128
+
129
+ # Create an appropriate SQL limit clause.
130
+ # Returns postgres/mysql compatible limit.
131
+
132
+ def to_sql
133
+ if @start_idx > 0
134
+ return "LIMIT #{@per_page} OFFSET #{@start_idx}"
135
+ else
136
+ # gmosx: perhaps this is optimized ? naaaaaah...
137
+ return "LIMIT #{@per_page}"
138
+ end
139
+ end
140
+
141
+ # Override this method in your application if needed.
142
+ #--
143
+ # TODO: better markup.
144
+ #++
145
+
146
+ def navigation
147
+ nav = ""
148
+
149
+ unless @page == first_page()
150
+ nav << %{
151
+ <div class="first"><a href="#{target_uri(first_page())}">First</a></div>
152
+ <div class="previous"><a href="#{target_uri(previous_page())}">Previous</a></div>
153
+ }
154
+ end
155
+
156
+ unless @page == last_page()
157
+ nav << %{
158
+ <div class="last"><a href="#{target_uri(last_page())}">Last</a></div>
159
+ <div class="next"><a href="#{target_uri(next_page())}">Next</a></div>
160
+ }
161
+ end
162
+
163
+ nav << %{<ul>}
164
+
165
+ for i in nav_range()
166
+ if i == @page
167
+ nav << %{
168
+ <li class="active">#{i}</li>
169
+ }
170
+ else
171
+ nav << %{
172
+ <li><a href="#{target_uri(i)}">#{i}</a></li>
173
+ }
174
+ end
175
+ end
176
+
177
+ nav << %{</ul>}
178
+
179
+ return nav
180
+ end
181
+ alias_method :links, :navigation
182
182
 
183
183
  private
184
184
 
185
- # Generate the target URI.
186
-
187
- def target_uri(page)
188
- params = { @key => page }
189
- return UriUtils.update_query_string(@request.uri.to_s, params)
190
- end
185
+ # Generate the target URI.
186
+
187
+ def target_uri(page)
188
+ params = { @key => page }
189
+ return UriUtils.update_query_string(@request.uri.to_s, params)
190
+ end
191
191
 
192
192
  end
193
193
 
@@ -196,37 +196,37 @@ end
196
196
  module PagerMixin
197
197
 
198
198
  private
199
-
200
- # Helper method that generates a collection of items and the
201
- # asorted pager object.
202
- #
203
- # === Example
204
- #
205
- # entries, pager = paginate(Article, :condition => 'title LIKE %Ab%', :per_page => 10)
206
- #
207
- # <ul>
208
- # <?r for entry in entries ?>
209
- # <li>#{entry.to_link}</li>
210
- # <?r end ?>
211
- # </ul>
212
- # #{pager.links}
213
-
214
- def paginate(klass_or_array, options = {})
215
- per_page = options.delete(:per_page) || Pager.per_page
216
-
217
- if klass_or_array.is_a? Array
218
- items = klass_or_array.dup
219
- pager = Pager.new(request, per_page, items.size, key = Pager.key)
220
- items = items.slice(pager.offset, pager.per_page)
221
- return items, pager
222
- else
223
- pager = Pager.new(request, per_page, klass_or_array.count(options), key = Pager.key)
224
- options.update(pager.limit)
225
- items = klass_or_array.all(options)
226
- return items, pager
227
- end
228
- end
229
-
199
+
200
+ # Helper method that generates a collection of items and the
201
+ # asorted pager object.
202
+ #
203
+ # === Example
204
+ #
205
+ # entries, pager = paginate(Article, :condition => 'title LIKE %Ab%', :per_page => 10)
206
+ #
207
+ # <ul>
208
+ # <?r for entry in entries ?>
209
+ # <li>#{entry.to_link}</li>
210
+ # <?r end ?>
211
+ # </ul>
212
+ # #{pager.links}
213
+
214
+ def paginate(klass_or_array, options = {})
215
+ per_page = options.delete(:per_page) || Pager.per_page
216
+
217
+ if klass_or_array.is_a? Array
218
+ items = klass_or_array.dup
219
+ pager = Pager.new(request, per_page, items.size, key = Pager.key)
220
+ items = items.slice(pager.offset, pager.per_page)
221
+ return items, pager
222
+ else
223
+ pager = Pager.new(request, per_page, klass_or_array.count(options), key = Pager.key)
224
+ options.update(pager.limit)
225
+ items = klass_or_array.all(options)
226
+ return items, pager
227
+ end
228
+ end
229
+
230
230
  end
231
231
 
232
232
  end
@@ -0,0 +1,67 @@
1
+ require 'cgi'
2
+ require 'rss/0.9'
3
+
4
+ require 'facet/string/first_char'
5
+
6
+ module Nitro
7
+
8
+ # Build RSS represenations of ruby object collections.
9
+ # Utilize duck typing to grab the attributes to render.
10
+ # Add this mixin to you classes to support RSS rendering.
11
+ #
12
+ #--
13
+ # TODO: add more options here, 1.0/2.0 support and more.
14
+ # use custom version to add headers like the following.
15
+ # <?xml version="1.0" encoding="UTF-8"?>
16
+ # <?xml-stylesheet href="rss.css" type="text/css"?>
17
+ #++
18
+
19
+ module RssMixin
20
+
21
+ # === Options
22
+ #
23
+ # [+:description+]
24
+ # Description of the Feed
25
+ # [+:base+]
26
+ # Base url of the Feed.
27
+ # [+:link+]
28
+ # Link of the Feed.
29
+
30
+ def build_rss_09(objects, options = {})
31
+ c = {
32
+ :description => 'Syndication'
33
+ }.update(options)
34
+
35
+ c[:base] ||= c[:link]
36
+
37
+ raise "Option ':base' cannot be infered!" unless c[:base]
38
+
39
+ channel = RSS::Rss::Channel.new
40
+ channel.description = c[:description]
41
+ channel.link = c[:link] if c[:link]
42
+
43
+ for obj in objects
44
+ item = RSS::Rss::Channel::Item.new
45
+ item.title = obj.title if obj.respond_to?(:title)
46
+ if obj.respond_to? :body and body = obj.body
47
+ item.description = CGI.escape(body.first_char(256))
48
+ end
49
+ if obj.respond_to? :to_href
50
+ item.link = "#{c[:base]}/#{obj.to_href}"
51
+ end
52
+ channel.items << item
53
+ end
54
+
55
+ rss = RSS::Rss.new '0.9'
56
+ rss.channel = channel
57
+
58
+ return rss.to_s
59
+ end
60
+ alias_method :build_rss, :build_rss_09
61
+ alias_method :rss, :build_rss_09
62
+
63
+ end
64
+
65
+ end
66
+
67
+ # * George Moschovitis <gm@navel.gr>