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.
- data/CHANGELOG +752 -543
- data/INSTALL +38 -38
- data/README +264 -225
- data/Rakefile +48 -49
- data/bin/nitro +3 -3
- data/bin/nitrogen +6 -6
- data/doc/AUTHORS +10 -10
- data/doc/CHANGELOG.1 +1939 -1939
- data/doc/CHANGELOG.2 +954 -954
- data/doc/LICENSE +3 -3
- data/doc/MIGRATION +28 -0
- data/doc/RELEASES +814 -643
- data/doc/config.txt +5 -5
- data/install.rb +7 -17
- data/lib/nitro.rb +38 -9
- data/lib/nitro/adapter/cgi.rb +311 -312
- data/lib/nitro/adapter/fastcgi.rb +18 -25
- data/lib/nitro/adapter/webrick.rb +128 -137
- data/lib/nitro/adapter/wee.rb +51 -0
- data/lib/nitro/caching.rb +20 -20
- data/lib/nitro/caching/actions.rb +43 -43
- data/lib/nitro/caching/fragments.rb +46 -46
- data/lib/nitro/caching/invalidation.rb +11 -11
- data/lib/nitro/caching/output.rb +65 -65
- data/lib/nitro/caching/stores.rb +67 -67
- data/lib/nitro/compiler.rb +262 -0
- data/lib/nitro/compiler/elements.rb +0 -0
- data/lib/nitro/compiler/errors.rb +65 -0
- data/lib/nitro/compiler/localization.rb +25 -0
- data/lib/nitro/compiler/markup.rb +19 -0
- data/lib/nitro/compiler/shaders.rb +206 -0
- data/lib/nitro/compiler/squeeze.rb +20 -0
- data/lib/nitro/compiler/xslt.rb +61 -0
- data/lib/nitro/context.rb +87 -88
- data/lib/nitro/controller.rb +151 -158
- data/lib/nitro/cookie.rb +34 -34
- data/lib/nitro/dispatcher.rb +195 -186
- data/lib/nitro/element.rb +132 -126
- data/lib/nitro/element/java_script.rb +6 -6
- data/lib/nitro/flash.rb +66 -66
- data/lib/nitro/mail.rb +192 -192
- data/lib/nitro/mixin/buffer.rb +66 -0
- data/lib/nitro/mixin/debug.rb +16 -16
- data/lib/nitro/mixin/form.rb +88 -0
- data/lib/nitro/mixin/helper.rb +2 -2
- data/lib/nitro/mixin/javascript.rb +108 -108
- data/lib/nitro/mixin/markup.rb +144 -0
- data/lib/nitro/mixin/pager.rb +202 -202
- data/lib/nitro/mixin/rss.rb +67 -0
- data/lib/nitro/mixin/table.rb +63 -0
- data/lib/nitro/mixin/xhtml.rb +75 -0
- data/lib/nitro/mixin/xml.rb +124 -0
- data/lib/nitro/render.rb +183 -359
- data/lib/nitro/request.rb +140 -140
- data/lib/nitro/response.rb +27 -27
- data/lib/nitro/routing.rb +21 -21
- data/lib/nitro/scaffold.rb +124 -118
- data/lib/nitro/server.rb +117 -80
- data/lib/nitro/server/runner.rb +341 -0
- data/lib/nitro/service.rb +12 -12
- data/lib/nitro/service/xmlrpc.rb +22 -22
- data/lib/nitro/session.rb +122 -120
- data/lib/nitro/session/drb.rb +9 -9
- data/lib/nitro/session/drbserver.rb +34 -34
- data/lib/nitro/template.rb +171 -155
- data/lib/nitro/testing/assertions.rb +90 -90
- data/lib/nitro/testing/context.rb +16 -16
- data/lib/nitro/testing/testcase.rb +34 -34
- data/proto/conf/lhttpd.conf +9 -9
- data/proto/public/error.xhtml +75 -75
- data/proto/public/index.xhtml +18 -18
- data/proto/public/js/behaviour.js +65 -65
- data/proto/public/js/controls.js +1 -1
- data/proto/public/js/prototype.js +3 -3
- data/proto/public/settings.xhtml +61 -61
- data/proto/run.rb +1 -5
- data/test/nitro/adapter/raw_post1.bin +0 -0
- data/test/nitro/adapter/tc_cgi.rb +57 -57
- data/test/nitro/adapter/tc_webrick.rb +4 -4
- data/test/nitro/mixin/tc_pager.rb +25 -25
- data/test/nitro/mixin/tc_rss.rb +24 -0
- data/test/nitro/mixin/tc_table.rb +31 -0
- data/test/nitro/mixin/tc_xhtml.rb +13 -0
- data/test/nitro/tc_caching.rb +10 -10
- data/test/nitro/tc_context.rb +8 -8
- data/test/nitro/tc_controller.rb +48 -48
- data/test/nitro/tc_cookie.rb +6 -6
- data/test/nitro/tc_dispatcher.rb +64 -64
- data/test/nitro/tc_element.rb +27 -27
- data/test/nitro/tc_flash.rb +31 -31
- data/test/nitro/tc_mail.rb +63 -63
- data/test/nitro/tc_server.rb +26 -26
- data/test/nitro/tc_session.rb +9 -9
- data/test/nitro/tc_template.rb +19 -19
- data/test/public/blog/list.xhtml +1 -1
- metadata +31 -37
- data/lib/nitro/buffering.rb +0 -45
- data/lib/nitro/builder/form.rb +0 -104
- data/lib/nitro/builder/rss.rb +0 -104
- data/lib/nitro/builder/table.rb +0 -80
- data/lib/nitro/builder/xhtml.rb +0 -132
- data/lib/nitro/builder/xml.rb +0 -131
- data/lib/nitro/conf.rb +0 -36
- data/lib/nitro/environment.rb +0 -21
- data/lib/nitro/errors.rb +0 -69
- data/lib/nitro/localization.rb +0 -153
- data/lib/nitro/markup.rb +0 -147
- data/lib/nitro/output.rb +0 -24
- data/lib/nitro/runner.rb +0 -348
- data/lib/nitro/shaders.rb +0 -206
- data/test/nitro/builder/tc_rss.rb +0 -23
- data/test/nitro/builder/tc_table.rb +0 -30
- data/test/nitro/builder/tc_xhtml.rb +0 -39
- data/test/nitro/builder/tc_xml.rb +0 -56
- data/test/nitro/tc_localization.rb +0 -49
data/lib/nitro/mixin/pager.rb
CHANGED
|
@@ -14,180 +14,180 @@ module Nitro
|
|
|
14
14
|
# interaction.
|
|
15
15
|
|
|
16
16
|
class Pager
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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>
|