raw 0.49.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/CONTRIBUTORS +106 -0
- data/doc/LICENSE +32 -0
- data/doc/coding_conventions.txt +11 -0
- data/lib/raw.rb +42 -0
- data/lib/raw/adapter.rb +113 -0
- data/lib/raw/adapter/cgi.rb +41 -0
- data/lib/raw/adapter/fastcgi.rb +48 -0
- data/lib/raw/adapter/mongrel.rb +146 -0
- data/lib/raw/adapter/script.rb +94 -0
- data/lib/raw/adapter/webrick.rb +144 -0
- data/lib/raw/adapter/webrick/vcr.rb +91 -0
- data/lib/raw/cgi.rb +323 -0
- data/lib/raw/cgi/cookie.rb +47 -0
- data/lib/raw/cgi/http.rb +62 -0
- data/lib/raw/compiler.rb +138 -0
- data/lib/raw/compiler/filter/cleanup.rb +21 -0
- data/lib/raw/compiler/filter/elements.rb +166 -0
- data/lib/raw/compiler/filter/elements/element.rb +210 -0
- data/lib/raw/compiler/filter/localization.rb +23 -0
- data/lib/raw/compiler/filter/markup.rb +32 -0
- data/lib/raw/compiler/filter/morph.rb +123 -0
- data/lib/raw/compiler/filter/morph/each.rb +34 -0
- data/lib/raw/compiler/filter/morph/for.rb +11 -0
- data/lib/raw/compiler/filter/morph/if.rb +26 -0
- data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
- data/lib/raw/compiler/filter/morph/standard.rb +55 -0
- data/lib/raw/compiler/filter/morph/times.rb +27 -0
- data/lib/raw/compiler/filter/script.rb +116 -0
- data/lib/raw/compiler/filter/squeeze.rb +16 -0
- data/lib/raw/compiler/filter/static_include.rb +74 -0
- data/lib/raw/compiler/filter/template.rb +121 -0
- data/lib/raw/compiler/reloader.rb +96 -0
- data/lib/raw/context.rb +154 -0
- data/lib/raw/context/flash.rb +157 -0
- data/lib/raw/context/global.rb +88 -0
- data/lib/raw/context/request.rb +338 -0
- data/lib/raw/context/response.rb +57 -0
- data/lib/raw/context/session.rb +198 -0
- data/lib/raw/context/session/drb.rb +11 -0
- data/lib/raw/context/session/file.rb +15 -0
- data/lib/raw/context/session/memcached.rb +13 -0
- data/lib/raw/context/session/memory.rb +12 -0
- data/lib/raw/context/session/og.rb +15 -0
- data/lib/raw/context/session/pstore.rb +13 -0
- data/lib/raw/control.rb +18 -0
- data/lib/raw/control/attribute.rb +91 -0
- data/lib/raw/control/attribute/checkbox.rb +25 -0
- data/lib/raw/control/attribute/datetime.rb +21 -0
- data/lib/raw/control/attribute/file.rb +20 -0
- data/lib/raw/control/attribute/fixnum.rb +26 -0
- data/lib/raw/control/attribute/float.rb +26 -0
- data/lib/raw/control/attribute/options.rb +38 -0
- data/lib/raw/control/attribute/password.rb +16 -0
- data/lib/raw/control/attribute/text.rb +16 -0
- data/lib/raw/control/attribute/textarea.rb +16 -0
- data/lib/raw/control/none.rb +16 -0
- data/lib/raw/control/relation.rb +59 -0
- data/lib/raw/control/relation/belongs_to.rb +0 -0
- data/lib/raw/control/relation/has_many.rb +97 -0
- data/lib/raw/control/relation/joins_many.rb +0 -0
- data/lib/raw/control/relation/many_to_many.rb +0 -0
- data/lib/raw/control/relation/refers_to.rb +29 -0
- data/lib/raw/controller.rb +37 -0
- data/lib/raw/controller/publishable.rb +160 -0
- data/lib/raw/dispatcher.rb +209 -0
- data/lib/raw/dispatcher/format.rb +108 -0
- data/lib/raw/dispatcher/format/atom.rb +31 -0
- data/lib/raw/dispatcher/format/css.rb +0 -0
- data/lib/raw/dispatcher/format/html.rb +42 -0
- data/lib/raw/dispatcher/format/json.rb +31 -0
- data/lib/raw/dispatcher/format/rss.rb +33 -0
- data/lib/raw/dispatcher/format/xoxo.rb +31 -0
- data/lib/raw/dispatcher/mounter.rb +60 -0
- data/lib/raw/dispatcher/router.rb +111 -0
- data/lib/raw/errors.rb +19 -0
- data/lib/raw/helper.rb +86 -0
- data/lib/raw/helper/benchmark.rb +23 -0
- data/lib/raw/helper/buffer.rb +60 -0
- data/lib/raw/helper/cookie.rb +32 -0
- data/lib/raw/helper/debug.rb +28 -0
- data/lib/raw/helper/default.rb +16 -0
- data/lib/raw/helper/feed.rb +451 -0
- data/lib/raw/helper/form.rb +284 -0
- data/lib/raw/helper/javascript.rb +59 -0
- data/lib/raw/helper/layout.rb +40 -0
- data/lib/raw/helper/navigation.rb +87 -0
- data/lib/raw/helper/pager.rb +305 -0
- data/lib/raw/helper/table.rb +247 -0
- data/lib/raw/helper/xhtml.rb +218 -0
- data/lib/raw/helper/xml.rb +125 -0
- data/lib/raw/mixin/magick.rb +35 -0
- data/lib/raw/mixin/sweeper.rb +71 -0
- data/lib/raw/mixin/thumbnails.rb +1 -0
- data/lib/raw/mixin/webfile.rb +165 -0
- data/lib/raw/render.rb +271 -0
- data/lib/raw/render/builder.rb +26 -0
- data/lib/raw/render/caching.rb +81 -0
- data/lib/raw/render/call.rb +43 -0
- data/lib/raw/render/send_file.rb +46 -0
- data/lib/raw/render/stream.rb +39 -0
- data/lib/raw/scaffold.rb +13 -0
- data/lib/raw/scaffold/controller.rb +25 -0
- data/lib/raw/scaffold/model.rb +157 -0
- data/lib/raw/test.rb +5 -0
- data/lib/raw/test/assertions.rb +169 -0
- data/lib/raw/test/context.rb +55 -0
- data/lib/raw/test/testcase.rb +79 -0
- data/lib/raw/util/attr.rb +128 -0
- data/lib/raw/util/encode_uri.rb +149 -0
- data/lib/raw/util/html_filter.rb +538 -0
- data/lib/raw/util/markup.rb +130 -0
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/CONFIG.rb +3 -0
- data/test/nitro/adapter/raw_post1.bin +9 -0
- data/test/nitro/adapter/tc_webrick.rb +16 -0
- data/test/nitro/cgi/tc_cookie.rb +14 -0
- data/test/nitro/cgi/tc_request.rb +61 -0
- data/test/nitro/compiler/tc_client_morpher.rb +47 -0
- data/test/nitro/compiler/tc_compiler.rb +25 -0
- data/test/nitro/dispatcher/tc_mounter.rb +47 -0
- data/test/nitro/helper/tc_feed.rb +135 -0
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_pager.rb +35 -0
- data/test/nitro/helper/tc_table.rb +68 -0
- data/test/nitro/helper/tc_xhtml.rb +19 -0
- data/test/nitro/tc_caching.rb +19 -0
- data/test/nitro/tc_cgi.rb +222 -0
- data/test/nitro/tc_context.rb +17 -0
- data/test/nitro/tc_controller.rb +103 -0
- data/test/nitro/tc_controller_aspect.rb +32 -0
- data/test/nitro/tc_controller_params.rb +885 -0
- data/test/nitro/tc_dispatcher.rb +109 -0
- data/test/nitro/tc_element.rb +85 -0
- data/test/nitro/tc_flash.rb +59 -0
- data/test/nitro/tc_helper.rb +47 -0
- data/test/nitro/tc_render.rb +119 -0
- data/test/nitro/tc_router.rb +61 -0
- data/test/nitro/tc_server.rb +35 -0
- data/test/nitro/tc_session.rb +66 -0
- data/test/nitro/tc_template.rb +71 -0
- data/test/nitro/util/tc_encode_url.rb +87 -0
- data/test/nitro/util/tc_markup.rb +31 -0
- data/test/public/blog/another/very_litle/index.xhtml +1 -0
- data/test/public/blog/inc1.xhtml +2 -0
- data/test/public/blog/inc2.xhtml +1 -0
- data/test/public/blog/list.xhtml +9 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- metadata +244 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
require "facets/more/ann"
|
2
|
+
|
3
|
+
require "raw/render"
|
4
|
+
require "raw/render/caching"
|
5
|
+
require "raw/context/flash"
|
6
|
+
require "raw/helper"
|
7
|
+
require "raw/helper/cookie"
|
8
|
+
require "raw/compiler"
|
9
|
+
require "raw/compiler/filter/template"
|
10
|
+
require "raw/util/encode_uri"
|
11
|
+
require "raw/util/markup"
|
12
|
+
|
13
|
+
module Raw
|
14
|
+
|
15
|
+
# Include this Mixin to a class to make objects of this class
|
16
|
+
# publishable, ie accessible through a standard web (REST)
|
17
|
+
# interface.
|
18
|
+
|
19
|
+
module Publishable
|
20
|
+
def self.included(base)
|
21
|
+
super
|
22
|
+
base.send(:include, Render)
|
23
|
+
base.send(:include, Flashing)
|
24
|
+
base.send(:include, Caching)
|
25
|
+
base.send(:include, Helpers)
|
26
|
+
base.helper(EncodeURI)
|
27
|
+
base.helper(CookieHelper)
|
28
|
+
base.helper(Markup)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Use the method_missing hook to compile the actions
|
32
|
+
# for this controller.
|
33
|
+
|
34
|
+
def method_missing(action, *args)
|
35
|
+
if Context.current.application.compiler.compile(self.class, action)
|
36
|
+
send(action, *args)
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class_extension do
|
43
|
+
|
44
|
+
# The path where this controller is mounted.
|
45
|
+
|
46
|
+
attr_accessor :mount_path
|
47
|
+
|
48
|
+
# Return the 'action' methods for this Object. Some
|
49
|
+
# dangerous methods from ancestors are removed. All private
|
50
|
+
# methods are ignored.
|
51
|
+
#--
|
52
|
+
# gmosx, TODO: We should optimize this method.
|
53
|
+
#++
|
54
|
+
|
55
|
+
def action_methods
|
56
|
+
public_instance_methods - Controller.public_instance_methods
|
57
|
+
end
|
58
|
+
alias_method :actions, :action_methods
|
59
|
+
|
60
|
+
# Check if the controller responds to this action.
|
61
|
+
|
62
|
+
def action?(action)
|
63
|
+
action_methods.include?(action.to_s)
|
64
|
+
end
|
65
|
+
alias_method :respond_to_action?, :action?
|
66
|
+
|
67
|
+
# Check if the a template for this action and format exists.
|
68
|
+
# Returns a valid path or nil.
|
69
|
+
|
70
|
+
def template?(action, format)
|
71
|
+
# Allow for template override using the :template annotation
|
72
|
+
#
|
73
|
+
# class MyController
|
74
|
+
# def myaction
|
75
|
+
# end
|
76
|
+
# ann :myaction, :template => :another_template
|
77
|
+
# end
|
78
|
+
|
79
|
+
template = ann(action, :template) || action
|
80
|
+
|
81
|
+
template = template.to_s.gsub(/__/, "/")
|
82
|
+
|
83
|
+
for dir in ann(:self, :template_dir_stack)
|
84
|
+
name = "#{dir}/#{template}".squeeze("/")
|
85
|
+
|
86
|
+
# attempt to find a template of the form:
|
87
|
+
# dir/action.xhtml
|
88
|
+
|
89
|
+
path = "#{name}.#{format.template_extension}"
|
90
|
+
return path if File.exist?(path)
|
91
|
+
|
92
|
+
# attempt to find a template of the form:
|
93
|
+
# dir/action/index.xhtml
|
94
|
+
|
95
|
+
path = "#{name}/index.#{format.template_extension}"
|
96
|
+
return path if File.exist?(path)
|
97
|
+
end
|
98
|
+
|
99
|
+
return nil
|
100
|
+
end
|
101
|
+
alias_method :has_template?, :template?
|
102
|
+
alias_method :template_path, :template?
|
103
|
+
|
104
|
+
# Check if this action or template exists.
|
105
|
+
|
106
|
+
def action_or_template?(action, format)
|
107
|
+
action?(action) or template?(action, format)
|
108
|
+
end
|
109
|
+
alias_method :respond_to_action_or_template?, :action_or_template?
|
110
|
+
|
111
|
+
# Aliases an action
|
112
|
+
#--
|
113
|
+
# gmosx, FIXME: better implementation needed.
|
114
|
+
# gmosx, FIXME: copy all annotations.
|
115
|
+
#++
|
116
|
+
|
117
|
+
def alias_action(new, old)
|
118
|
+
alias_method new, old
|
119
|
+
ann new, :template => old
|
120
|
+
end
|
121
|
+
|
122
|
+
# Override this method to customize the template_dir_stack.
|
123
|
+
# Typically used in controllers defined in reusable Parts.
|
124
|
+
# Call super to include the parent class's customizations.
|
125
|
+
# Implements some form of template root inheritance,
|
126
|
+
# thus allowing for more reusable controllers. Ie you can
|
127
|
+
# 'extend' a controller, and only override the templates
|
128
|
+
# you want to change. The compiler will traverse the
|
129
|
+
# template dir stack and use the templates from parent
|
130
|
+
# controllers if they are not overriden.
|
131
|
+
#
|
132
|
+
# def self.setup_template_dir_stack(stack)
|
133
|
+
# super
|
134
|
+
# stack << "custom/route/#{self.mount_path}"
|
135
|
+
# stack << "another/route"
|
136
|
+
# end
|
137
|
+
|
138
|
+
def setup_template_dir_stack(path)
|
139
|
+
end
|
140
|
+
|
141
|
+
# This callback is called when this controller is mounted.
|
142
|
+
|
143
|
+
def mount_at(path)
|
144
|
+
@mount_path = path
|
145
|
+
|
146
|
+
# Setup the template_dir_stack.
|
147
|
+
|
148
|
+
stack = []
|
149
|
+
stack << File.join(Template.root_dir, path).gsub(/\/$/, "")
|
150
|
+
self.setup_template_dir_stack(stack)
|
151
|
+
stack << File.join(Nitro.proto_path, "template", path).gsub(/\/$/, "")
|
152
|
+
ann(:self, :template_dir_stack => stack)
|
153
|
+
end
|
154
|
+
alias_method :mount, :mount_at
|
155
|
+
|
156
|
+
end # class_extension
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require "facets/core/module/ancestor"
|
2
|
+
|
3
|
+
require "raw/dispatcher/router"
|
4
|
+
require "raw/dispatcher/mounter"
|
5
|
+
require "raw/dispatcher/format"
|
6
|
+
|
7
|
+
module Raw
|
8
|
+
|
9
|
+
# The Dispatcher manages a set of controllers. It selects the
|
10
|
+
# appropriate Controller and action to handle the given
|
11
|
+
# request.
|
12
|
+
#
|
13
|
+
# This dispatcher intelligently handles RESTful uris according
|
14
|
+
# to the following scheme:
|
15
|
+
#
|
16
|
+
# GET /links GET /links/index Link::Controller#index
|
17
|
+
# POST /links POST /links/create Link::Controller#create
|
18
|
+
# GET /links;new GET /links/new Link::Controller#new
|
19
|
+
# GET /links/1 Link::Controller#view(1)
|
20
|
+
# GET /links/1;edit GET /links/edit/1 Link::Controller#edit(1)
|
21
|
+
# PUT /links/1 POST /links/update/1 Link::Controller#update
|
22
|
+
# DELETE /links/1 GET /links/delete/1 Link::Controller#delete(1)
|
23
|
+
# GET /links/index.xml Link::Controller#index # Atom
|
24
|
+
# GET /links/index.json Link::Controller#index # JSON
|
25
|
+
#
|
26
|
+
# The default actions for the various methods are:
|
27
|
+
#
|
28
|
+
# GET: index
|
29
|
+
# POST: create
|
30
|
+
# PUT: update
|
31
|
+
# DELETE: delete
|
32
|
+
|
33
|
+
class Dispatcher
|
34
|
+
|
35
|
+
# The (optional) router.
|
36
|
+
|
37
|
+
attr_accessor :router
|
38
|
+
|
39
|
+
# The hash that maps mount paths to controllers.
|
40
|
+
|
41
|
+
attr_accessor :controllers
|
42
|
+
|
43
|
+
# The representation formats this dispatcher understands.
|
44
|
+
|
45
|
+
attr_accessor :formats
|
46
|
+
|
47
|
+
# Initialize the dispatcher.
|
48
|
+
|
49
|
+
def initialize(controller_or_map = nil)
|
50
|
+
@controllers = {}
|
51
|
+
@formats = Nitro::STANDARD_FORMATS.dup
|
52
|
+
|
53
|
+
if controller_or_map.is_a?(Class)
|
54
|
+
mount("/" => controller_or_map)
|
55
|
+
elsif controller_or_map.is_a?(Hash)
|
56
|
+
mount(controller_or_map)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Mounts a map of controllers.
|
61
|
+
|
62
|
+
def mount(map)
|
63
|
+
for path, controller in map
|
64
|
+
self[path] = controller
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Return the controller for the given mount path.
|
69
|
+
|
70
|
+
def [](path = "/")
|
71
|
+
@controllers[path]
|
72
|
+
end
|
73
|
+
|
74
|
+
# Mount a controller to the given mount path.
|
75
|
+
|
76
|
+
def []=(path, controller)
|
77
|
+
controller = resolve_controller(controller)
|
78
|
+
|
79
|
+
# Customize the class for mounting at the given path.
|
80
|
+
controller.mount_at(path) if controller.respond_to? :mount_at
|
81
|
+
|
82
|
+
# Call the mounted callback to allow for post mount
|
83
|
+
# initialization.
|
84
|
+
controller.mounted(path) if controller.respond_to? :mounted
|
85
|
+
|
86
|
+
@controllers[path] = controller
|
87
|
+
end
|
88
|
+
|
89
|
+
# Dispatch a request. Calls the lower level dispatch method.
|
90
|
+
|
91
|
+
def dispatch_request(request)
|
92
|
+
dispatch(request.uri, request.method)
|
93
|
+
end
|
94
|
+
alias_method :dispatch_context, :dispatch_request
|
95
|
+
|
96
|
+
# Dispatch a path given the request method. This method
|
97
|
+
# handles fully resolved paths (containing an extension that
|
98
|
+
# denotes the expected content type).
|
99
|
+
#
|
100
|
+
# This method automatically handles 'nice' (seo friendly, elegant)
|
101
|
+
# parameters, ie:
|
102
|
+
#
|
103
|
+
# /links/view/1
|
104
|
+
#
|
105
|
+
# instead of
|
106
|
+
#
|
107
|
+
# /links/view?oid=1
|
108
|
+
#
|
109
|
+
# === Output
|
110
|
+
#
|
111
|
+
# controller, action, query_string, nice_params, extension
|
112
|
+
#
|
113
|
+
#--
|
114
|
+
# Lower level, useful for testing.
|
115
|
+
#++
|
116
|
+
|
117
|
+
def dispatch(uri, method = :get)
|
118
|
+
# Extract the query string.
|
119
|
+
|
120
|
+
path, query = uri.split("?", 2)
|
121
|
+
|
122
|
+
# Try to route the path.
|
123
|
+
|
124
|
+
path = @router.route(path) if @router
|
125
|
+
|
126
|
+
# The characters after the last '.' in the path form the
|
127
|
+
# extension that itself represents the expected response
|
128
|
+
# content type.
|
129
|
+
|
130
|
+
ext = File.extname(path)[1..-1] || "html"
|
131
|
+
|
132
|
+
# The resource representation format for this request.
|
133
|
+
|
134
|
+
unless format = Context.current.format = @formats.by_extension[ext]
|
135
|
+
raise ActionError.new("Cannot respond to '#{path}' using the '#{ext}' format representation.")
|
136
|
+
end
|
137
|
+
|
138
|
+
# Remove the extension from the path.
|
139
|
+
|
140
|
+
path = path.gsub(/\.(.*)$/, '')
|
141
|
+
|
142
|
+
# Try to extract the controller from the path (that may also
|
143
|
+
# include 'nice' parameters). This algorithm tries to find
|
144
|
+
# the bigest substring of the path that represents a mount
|
145
|
+
# path for a controller.
|
146
|
+
|
147
|
+
key = path.dup
|
148
|
+
|
149
|
+
while (controller = @controllers[key]).nil?
|
150
|
+
key = key[%r{^(/.+)/.+$}, 1] || '/'
|
151
|
+
end
|
152
|
+
|
153
|
+
# Try to extract the controller from the path. This
|
154
|
+
# algorithm tries to find the bigest substring of the path
|
155
|
+
# that represents an action of this controller.
|
156
|
+
#
|
157
|
+
# The algorithm respects action name conventions, ie
|
158
|
+
# simple/sub/action maps to simple__sub__action.
|
159
|
+
|
160
|
+
action = key = path.sub(%r{^#{key}}, '').gsub(%r{^/}, '').gsub(%r{/}, '__')
|
161
|
+
|
162
|
+
while (!action.blank?) and !controller.action_or_template?(action, format)
|
163
|
+
action = action[%r{^(.+)__.+$}, 1]
|
164
|
+
end
|
165
|
+
|
166
|
+
# Extract the 'nice' parameters.
|
167
|
+
|
168
|
+
params = key.sub(%r{^#{action}}, '').gsub(/^__/, '').split('__')
|
169
|
+
|
170
|
+
# Do we have an action?
|
171
|
+
|
172
|
+
if action.blank?
|
173
|
+
# Try to use a standard action for this http method.
|
174
|
+
|
175
|
+
case method
|
176
|
+
when :get
|
177
|
+
action = "index"
|
178
|
+
|
179
|
+
when :post
|
180
|
+
action = "create"
|
181
|
+
|
182
|
+
when :delete
|
183
|
+
action = "delete"
|
184
|
+
|
185
|
+
when :put
|
186
|
+
action = "update"
|
187
|
+
end
|
188
|
+
|
189
|
+
unless controller.action_or_template?(action, format)
|
190
|
+
raise ActionError.new("Cannot respond to '#{path}' using '#{controller}'")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
return controller, "#{action}___super", query, params, ext
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
def resolve_controller(controller)
|
200
|
+
unless controller.ancestor?(Controller) or controller.ancestor?(Publishable)
|
201
|
+
controller.send(:include, Publishable)
|
202
|
+
end
|
203
|
+
|
204
|
+
return controller
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Raw
|
2
|
+
|
3
|
+
# A REST Resource Representation format.
|
4
|
+
|
5
|
+
class Format
|
6
|
+
|
7
|
+
# The name of this format.
|
8
|
+
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# The resource content type. Typically the resource MIME type
|
12
|
+
# is used.
|
13
|
+
|
14
|
+
attr_accessor :content_type
|
15
|
+
alias_method :mime_type, :content_type
|
16
|
+
|
17
|
+
# The default resource extension.
|
18
|
+
|
19
|
+
attr_accessor :extension
|
20
|
+
|
21
|
+
# The default template extension.
|
22
|
+
|
23
|
+
attr_accessor :template_extension
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@name
|
27
|
+
end
|
28
|
+
|
29
|
+
# Apply filters to the template source. The original template
|
30
|
+
# representation must be transformed to executable Ruby code
|
31
|
+
# at the end.
|
32
|
+
|
33
|
+
def filter_template(source)
|
34
|
+
return source
|
35
|
+
end
|
36
|
+
|
37
|
+
# This callback is called before the action is executed with
|
38
|
+
# this format.
|
39
|
+
|
40
|
+
def before_action(controller, context)
|
41
|
+
end
|
42
|
+
|
43
|
+
# This callback is called after the action is executed with
|
44
|
+
# this format.
|
45
|
+
|
46
|
+
def after_action(controller, context)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# A Format Manager. Provides useful methods for fast Format
|
52
|
+
# lookup.
|
53
|
+
|
54
|
+
class FormatManager
|
55
|
+
# Formats indexed by name.
|
56
|
+
|
57
|
+
attr_accessor :by_name
|
58
|
+
|
59
|
+
# Formats indexed by mime type.
|
60
|
+
|
61
|
+
attr_accessor :by_mime_type
|
62
|
+
|
63
|
+
# Formats indexed by extension.
|
64
|
+
|
65
|
+
attr_accessor :by_extension
|
66
|
+
|
67
|
+
def initialize(*formats)
|
68
|
+
@by_name = {}
|
69
|
+
@by_mime_type = {}
|
70
|
+
@by_extension = {}
|
71
|
+
|
72
|
+
for format in formats.flatten
|
73
|
+
put(format)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Add a new format to the manager.
|
78
|
+
|
79
|
+
def put(format)
|
80
|
+
if format.is_a? Class
|
81
|
+
format = format.new
|
82
|
+
end
|
83
|
+
|
84
|
+
@by_name[format.name] = format
|
85
|
+
@by_mime_type[format.mime_type] = format
|
86
|
+
@by_extension[format.extension] = format
|
87
|
+
end
|
88
|
+
alias_method :<<, :put
|
89
|
+
|
90
|
+
# Lookup a format by name.
|
91
|
+
|
92
|
+
def [](name)
|
93
|
+
@by_name[name]
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
require "raw/dispatcher/format/html"
|
99
|
+
require "raw/dispatcher/format/atom"
|
100
|
+
require "raw/dispatcher/format/rss"
|
101
|
+
require "raw/dispatcher/format/json"
|
102
|
+
require "raw/dispatcher/format/xoxo"
|
103
|
+
|
104
|
+
STANDARD_FORMATS = FormatManager.new(
|
105
|
+
HTMLFormat, ATOMFormat, RSSFormat, JSONFormat, XOXOFormat
|
106
|
+
)
|
107
|
+
|
108
|
+
end
|