nitro 0.19.0 → 0.20.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 +187 -0
- data/INSTALL +5 -0
- data/README +11 -5
- data/doc/AUTHORS +11 -1
- data/doc/RELEASES +217 -0
- data/doc/tutorial.txt +1 -2
- data/lib/nitro.rb +9 -6
- data/lib/nitro/adapter/webrick.rb +13 -2
- data/lib/nitro/builder/form.rb +11 -9
- data/lib/nitro/builder/rss.rb +2 -2
- data/lib/nitro/builder/xhtml.rb +15 -0
- data/lib/nitro/caching.rb +15 -10
- data/lib/nitro/conf.rb +0 -5
- data/lib/nitro/controller.rb +118 -81
- data/lib/nitro/cookie.rb +6 -6
- data/lib/nitro/dispatcher.rb +62 -18
- data/lib/nitro/element.rb +4 -1
- data/lib/nitro/element/java_script.rb +15 -0
- data/lib/nitro/localization.rb +3 -4
- data/lib/nitro/markup.rb +4 -4
- data/lib/nitro/mixin/debug.rb +30 -0
- data/lib/nitro/mixin/helper.rb +14 -0
- data/lib/nitro/mixin/javascript.rb +137 -0
- data/lib/nitro/{ui → mixin}/pager.rb +110 -82
- data/lib/nitro/render.rb +20 -8
- data/lib/nitro/request.rb +6 -0
- data/lib/nitro/routing.rb +6 -5
- data/lib/nitro/runner.rb +21 -9
- data/lib/nitro/server.rb +95 -0
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/session.rb +4 -5
- data/lib/nitro/shaders.rb +2 -2
- data/lib/nitro/template.rb +1 -1
- data/lib/nitro/testing/assertions.rb +2 -4
- data/lib/nitro/testing/context.rb +4 -6
- data/proto/public/js/behaviour.js +254 -0
- data/proto/public/js/controls.js +446 -0
- data/proto/public/js/dragdrop.js +537 -0
- data/proto/public/js/effects.js +612 -0
- data/proto/public/js/prototype.js +644 -370
- data/proto/public/settings.xhtml +64 -0
- data/test/nitro/adapter/tc_cgi.rb +2 -2
- data/test/nitro/builder/tc_rss.rb +1 -1
- data/test/nitro/mixin/tc_pager.rb +35 -0
- data/test/nitro/tc_controller.rb +1 -1
- data/test/nitro/tc_cookie.rb +14 -0
- data/test/nitro/tc_dispatcher.rb +11 -6
- data/test/nitro/tc_server.rb +35 -0
- metadata +20 -15
- data/lib/nitro/builder/atom.rb +0 -74
- data/lib/nitro/part.rb +0 -22
- data/lib/nitro/simple.rb +0 -11
- data/lib/nitro/ui/popup.rb +0 -41
- data/lib/nitro/ui/tabs.rb +0 -25
- data/lib/nitro/uri.rb +0 -193
- data/test/nitro/builder/tc_atom.rb +0 -24
- data/test/nitro/tc_uri.rb +0 -97
- data/test/nitro/ui/tc_pager.rb +0 -49
@@ -1,78 +1,58 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# $Id: pager.rb 1 2005-04-11 11:04:30Z gmosx $
|
1
|
+
require 'glue/uri'
|
2
|
+
require 'glue/configuration'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
module Nitro; module UI
|
4
|
+
module Nitro
|
8
5
|
|
9
6
|
# Displays a collection of entitities in multiple pages.
|
10
7
|
#
|
11
8
|
# === Design
|
12
9
|
#
|
13
|
-
#
|
10
|
+
# This pager is carefully designed for scaleability. It stores
|
14
11
|
# only the items for one page. The name parameter is needed, multiple
|
15
12
|
# pagers can coexist in a single page. Unlike older pagers this
|
16
|
-
# pager leverages the SQL LIMIT option to optimize database
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
# @entries = BlogEntry.all("ORDER BY oid #{@pager.sql_limit}")
|
22
|
-
# @pager.set(BlogEntry.count)
|
23
|
-
#
|
24
|
-
# default navigation (customize with css):
|
25
|
-
# <div class="pager">#{@pager.navigation}</div>
|
26
|
-
#
|
27
|
-
# custom navigation:
|
28
|
-
#
|
29
|
-
# <table cellspacing="0" width="100%" border="1">
|
30
|
-
# <tr>
|
31
|
-
# <td width="64"><x:pager-prev>Previous</x:pager-prev></td>
|
32
|
-
# <td width="100%"></td>
|
33
|
-
# <td width="64"><x:pager-next>Next</x:pager-next></td>
|
34
|
-
# </tr>
|
35
|
-
# </table>
|
36
|
-
#--
|
37
|
-
# INVESTIGATE:
|
38
|
-
# mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
|
39
|
-
# -> WHERE id > 100 LIMIT 10;
|
40
|
-
# mysql> SELECT FOUND_ROWS();
|
41
|
-
#++
|
42
|
-
|
43
|
-
class Pager < Array
|
44
|
-
|
45
|
-
attr_accessor :name, :idx, :page, :page_count
|
46
|
-
|
47
|
-
# Total count of items
|
48
|
-
attr_accessor :total_count
|
13
|
+
# pager leverages the SQL LIMIT option to optimize database
|
14
|
+
# interaction.
|
15
|
+
|
16
|
+
class Pager
|
17
|
+
# Items per page.
|
49
18
|
|
50
|
-
|
51
|
-
attr_accessor :page_items
|
19
|
+
setting :per_page, :default => 10, :doc => 'Items per page'
|
52
20
|
|
53
|
-
#
|
54
|
-
attr_accessor :request
|
21
|
+
# The request key.
|
55
22
|
|
56
|
-
|
57
|
-
|
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
|
58
32
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
33
|
+
# The total number of pages.
|
34
|
+
|
35
|
+
attr_accessor :page_count
|
36
|
+
|
37
|
+
# Total count of items.
|
38
|
+
|
39
|
+
attr_accessor :total_count
|
63
40
|
|
64
|
-
|
65
|
-
|
66
|
-
# gmosx, FIXME: not exactly what i want!
|
67
|
-
items.slice!(@start_idx, @items_per_page)
|
68
|
-
end
|
69
|
-
end
|
41
|
+
def initialize(request, per_page, total_count, key = Pager.key)
|
42
|
+
raise 'per_page should be > 0' unless per_page > 0
|
70
43
|
|
71
|
-
|
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)
|
72
52
|
@total_count = total_count
|
73
|
-
@page_count = (@total_count.to_f
|
53
|
+
@page_count = (@total_count.to_f / @per_page).ceil
|
74
54
|
end
|
75
|
-
|
55
|
+
|
76
56
|
def first_page
|
77
57
|
return 1
|
78
58
|
end
|
@@ -135,10 +115,33 @@ class Pager < Array
|
|
135
115
|
|
136
116
|
return (s..e)
|
137
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.
|
138
131
|
|
139
|
-
|
140
|
-
|
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
|
+
#--
|
141
143
|
# TODO: better markup.
|
144
|
+
#++
|
142
145
|
|
143
146
|
def navigation
|
144
147
|
nav = ""
|
@@ -175,32 +178,57 @@ class Pager < Array
|
|
175
178
|
|
176
179
|
return nav
|
177
180
|
end
|
181
|
+
alias_method :links, :navigation
|
182
|
+
|
183
|
+
private
|
178
184
|
|
179
|
-
# Create an appropriate SQL limit clause.
|
180
|
-
# Returns postgres/mysql compatible limit.
|
181
|
-
|
182
|
-
def sql_limit
|
183
|
-
if @start_idx > 0
|
184
|
-
return "LIMIT #{@items_per_page} OFFSET #{@start_idx}"
|
185
|
-
else
|
186
|
-
# gmosx: perhaps this is optimized ? naaaaaah...
|
187
|
-
return "LIMIT #{@items_per_page}"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Returns the current offset. The offset is zero-based.
|
192
|
-
|
193
|
-
def offset
|
194
|
-
(@page-1) * @items_per_page
|
195
|
-
end
|
196
|
-
|
197
185
|
# Generate the target URI.
|
198
|
-
|
186
|
+
|
199
187
|
def target_uri(page)
|
200
|
-
params = {
|
188
|
+
params = { @key => page }
|
201
189
|
return UriUtils.update_query_string(@request.uri.to_s, params)
|
202
190
|
end
|
203
191
|
|
204
192
|
end
|
205
193
|
|
206
|
-
|
194
|
+
# Pager related helper methods.
|
195
|
+
|
196
|
+
module PagerMixin
|
197
|
+
|
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
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/render.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'sync'
|
2
2
|
|
3
|
+
require 'facet/string/blank%3F'
|
4
|
+
|
3
5
|
require 'glue/attribute'
|
4
6
|
require 'glue/misc'
|
5
7
|
require 'glue/object'
|
8
|
+
require 'glue/settings'
|
6
9
|
|
7
10
|
require 'nitro/shaders'
|
8
11
|
require 'nitro/buffering'
|
@@ -27,12 +30,12 @@ module Rendering
|
|
27
30
|
@@sync = Sync.new
|
28
31
|
|
29
32
|
# The default template root
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
|
34
|
+
setting :default_template_root, :default => 'public', :doc => 'The default template root'
|
35
|
+
|
33
36
|
# The default template name (no extension).
|
34
37
|
|
35
|
-
|
38
|
+
setting :default_template, :default => 'index', :doc => 'The default template name (no extension).'
|
36
39
|
|
37
40
|
# The shader used for transforming templates.
|
38
41
|
# The default shader is very simple, here is a
|
@@ -48,11 +51,12 @@ module Rendering
|
|
48
51
|
# </tt>
|
49
52
|
|
50
53
|
mattr_accessor :shader; @@shader = RubyShader.new
|
54
|
+
# setting :shader, :default => RubyShader.new, :doc => 'The shader used for transforming templates'
|
51
55
|
|
52
56
|
# If set to :full, reloads all controllers. Useful in
|
53
57
|
# development.
|
54
58
|
|
55
|
-
|
59
|
+
setting :reload, :default => false, :doc => 'If set to :full reloads everything, useful in development'
|
56
60
|
|
57
61
|
# Given the action try find the matching template.
|
58
62
|
# Can search for xhtml or xml templates.
|
@@ -133,15 +137,17 @@ module Rendering
|
|
133
137
|
|
134
138
|
param_count = klass.instance_method(action.intern).arity
|
135
139
|
|
140
|
+
# gmosx, FIXME: REIMPLEMENT THIS!!!!
|
141
|
+
|
136
142
|
if param_count > 0
|
137
143
|
code << %{
|
144
|
+
params = []
|
138
145
|
qs = context.query_string.split(/[&;]/)
|
139
146
|
|
140
|
-
params = []
|
141
147
|
#{param_count}.times do |i|
|
142
148
|
params << qs.shift.split(/=/).last
|
143
149
|
end
|
144
|
-
|
150
|
+
|
145
151
|
unless :stop == #{action}(*params)
|
146
152
|
}
|
147
153
|
else
|
@@ -272,7 +278,11 @@ module Render
|
|
272
278
|
# The name of the currently executing action.
|
273
279
|
|
274
280
|
attr_accessor :action_name
|
275
|
-
|
281
|
+
|
282
|
+
# The name of the current controller.
|
283
|
+
|
284
|
+
attr_accessor :controller_name
|
285
|
+
|
276
286
|
# Initialize the render.
|
277
287
|
#
|
278
288
|
# [+context+]
|
@@ -280,6 +290,7 @@ module Render
|
|
280
290
|
|
281
291
|
def initialize(context, base = nil)
|
282
292
|
@request = @response = @context = context
|
293
|
+
@controller_name = base
|
283
294
|
@out = context.out
|
284
295
|
end
|
285
296
|
|
@@ -324,6 +335,7 @@ private
|
|
324
335
|
def redirect(url, status = 303)
|
325
336
|
url = url.to_s
|
326
337
|
url = "#{@context.host_url}/#{url.gsub(/^\//, '')}" unless url =~ /http/
|
338
|
+
|
327
339
|
@context.status = status
|
328
340
|
@context.out = "<html><a href=\"#{url}\">#{url}</a>.</html>\n"
|
329
341
|
@context.response_headers['location'] = url
|
data/lib/nitro/request.rb
CHANGED
data/lib/nitro/routing.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: routing.rb 1 2005-04-11 11:04:30Z gmosx $
|
4
|
-
|
5
1
|
module Nitro
|
6
2
|
|
7
|
-
# Router mixin.
|
3
|
+
# Router mixin. Typically used to generate 'nice' urls.
|
4
|
+
# Nice urls are considered (?) more Search Engine
|
5
|
+
# friendly.
|
8
6
|
|
9
7
|
module Router
|
10
8
|
|
@@ -31,3 +29,6 @@ module Router
|
|
31
29
|
end
|
32
30
|
|
33
31
|
end
|
32
|
+
|
33
|
+
# * George Moschovitis <gm@navel.gr>
|
34
|
+
|
data/lib/nitro/runner.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'optparse'
|
4
4
|
|
5
5
|
require 'glue/misc'
|
6
|
+
require 'glue/configuration'
|
7
|
+
|
6
8
|
require 'nitro/conf'
|
7
9
|
|
8
10
|
module Nitro
|
@@ -135,7 +137,8 @@ class Runner
|
|
135
137
|
end
|
136
138
|
ENV['NITRO_INVOKE'] = 'irb'
|
137
139
|
conf_file = File.basename(caller.last.split(':').first)
|
138
|
-
exec "#{irb_name} -r #{conf_file} -r irb/completion --noinspect"
|
140
|
+
# exec "#{irb_name} -r #{conf_file} -r irb/completion --noinspect"
|
141
|
+
exec "#{irb_name} -r #{conf_file} --noinspect"
|
139
142
|
exit
|
140
143
|
end
|
141
144
|
|
@@ -170,20 +173,19 @@ class Runner
|
|
170
173
|
# using the passed configuration parameters.
|
171
174
|
|
172
175
|
def run(conf)
|
173
|
-
|
174
176
|
if conf.is_a?(Hash)
|
175
177
|
conf = Conf.new(conf)
|
176
178
|
end
|
177
179
|
|
178
180
|
case @mode
|
179
|
-
|
180
|
-
|
181
|
+
when :debug
|
182
|
+
setup_debug(conf)
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
184
|
+
when :stage
|
185
|
+
setup_stage(conf)
|
186
|
+
|
187
|
+
when :live
|
188
|
+
setup_live(conf)
|
187
189
|
end
|
188
190
|
|
189
191
|
if 'fcgi_proc' == ENV['NITRO_INVOKE']
|
@@ -330,6 +332,16 @@ def self.run(conf = nil)
|
|
330
332
|
runner.run(conf)
|
331
333
|
end
|
332
334
|
|
335
|
+
#--
|
336
|
+
# Experimental.
|
337
|
+
#++
|
338
|
+
|
339
|
+
def self.start(controller)
|
340
|
+
# require 'glue/autoreload'
|
341
|
+
# autoreload(3)
|
342
|
+
Server.run(controller)
|
343
|
+
end
|
344
|
+
|
333
345
|
end
|
334
346
|
|
335
347
|
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/server.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'glue/autoreload'
|
2
|
+
require 'nitro/adapter/webrick'
|
3
|
+
|
4
|
+
module Nitro
|
5
|
+
|
6
|
+
class Server
|
7
|
+
|
8
|
+
# :nodoc: all
|
9
|
+
# A Helper class used for CherryPy-style publishing.
|
10
|
+
|
11
|
+
class Mounter
|
12
|
+
def initialize(parent, base = '')
|
13
|
+
@parent, @base = parent, base
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(sym, *args)
|
17
|
+
sym = sym.to_s
|
18
|
+
if sym =~ /=$/
|
19
|
+
@parent.map["#@base/#{sym.gsub(/=/, '')}"] = args.first
|
20
|
+
else
|
21
|
+
Mounter.new(@parent, "#@base/#{sym}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The server listening address.
|
27
|
+
#--
|
28
|
+
# 0.0.0.0 may be a better default?
|
29
|
+
#++
|
30
|
+
|
31
|
+
setting :address, :default => '127.0.0.1', :doc => 'The server listening address'
|
32
|
+
|
33
|
+
# The server listening port.
|
34
|
+
|
35
|
+
setting :port, :default => 9999, :doc => 'The server listening port'
|
36
|
+
|
37
|
+
# The map.
|
38
|
+
|
39
|
+
setting :map, :default => { '/' => SimpleController }, :doc => 'The server map'
|
40
|
+
|
41
|
+
# The name of the application.
|
42
|
+
|
43
|
+
attr_accessor :name
|
44
|
+
|
45
|
+
# The sitemap. Defines how controller objects are published.
|
46
|
+
|
47
|
+
attr_accessor :map
|
48
|
+
|
49
|
+
def initialize(name = 'Nitro')
|
50
|
+
@name = name
|
51
|
+
@map = self.class.map.dup
|
52
|
+
end
|
53
|
+
|
54
|
+
# Start the server.
|
55
|
+
|
56
|
+
def start(controller = nil)
|
57
|
+
self.map['/'] = controller if controller
|
58
|
+
|
59
|
+
$DBG = true
|
60
|
+
autoreload(3)
|
61
|
+
Rendering.reload = :full
|
62
|
+
|
63
|
+
dispatcher = Dispatcher.new
|
64
|
+
dispatcher.publish(self.map)
|
65
|
+
conf = {
|
66
|
+
:dispatcher => dispatcher
|
67
|
+
}
|
68
|
+
|
69
|
+
Webrick.start(Conf.new(conf))
|
70
|
+
end
|
71
|
+
|
72
|
+
def root=(controller)
|
73
|
+
@map['/'] = controller
|
74
|
+
end
|
75
|
+
|
76
|
+
def root
|
77
|
+
Mounter.new(self)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Helper method.
|
81
|
+
|
82
|
+
def self.run(controller = nil)
|
83
|
+
server = Server.new
|
84
|
+
server.start(controller)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
# Alias for the Server class.
|
92
|
+
|
93
|
+
App = Nitro::Server unless Object.const_defined?(:App)
|
94
|
+
|
95
|
+
# * George Moschovitis <gm@navel.gr>
|