nitro 0.31.0 → 0.40.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/bin/nitro +135 -37
- data/doc/CHANGELOG.1 +108 -108
- data/doc/CHANGELOG.2 +89 -89
- data/doc/CHANGELOG.3 +105 -105
- data/{CHANGELOG → doc/CHANGELOG.4} +509 -509
- data/doc/{AUTHORS → CONTRIBUTORS} +49 -37
- data/doc/LIBRARIES +13 -0
- data/doc/LICENSE +2 -3
- data/doc/MIGRATION +45 -0
- data/doc/RELEASES +131 -11
- data/doc/TODO +67 -0
- data/lib/glue/magick.rb +0 -3
- data/lib/glue/sweeper.rb +30 -15
- data/lib/glue/thumbnails.rb +0 -2
- data/lib/glue/webfile.rb +23 -11
- data/lib/nitro.rb +37 -44
- data/lib/nitro/adapter/cgi.rb +0 -3
- data/lib/nitro/adapter/console.rb +0 -2
- data/lib/nitro/adapter/fastcgi.rb +6 -3
- data/lib/nitro/adapter/mongrel.rb +97 -58
- data/lib/nitro/adapter/script.rb +4 -6
- data/lib/nitro/adapter/webrick.rb +33 -87
- data/lib/nitro/adapter/webrick/vcr.rb +85 -0
- data/lib/nitro/caching.rb +0 -2
- data/lib/nitro/caching/actions.rb +0 -2
- data/lib/nitro/caching/fragments.rb +0 -2
- data/lib/nitro/caching/output.rb +45 -16
- data/lib/nitro/caching/proxy.rb +49 -0
- data/lib/nitro/cgi.rb +3 -6
- data/lib/nitro/cgi/cookie.rb +0 -3
- data/lib/nitro/cgi/request.rb +67 -24
- data/lib/nitro/cgi/response.rb +0 -2
- data/lib/nitro/cgi/{sendfile.rb → send_file.rb} +7 -6
- data/lib/nitro/compiler.rb +62 -55
- data/lib/nitro/compiler/cleanup.rb +0 -3
- data/lib/nitro/compiler/elements.rb +31 -28
- data/lib/nitro/compiler/errors.rb +2 -5
- data/lib/nitro/compiler/include.rb +10 -8
- data/lib/nitro/compiler/layout.rb +0 -2
- data/lib/nitro/compiler/localization.rb +0 -2
- data/lib/nitro/compiler/markup.rb +14 -6
- data/lib/nitro/compiler/morphing.rb +1 -5
- data/lib/nitro/compiler/script.rb +2 -4
- data/lib/nitro/compiler/squeeze.rb +0 -2
- data/lib/nitro/compiler/xslt.rb +0 -2
- data/lib/nitro/context.rb +10 -5
- data/lib/nitro/control.rb +18 -0
- data/lib/nitro/control/attribute.rb +88 -0
- data/lib/nitro/control/attribute/checkbox.rb +19 -0
- data/lib/nitro/control/attribute/datetime.rb +21 -0
- data/lib/nitro/control/attribute/file.rb +20 -0
- data/lib/nitro/control/attribute/fixnum.rb +26 -0
- data/lib/nitro/control/attribute/float.rb +26 -0
- data/lib/nitro/control/attribute/options.rb +38 -0
- data/lib/nitro/control/attribute/password.rb +16 -0
- data/lib/nitro/control/attribute/text.rb +16 -0
- data/lib/nitro/control/attribute/textarea.rb +16 -0
- data/lib/nitro/control/none.rb +16 -0
- data/lib/nitro/control/relation.rb +53 -0
- data/lib/nitro/control/relation/belongs_to.rb +0 -0
- data/lib/nitro/control/relation/has_many.rb +97 -0
- data/lib/nitro/control/relation/joins_many.rb +0 -0
- data/lib/nitro/control/relation/many_to_many.rb +0 -0
- data/lib/nitro/control/relation/refers_to.rb +29 -0
- data/lib/nitro/controller.rb +7 -296
- data/lib/nitro/dispatcher.rb +72 -34
- data/lib/nitro/element.rb +36 -10
- data/lib/nitro/element/javascript.rb +0 -2
- data/lib/nitro/flash.rb +23 -10
- data/lib/nitro/global.rb +36 -11
- data/lib/nitro/helper.rb +22 -8
- data/lib/nitro/helper/benchmark.rb +0 -2
- data/lib/nitro/helper/buffer.rb +0 -3
- data/lib/nitro/helper/css.rb +12 -0
- data/lib/nitro/helper/debug.rb +1 -3
- data/lib/nitro/helper/default.rb +1 -0
- data/lib/nitro/helper/feed.rb +400 -386
- data/lib/nitro/helper/form.rb +246 -116
- data/lib/nitro/helper/javascript.rb +28 -2
- data/lib/nitro/helper/javascript/morphing.rb +0 -2
- data/lib/nitro/helper/javascript/prototype.rb +0 -2
- data/lib/nitro/helper/javascript/scriptaculous.rb +0 -1
- data/lib/nitro/helper/layout.rb +0 -2
- data/lib/nitro/helper/navigation.rb +87 -0
- data/lib/nitro/helper/pager.rb +11 -22
- data/lib/nitro/helper/table.rb +9 -32
- data/lib/nitro/helper/url.rb +104 -0
- data/lib/nitro/helper/xhtml.rb +20 -4
- data/lib/nitro/helper/xml.rb +0 -2
- data/lib/nitro/markup.rb +131 -0
- data/lib/nitro/part.rb +52 -7
- data/lib/nitro/publishable.rb +328 -0
- data/lib/nitro/render.rb +30 -61
- data/lib/nitro/router.rb +12 -4
- data/lib/nitro/sanitize.rb +48 -0
- data/lib/nitro/scaffold.rb +9 -11
- data/lib/nitro/scaffold/controller.rb +25 -0
- data/lib/nitro/scaffold/model.rb +150 -0
- data/lib/nitro/scaffolding.rb +1 -3
- data/lib/nitro/server.rb +57 -32
- data/lib/nitro/server/drb.rb +16 -2
- data/lib/nitro/server/runner.rb +80 -102
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/service/xmlrpc.rb +0 -2
- data/lib/nitro/session.rb +26 -18
- data/lib/nitro/session/drb.rb +2 -16
- data/lib/nitro/session/memory.rb +0 -2
- data/lib/nitro/template.rb +219 -0
- data/lib/nitro/test/assertions.rb +1 -3
- data/lib/nitro/test/context.rb +0 -1
- data/lib/nitro/test/testcase.rb +0 -1
- data/lib/nitro/version.rb +6 -0
- data/lib/part/admin.rb +16 -0
- data/lib/part/admin/controller.rb +19 -0
- data/lib/part/admin/helper.rb +30 -0
- data/lib/part/admin/og/controller.rb +114 -0
- data/lib/part/admin/og/customize.rb +4 -0
- data/lib/part/admin/og/template/index.xhtml +27 -0
- data/lib/part/admin/og/template/list.xhtml +38 -0
- data/lib/part/admin/og/template/search.xhtml +20 -0
- data/lib/part/admin/og/template/update.xhtml +25 -0
- data/lib/part/admin/skin.rb +207 -0
- data/lib/part/admin/template/denied.xhtml +13 -0
- data/lib/part/admin/template/index.xhtml +12 -0
- data/lib/part/admin/todo.txt +2 -0
- data/proto/public/error.xhtml +4 -2
- data/proto/run.rb +0 -2
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/cgi/tc_request.rb +23 -0
- data/test/nitro/helper/tc_feed.rb +0 -3
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_table.rb +2 -0
- data/test/nitro/tc_cgi.rb +72 -19
- data/test/nitro/tc_controller.rb +35 -26
- data/test/nitro/tc_controller_aspect.rb +1 -0
- data/test/nitro/tc_controller_params.rb +864 -0
- data/test/nitro/tc_dispatcher.rb +2 -2
- data/test/nitro/tc_element.rb +16 -16
- data/test/nitro/tc_flash.rb +3 -3
- data/test/nitro/tc_markup.rb +31 -0
- data/test/nitro/tc_render.rb +12 -14
- data/test/nitro/tc_session.rb +9 -7
- data/test/nitro/tc_template.rb +34 -0
- metadata +217 -198
- data/INSTALL +0 -121
- data/ProjectInfo +0 -74
- data/README +0 -555
- data/doc/apache.txt +0 -9
- data/doc/config.txt +0 -28
- data/doc/faq.txt +0 -7
- data/doc/lhttpd.txt +0 -7
- data/lib/nitro/adapter/scgi.rb +0 -239
- data/lib/nitro/helper/form/builder.rb +0 -144
- data/lib/nitro/helper/form/controls.rb +0 -389
- data/lib/nitro/helper/rss.rb +0 -72
- data/proto/conf/apache.conf +0 -51
- data/proto/public/scaffold/advanced_search.xhtml +0 -30
- data/proto/public/scaffold/edit.xhtml +0 -11
- data/proto/public/scaffold/form.xhtml +0 -1
- data/proto/public/scaffold/index.xhtml +0 -20
- data/proto/public/scaffold/list.xhtml +0 -32
- data/proto/public/scaffold/new.xhtml +0 -11
- data/proto/public/scaffold/search.xhtml +0 -29
- data/proto/public/scaffold/view.xhtml +0 -8
- data/proto/script/scgi_ctl +0 -221
- data/proto/script/scgi_service +0 -128
- data/setup.rb +0 -1585
- data/src/part/admin.rb +0 -16
- data/src/part/admin/controller.rb +0 -81
- data/src/part/admin/skin.rb +0 -21
- data/src/part/admin/system.css +0 -135
- data/src/part/admin/template/denied.xhtml +0 -1
- data/src/part/admin/template/index.xhtml +0 -43
- data/test/nitro/helper/tc_rss.rb +0 -24
data/lib/nitro/part.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'facets/core/class/descendents'
|
|
2
|
+
|
|
1
3
|
module Nitro
|
|
2
4
|
|
|
3
5
|
# A part is a module of reusable functionality encapsulated as
|
|
@@ -58,18 +60,61 @@ module Nitro
|
|
|
58
60
|
# 'inherits' its templates. If you want to customize (override)
|
|
59
61
|
# one template, just place a template with the same name in the
|
|
60
62
|
# respective directory in the application template root.
|
|
61
|
-
|
|
63
|
+
#
|
|
64
|
+
#--
|
|
65
|
+
# TODO:
|
|
66
|
+
#
|
|
67
|
+
# * add support for autoload
|
|
68
|
+
# * add support for install/uninstall
|
|
69
|
+
#++
|
|
70
|
+
|
|
62
71
|
class Part
|
|
63
72
|
|
|
64
|
-
#
|
|
73
|
+
# Perform part initialization, just before the server is
|
|
74
|
+
# started. Override this in your parts.
|
|
75
|
+
|
|
76
|
+
def initialize
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Perform part finalization.
|
|
80
|
+
|
|
81
|
+
def finalize
|
|
82
|
+
end
|
|
65
83
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
84
|
+
# Perform part initialization when the part is installed,
|
|
85
|
+
# ie you add this in your application. Here comes one time
|
|
86
|
+
# initialization code.
|
|
87
|
+
|
|
88
|
+
def install
|
|
69
89
|
end
|
|
90
|
+
|
|
91
|
+
# Perform part cleanup when you want to remove the part
|
|
92
|
+
# from your application.
|
|
93
|
+
|
|
94
|
+
def uninstall
|
|
95
|
+
end
|
|
96
|
+
alias cleanup uninstall
|
|
70
97
|
|
|
71
|
-
|
|
98
|
+
class << self
|
|
99
|
+
|
|
100
|
+
# Require (include) a part in the current application.
|
|
101
|
+
|
|
102
|
+
def require(name)
|
|
103
|
+
Logger.debug "Requiring part '#{name}'." if $DBG
|
|
104
|
+
Kernel.require 'part/' + name + '/run.rb'
|
|
105
|
+
end
|
|
72
106
|
|
|
107
|
+
# Call the initialization code of all parts. Typically
|
|
108
|
+
# called just before the server starts.
|
|
109
|
+
|
|
110
|
+
def setup
|
|
111
|
+
for klass in self.descendents
|
|
112
|
+
p = klass.new
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
73
118
|
end
|
|
74
119
|
|
|
75
|
-
|
|
120
|
+
end
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
require 'facets/more/annotation'
|
|
2
|
+
require 'facets/more/inheritor'
|
|
3
|
+
require 'facets/more/aspects'
|
|
4
|
+
|
|
5
|
+
require 'nitro/markup'
|
|
6
|
+
|
|
7
|
+
require 'nitro'
|
|
8
|
+
require 'nitro/render'
|
|
9
|
+
require 'nitro/scaffolding'
|
|
10
|
+
require 'nitro/caching'
|
|
11
|
+
require 'nitro/flash'
|
|
12
|
+
require 'nitro/helper'
|
|
13
|
+
require 'nitro/compiler'
|
|
14
|
+
|
|
15
|
+
module Nitro
|
|
16
|
+
|
|
17
|
+
# Include this Mixin to a class to make objects of this class
|
|
18
|
+
# publishable, ie accessible through a standard web (REST)
|
|
19
|
+
# interface.
|
|
20
|
+
#
|
|
21
|
+
# === Instance variables
|
|
22
|
+
#
|
|
23
|
+
# ==== mount_path
|
|
24
|
+
#
|
|
25
|
+
# Where the publishable is mounted.
|
|
26
|
+
#
|
|
27
|
+
# ==== template_root
|
|
28
|
+
#
|
|
29
|
+
# Where to look for templates for this publishable
|
|
30
|
+
# object / controller. The template root is actually a stack
|
|
31
|
+
# to implement some form of template root inheritance,
|
|
32
|
+
# thus allowing for more reusable controllers. Ie you can
|
|
33
|
+
# 'extend' a controller, and only override the templates
|
|
34
|
+
# you want to change. The compiler will traverse the
|
|
35
|
+
# template root stack and use the templates from parent
|
|
36
|
+
# controllers if they are not overriden.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
module Publishable
|
|
40
|
+
|
|
41
|
+
def self.included(base)
|
|
42
|
+
super
|
|
43
|
+
|
|
44
|
+
base.module_eval do
|
|
45
|
+
include Render
|
|
46
|
+
include Aspects
|
|
47
|
+
include Flashing
|
|
48
|
+
include Helpers
|
|
49
|
+
|
|
50
|
+
# The collection of 'models' ie classes that are linked
|
|
51
|
+
# to this Publishable/Controller.
|
|
52
|
+
|
|
53
|
+
ann :self, :models => []
|
|
54
|
+
|
|
55
|
+
# This is a helper that 'links' one or more classes to this
|
|
56
|
+
# controller. In practice it annotates each class with the
|
|
57
|
+
# controller and stores the controller's list of 'models'.
|
|
58
|
+
|
|
59
|
+
def self.model *classes
|
|
60
|
+
for c in classes
|
|
61
|
+
c.ann :self, :controller => self
|
|
62
|
+
self.ann.self.models! << c
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Aliases an action
|
|
68
|
+
#--
|
|
69
|
+
# gmosx, FIXME: better implementation needed.
|
|
70
|
+
# gmosx, FIXME: copy all annotations.
|
|
71
|
+
#++
|
|
72
|
+
|
|
73
|
+
base.module_eval do
|
|
74
|
+
def self.alias_action(new, old)
|
|
75
|
+
alias_method new, old
|
|
76
|
+
ann new, :template => old
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Return the 'action' methods for this Controller.
|
|
81
|
+
# Some dangerous methods from ancestors are removed.
|
|
82
|
+
# All private methods are ignored.
|
|
83
|
+
|
|
84
|
+
base.module_eval do
|
|
85
|
+
def self.action_methods
|
|
86
|
+
classes = self.ancestors - [Object, Kernel, Render, Controller, Caching]
|
|
87
|
+
|
|
88
|
+
classes.delete(PP::ObjectMixin) if defined?(PP::ObjectMixin)
|
|
89
|
+
|
|
90
|
+
methods = classes.inject([]) do |action_methods, klass|
|
|
91
|
+
action_methods + klass.public_instance_methods(false)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return methods
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Use the method_missing hook to compile the actions
|
|
99
|
+
# for this controller.
|
|
100
|
+
|
|
101
|
+
base.module_eval do
|
|
102
|
+
def method_missing(action, *args)
|
|
103
|
+
if Compiler.new(self.class).compile(action)
|
|
104
|
+
send(action, *args)
|
|
105
|
+
else
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Does this publishable respond to the given action?
|
|
112
|
+
|
|
113
|
+
base.module_eval do
|
|
114
|
+
class << self
|
|
115
|
+
def respond_to_action?(action)
|
|
116
|
+
action_methods.include?(action.to_s)
|
|
117
|
+
end
|
|
118
|
+
alias action? respond_to_action?
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Does this publishable respond to the given template?
|
|
123
|
+
|
|
124
|
+
base.module_eval do
|
|
125
|
+
class << self
|
|
126
|
+
def respond_to_template?(action)
|
|
127
|
+
Compiler.new(self).template?(action.to_s)
|
|
128
|
+
end
|
|
129
|
+
alias template? respond_to_template?
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Does this class respond to the given action?
|
|
134
|
+
# Also looks for templates in the template root.
|
|
135
|
+
#
|
|
136
|
+
# Prefer to use the compiler for this.
|
|
137
|
+
#--
|
|
138
|
+
# THINK: maybe move template? here
|
|
139
|
+
#++
|
|
140
|
+
|
|
141
|
+
base.module_eval do
|
|
142
|
+
class << self
|
|
143
|
+
def respond_to_action_or_template?(sym)
|
|
144
|
+
#--
|
|
145
|
+
# gmosx, FIXME: optimize this!
|
|
146
|
+
#++
|
|
147
|
+
return self.respond_to_action?(sym) || self.respond_to_template?(sym)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
base.module_eval do
|
|
153
|
+
class << self
|
|
154
|
+
# Override this method to customize the template_root.
|
|
155
|
+
# Typically used in controllers defined in reusable Parts.
|
|
156
|
+
# Call super to include the parent class's customizations.
|
|
157
|
+
#
|
|
158
|
+
# def setup_template_root(path)
|
|
159
|
+
# super
|
|
160
|
+
# @template_root << "custom/route/#{path}"
|
|
161
|
+
# @template_root << "another/route/#{path}"
|
|
162
|
+
# end
|
|
163
|
+
|
|
164
|
+
def setup_template_root(path)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def mount_at(path)
|
|
168
|
+
# Store the mount_path (where the controller is mounted).
|
|
169
|
+
|
|
170
|
+
@mount_path = path
|
|
171
|
+
|
|
172
|
+
# Update template_root. Unshift the PROTO_TEMPLATE_ROOT,
|
|
173
|
+
# and unshift a template_root relative to the
|
|
174
|
+
# application template root.
|
|
175
|
+
|
|
176
|
+
@template_root = []
|
|
177
|
+
@template_root << File.join(Compiler::PROTO_TEMPLATE_ROOT, path).gsub(/\/$/, '')
|
|
178
|
+
setup_template_root(path)
|
|
179
|
+
@template_root << File.join(Nitro::Template.root, path).gsub(/\/$/, '')
|
|
180
|
+
@template_root.reverse!
|
|
181
|
+
end
|
|
182
|
+
alias_method :mount, :mount_at
|
|
183
|
+
|
|
184
|
+
# Returns the path where this controller is mounted.
|
|
185
|
+
|
|
186
|
+
def mount_path
|
|
187
|
+
@mount_path
|
|
188
|
+
end
|
|
189
|
+
alias mount_point mount_path
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
private
|
|
196
|
+
|
|
197
|
+
# Cookie helpers.
|
|
198
|
+
#--
|
|
199
|
+
# TODO: move elsewhere, probably to a default helper.
|
|
200
|
+
#++
|
|
201
|
+
|
|
202
|
+
def cookies
|
|
203
|
+
@context.cookies
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Send the cookie to the response stream.
|
|
207
|
+
|
|
208
|
+
def send_cookie(name, value = nil)
|
|
209
|
+
@context.add_cookie(name, value)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Delete the cookie by setting the expire time to now and
|
|
213
|
+
# clearing the value.
|
|
214
|
+
|
|
215
|
+
def delete_cookie(name)
|
|
216
|
+
cookie = Cookie.new(name, '')
|
|
217
|
+
cookie.expires = Time.now
|
|
218
|
+
@context.add_cookie(cookie)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Encode controller, action, params into a valid url.
|
|
222
|
+
# Automatically respects nice urls and routing.
|
|
223
|
+
#
|
|
224
|
+
# Handles parameters either as a hash or as an array.
|
|
225
|
+
# Use the array method to pass parameters to 'nice' actions.
|
|
226
|
+
#
|
|
227
|
+
# Pass Controller, action, and (param_name, param_value)
|
|
228
|
+
# pairs.
|
|
229
|
+
#
|
|
230
|
+
# === Examples
|
|
231
|
+
#
|
|
232
|
+
# encode_url ForaController, :post, :title, 'Hello', :body, 'World'
|
|
233
|
+
# encode_url :post, :title, 'Hello', :body, 'World' # => implies controller == self
|
|
234
|
+
# encode_url :kick, :oid, 4
|
|
235
|
+
# encode_url article # => article.to_href
|
|
236
|
+
#
|
|
237
|
+
# Alternatively you can pass options with a hash:
|
|
238
|
+
#
|
|
239
|
+
# encode_url :controller => ForaController, :action => :delete, :params => { :title => 'Hello' }
|
|
240
|
+
# encode_url :action => :delete
|
|
241
|
+
#--
|
|
242
|
+
# FIXME: better implementation? optimize this?
|
|
243
|
+
# TODO: move elsewhere.
|
|
244
|
+
#++
|
|
245
|
+
|
|
246
|
+
def encode_url(*args)
|
|
247
|
+
f = args.first
|
|
248
|
+
|
|
249
|
+
# A standard url as string, return as is.
|
|
250
|
+
|
|
251
|
+
if f.is_a? String
|
|
252
|
+
return f
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# If the passed param is an object that responds to :to_href
|
|
256
|
+
# returns the url to this object.
|
|
257
|
+
|
|
258
|
+
if f.respond_to? :to_href
|
|
259
|
+
return args.first.to_href
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
if f.is_a? Symbol
|
|
263
|
+
# no controller passed, imply controller == self!
|
|
264
|
+
args.unshift(self.class)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Try to encode using the router.
|
|
268
|
+
|
|
269
|
+
if url = context.dispatcher.encode_route(*args)
|
|
270
|
+
return url
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# No routing rule, manual encoding.
|
|
274
|
+
|
|
275
|
+
controller = args.shift
|
|
276
|
+
action = args.shift.to_sym
|
|
277
|
+
|
|
278
|
+
if action == :index
|
|
279
|
+
url = "#{controller.mount_path}"
|
|
280
|
+
else
|
|
281
|
+
mount_path = controller.mount_path
|
|
282
|
+
mount_path = nil if mount_path == '/'
|
|
283
|
+
url = "#{mount_path}/#{action}"
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
unless args.empty?
|
|
287
|
+
if controller.respond_to_action_or_template? action
|
|
288
|
+
param_count = controller.instance_method(action).arity
|
|
289
|
+
if param_count != 0
|
|
290
|
+
param_count.times do
|
|
291
|
+
args.shift # name
|
|
292
|
+
url << "/#{CGI.escape(args.shift.to_s)}"
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
unless args.empty?
|
|
298
|
+
url << '?'
|
|
299
|
+
params = []
|
|
300
|
+
(args.size / 2).times do
|
|
301
|
+
params << "#{args.shift}=#{args.shift}"
|
|
302
|
+
end
|
|
303
|
+
url << params.join(';')
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
return url
|
|
308
|
+
end
|
|
309
|
+
alias R encode_url
|
|
310
|
+
|
|
311
|
+
# Just like encode_url, but generates an absolute url instead.
|
|
312
|
+
|
|
313
|
+
def encode_absolute_url(*args)
|
|
314
|
+
return "#{request.host_url}#{encode_url(*args)}"
|
|
315
|
+
end
|
|
316
|
+
alias RA encode_absolute_url
|
|
317
|
+
|
|
318
|
+
# Allows instances of Publishable classes to know where they
|
|
319
|
+
# are mounted.
|
|
320
|
+
|
|
321
|
+
def mount_path
|
|
322
|
+
self.class.mount_path
|
|
323
|
+
end
|
|
324
|
+
alias mount_point mount_path
|
|
325
|
+
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|
data/lib/nitro/render.rb
CHANGED
|
@@ -5,7 +5,7 @@ require 'stringio'
|
|
|
5
5
|
require 'facet/string/blank'
|
|
6
6
|
|
|
7
7
|
require 'glue/settings'
|
|
8
|
-
require '
|
|
8
|
+
require 'nitro/template'
|
|
9
9
|
require 'glue/builder/xml'
|
|
10
10
|
|
|
11
11
|
require 'nitro/helper/xhtml'
|
|
@@ -84,10 +84,6 @@ module Render
|
|
|
84
84
|
|
|
85
85
|
attr_accessor :action_name
|
|
86
86
|
|
|
87
|
-
# The base url for this render.
|
|
88
|
-
|
|
89
|
-
attr_accessor :base
|
|
90
|
-
|
|
91
87
|
# The current controller class.
|
|
92
88
|
|
|
93
89
|
attr_accessor :controller
|
|
@@ -97,9 +93,8 @@ module Render
|
|
|
97
93
|
# [+context+]
|
|
98
94
|
# A parent render/controller acts as the context.
|
|
99
95
|
|
|
100
|
-
def initialize(context
|
|
96
|
+
def initialize(context)
|
|
101
97
|
@request = @response = @context = context
|
|
102
|
-
@base = base
|
|
103
98
|
@out = context.out
|
|
104
99
|
end
|
|
105
100
|
|
|
@@ -108,16 +103,16 @@ module Render
|
|
|
108
103
|
# controller.
|
|
109
104
|
#
|
|
110
105
|
# Both relative and absolute paths are supported. Relative
|
|
111
|
-
# paths are converted to absolute by prepending the
|
|
112
|
-
#
|
|
106
|
+
# paths are converted to absolute by prepending the mount path
|
|
107
|
+
# of the controller.
|
|
113
108
|
|
|
114
109
|
def render(path)
|
|
115
110
|
# Convert relative paths to absolute paths.
|
|
116
|
-
path = "
|
|
111
|
+
path = "#{self.class.mount_path}/#{path}".squeeze('/') unless path =~ /^\//
|
|
117
112
|
|
|
118
113
|
Logger.debug "Rendering '#{path}'." if $DBG
|
|
119
114
|
|
|
120
|
-
@controller, action
|
|
115
|
+
@controller, action = @context.dispatcher.dispatch(path.to_s, @context)
|
|
121
116
|
|
|
122
117
|
raise 'No controller for action' unless @controller
|
|
123
118
|
|
|
@@ -130,13 +125,13 @@ module Render
|
|
|
130
125
|
if self.class == @controller
|
|
131
126
|
self.send(action)
|
|
132
127
|
else
|
|
133
|
-
@controller.new(@context
|
|
128
|
+
@controller.new(@context).send(action)
|
|
134
129
|
end
|
|
135
130
|
|
|
136
131
|
Controller.replace_current(old_controller)
|
|
137
132
|
@context.level -= 1
|
|
138
133
|
|
|
139
|
-
rescue
|
|
134
|
+
rescue ActionError => e1
|
|
140
135
|
log_error(e1, path, false)
|
|
141
136
|
print '(error)'
|
|
142
137
|
|
|
@@ -200,6 +195,11 @@ private
|
|
|
200
195
|
# The default redirect status is 303.
|
|
201
196
|
|
|
202
197
|
def redirect(*args)
|
|
198
|
+
# If this is an ajax and/or rpc request skip the redirect.
|
|
199
|
+
# Allows to write more reusable code.
|
|
200
|
+
|
|
201
|
+
return if request.script?
|
|
202
|
+
|
|
203
203
|
if args.last.is_a? Hash
|
|
204
204
|
status = args.last.fetch(:status, 303)
|
|
205
205
|
else
|
|
@@ -209,9 +209,8 @@ private
|
|
|
209
209
|
url = encode_url(*args)
|
|
210
210
|
|
|
211
211
|
# gmosx, THINK: this may be unnecessary!
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
unless url =~ /^http/
|
|
214
|
-
url = "#@base/#{url}" unless url =~ /^\//
|
|
215
214
|
url = "#{@context.host_url}/#{url.gsub(/^\//, '')}"
|
|
216
215
|
end
|
|
217
216
|
|
|
@@ -239,42 +238,6 @@ private
|
|
|
239
238
|
end
|
|
240
239
|
alias_method :redirect_to_home, :redirect_home
|
|
241
240
|
|
|
242
|
-
# :section: Seaside style call/answer methods.
|
|
243
|
-
|
|
244
|
-
# Call redirects to the given url but push the original
|
|
245
|
-
# url in a callstack, so that the target can return by
|
|
246
|
-
# executing answer.
|
|
247
|
-
#
|
|
248
|
-
# === Example
|
|
249
|
-
#
|
|
250
|
-
# caller:
|
|
251
|
-
# color, type = call 'utils/select_color'
|
|
252
|
-
#
|
|
253
|
-
# target:
|
|
254
|
-
# answer color, type
|
|
255
|
-
#--
|
|
256
|
-
# FIXME: dont use yet, you have to encode the branch to
|
|
257
|
-
# make this safe for use.
|
|
258
|
-
#++
|
|
259
|
-
|
|
260
|
-
def call(url, status = 303)
|
|
261
|
-
(session[:CALL_STACK] ||= {}) << request.uri
|
|
262
|
-
redirect(url, status)
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
# Returns from a call by poping the callstack.
|
|
266
|
-
#--
|
|
267
|
-
# FIXME: don't use yet.
|
|
268
|
-
#++
|
|
269
|
-
|
|
270
|
-
def answer(index = 0, status = 303)
|
|
271
|
-
if stack = session[:CALL_STACK] and not stack.empty?
|
|
272
|
-
redirect(stack.pop, status)
|
|
273
|
-
else
|
|
274
|
-
raise 'Cannot answer, call stack is empty'
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
|
|
278
241
|
# Log a rendering error.
|
|
279
242
|
|
|
280
243
|
def log_error(error, path, full = true)
|
|
@@ -305,20 +268,28 @@ private
|
|
|
305
268
|
alias_method :print, :render_text
|
|
306
269
|
|
|
307
270
|
# Render a template into the output buffer.
|
|
308
|
-
|
|
309
|
-
def render_template(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
271
|
+
=begin
|
|
272
|
+
def render_template(*args)
|
|
273
|
+
url = encode_url(*args)
|
|
274
|
+
filename = "#{url}.xhtml" unless url =~ /\.xhtml$/
|
|
275
|
+
template = File.read(File.join(Template.root, filename))
|
|
276
|
+
Template.process_template(template, '@out', binding)
|
|
313
277
|
end
|
|
278
|
+
=end
|
|
314
279
|
|
|
280
|
+
def render_template(path)
|
|
281
|
+
render(path)
|
|
282
|
+
exit
|
|
283
|
+
end
|
|
284
|
+
alias_method :template, :render_template
|
|
285
|
+
|
|
315
286
|
# Access the programmatic renderer (builder).
|
|
316
287
|
|
|
317
288
|
def build(&block)
|
|
318
289
|
if block.arity == 1
|
|
319
|
-
yield
|
|
290
|
+
yield XmlBuilder.new(@out)
|
|
320
291
|
else
|
|
321
|
-
|
|
292
|
+
XmlBuilder.new(@out).instance_eval(&block)
|
|
322
293
|
end
|
|
323
294
|
end
|
|
324
295
|
|
|
@@ -326,7 +297,7 @@ private
|
|
|
326
297
|
# output buffer.
|
|
327
298
|
|
|
328
299
|
def builder
|
|
329
|
-
|
|
300
|
+
XmlBuilder.new(@out)
|
|
330
301
|
end
|
|
331
302
|
|
|
332
303
|
# A Helper class to access rendering mixins. Useful to avoid
|
|
@@ -356,5 +327,3 @@ private
|
|
|
356
327
|
end
|
|
357
328
|
|
|
358
329
|
end
|
|
359
|
-
|
|
360
|
-
# * George Moschovitis <gm@navel.gr>
|