ramaze 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/ramaze +58 -26
- data/doc/AUTHORS +2 -0
- data/doc/CHANGELOG +401 -0
- data/doc/README +14 -9
- data/doc/README.html +737 -0
- data/doc/TODO +14 -14
- data/doc/changes.txt +401 -0
- data/doc/changes.xml +401 -0
- data/doc/meta/announcement.txt +28 -15
- data/doc/meta/configuration.txt +3 -3
- data/doc/meta/internals.txt +2 -2
- data/doc/meta/users.kml +62 -0
- data/doc/readme_chunks/examples.txt +1 -1
- data/doc/readme_chunks/features.txt +13 -8
- data/doc/tutorial/todolist.html +2 -2
- data/doc/tutorial/todolist.mkd +2 -2
- data/examples/blog/README +3 -0
- data/examples/blog/spec/blog.rb +101 -0
- data/examples/blog/{main.rb → start.rb} +0 -0
- data/examples/caching.rb +16 -5
- data/examples/layout.rb +41 -0
- data/examples/templates/template_amrita2.rb +1 -1
- data/examples/templates/template_erubis.rb +1 -1
- data/examples/templates/template_ezamar.rb +1 -1
- data/examples/templates/template_haml.rb +1 -1
- data/examples/templates/template_liquid.rb +1 -1
- data/examples/templates/template_markaby.rb +1 -1
- data/examples/templates/template_remarkably.rb +1 -1
- data/examples/todolist/README +1 -0
- data/{spec/examples → examples/todolist/spec}/todolist.rb +3 -3
- data/examples/todolist/{main.rb → start.rb} +0 -0
- data/examples/whywiki/{main.rb → start.rb} +0 -0
- data/examples/wiktacular/README +2 -0
- data/examples/wiktacular/spec/wiktacular.rb +146 -0
- data/examples/wiktacular/src/controller.rb +11 -0
- data/examples/wiktacular/src/model.rb +5 -1
- data/examples/wiktacular/{main.rb → start.rb} +0 -1
- data/examples/wiktacular/template/edit.xhtml +1 -2
- data/examples/wiktacular/template/html_layout.xhtml +27 -0
- data/examples/wiktacular/template/index.xhtml +8 -10
- data/examples/wiktacular/template/new.xhtml +1 -2
- data/lib/proto/{main.rb → start.rb} +0 -0
- data/lib/proto/template/index.xhtml +1 -1
- data/lib/ramaze/action/render.rb +58 -4
- data/lib/ramaze/action.rb +20 -0
- data/lib/ramaze/adapter/cgi.rb +7 -4
- data/lib/ramaze/adapter/fcgi.rb +6 -4
- data/lib/ramaze/adapter/mongrel.rb +4 -0
- data/lib/ramaze/adapter/webrick.rb +20 -9
- data/lib/ramaze/adapter.rb +3 -1
- data/lib/ramaze/cache/memcached.rb +2 -26
- data/lib/ramaze/cache.rb +8 -4
- data/lib/ramaze/controller/resolve.rb +26 -8
- data/lib/ramaze/controller.rb +44 -7
- data/lib/ramaze/dispatcher/action.rb +5 -1
- data/lib/ramaze/dispatcher/directory.rb +115 -0
- data/lib/ramaze/dispatcher/error.rb +19 -5
- data/lib/ramaze/dispatcher/file.rb +2 -2
- data/lib/ramaze/dispatcher.rb +52 -39
- data/lib/ramaze/global/dsl.rb +3 -2
- data/lib/ramaze/global/globalstruct.rb +26 -4
- data/lib/ramaze/global.rb +20 -11
- data/lib/ramaze/helper/aspect.rb +29 -11
- data/lib/ramaze/helper/auth.rb +2 -2
- data/lib/ramaze/helper/cache.rb +2 -0
- data/lib/ramaze/helper/identity.rb +21 -6
- data/lib/ramaze/helper/link.rb +1 -1
- data/lib/ramaze/helper/pager.rb +158 -100
- data/lib/ramaze/helper/partial.rb +22 -0
- data/lib/ramaze/helper/redirect.rb +1 -2
- data/lib/ramaze/helper/stack.rb +1 -1
- data/lib/ramaze/inform/informer.rb +20 -0
- data/lib/ramaze/inform/syslog.rb +5 -0
- data/lib/ramaze/snippets/kernel/__dir__.rb +21 -0
- data/lib/ramaze/snippets/kernel/aquire.rb +22 -12
- data/lib/ramaze/snippets/numeric/human_readable_filesize_format.rb +33 -0
- data/lib/ramaze/snippets/ramaze/caller_lines.rb +1 -1
- data/lib/ramaze/snippets/struct/values_at.rb +11 -4
- data/lib/ramaze/sourcereload.rb +29 -1
- data/{spec → lib/ramaze/spec}/helper/context.rb +0 -0
- data/{spec → lib/ramaze/spec}/helper/layout.rb +1 -1
- data/{spec → lib/ramaze/spec}/helper/minimal.rb +0 -0
- data/{spec → lib/ramaze/spec}/helper/mock_http.rb +0 -0
- data/{spec → lib/ramaze/spec}/helper/requester.rb +0 -0
- data/{spec → lib/ramaze/spec}/helper/simple_http.rb +0 -0
- data/{spec → lib/ramaze/spec}/helper/wrap.rb +0 -0
- data/lib/ramaze/spec/helper.rb +60 -0
- data/lib/ramaze/store/default.rb +3 -0
- data/lib/ramaze/template/ezamar/render_partial.rb +3 -0
- data/lib/ramaze/template/sass.rb +45 -0
- data/lib/ramaze/template.rb +1 -1
- data/lib/ramaze/tool/create.rb +5 -5
- data/lib/ramaze/tool/localize.rb +26 -5
- data/lib/ramaze/tool/mime.rb +7 -0
- data/lib/ramaze/trinity/response.rb +15 -0
- data/lib/ramaze/trinity/session.rb +1 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze.rb +5 -0
- data/rake_tasks/conf.rake +4 -4
- data/rake_tasks/maintaince.rake +12 -7
- data/rake_tasks/spec.rake +7 -4
- data/spec/examples/caching.rb +6 -8
- data/spec/helper.rb +3 -60
- data/spec/ramaze/action/basics.rb +17 -0
- data/spec/ramaze/action/cache.rb +28 -0
- data/spec/ramaze/action/layout.rb +110 -0
- data/spec/ramaze/action/render.rb +14 -0
- data/spec/ramaze/action/template/bar.xhtml +1 -0
- data/spec/ramaze/action/template/other_wrapper.xhtml +1 -0
- data/spec/ramaze/action/template/single_wrapper.xhtml +1 -0
- data/spec/ramaze/controller/template/edit/content.xhtml +1 -0
- data/spec/ramaze/controller/template/edit.xhtml +1 -0
- data/spec/ramaze/controller/template_resolving.rb +2 -2
- data/spec/ramaze/dispatcher/directory.rb +53 -0
- data/spec/ramaze/dispatcher/file.rb +0 -3
- data/spec/ramaze/error.rb +17 -2
- data/spec/ramaze/helper/aspect.rb +14 -20
- data/spec/ramaze/helper/pager.rb +83 -1
- data/spec/ramaze/helper/partial.rb +1 -1
- data/spec/ramaze/helper/template/test_template.xhtml +1 -0
- data/spec/ramaze/inform/informer.rb +37 -5
- data/spec/ramaze/localize.rb +1 -1
- data/spec/ramaze/template/haml.rb +5 -5
- data/spec/ramaze/template/sass/file.css.sass +5 -0
- data/spec/ramaze/template/sass.rb +46 -0
- data/spec/ramaze/template.rb +1 -1
- data/spec/ramaze/trinity/session.rb +27 -0
- data/spec/snippets/kernel/__dir__.rb +8 -0
- data/spec/snippets/kernel/aquire.rb +71 -0
- data/spec/snippets/kernel/constant.rb +27 -0
- data/spec/snippets/numeric/human_readable_filesize_format.rb +11 -0
- data/spec/snippets/ramaze/caller_info.rb +39 -0
- data/spec/snippets/ramaze/caller_lines.rb +27 -0
- data/spec/snippets/string/DIVIDE.rb +18 -0
- data/spec/snippets/string/camel_case.rb +25 -0
- data/spec/snippets/string/color.rb +11 -0
- data/spec/snippets/string/snake_case.rb +17 -0
- data/spec/snippets/struct/fill.rb +27 -0
- data/spec/snippets/struct/values_at.rb +39 -0
- metadata +71 -31
- data/examples/todolist/todolist.db +0 -5
- data/examples/wiktacular/src/page.rb +0 -66
- data/lib/ramaze/helper/feed.rb +0 -135
- data/lib/ramaze/helper/form.rb +0 -204
- data/lib/ramaze/snippets/openstruct/temp.rb +0 -13
- data/lib/ramaze/store/yaml.rb +0 -170
- data/spec/ramaze/helper/feed.rb +0 -127
- data/spec/ramaze/helper/form.rb +0 -146
- data/spec/ramaze/store/yaml.rb +0 -76
data/lib/ramaze/action.rb
CHANGED
@@ -101,6 +101,26 @@ module Ramaze
|
|
101
101
|
self[:binding] ||= instance.instance_eval{ binding }
|
102
102
|
end
|
103
103
|
|
104
|
+
def name
|
105
|
+
File.basename((self[:method] || self[:template]).to_s).split('.').first
|
106
|
+
end
|
107
|
+
|
108
|
+
# TODO: find good names for this method.
|
109
|
+
|
110
|
+
def basepath
|
111
|
+
@basepath ||= "#{controller.mapping}/#{name}".gsub(/^\/+/, '/')
|
112
|
+
end
|
113
|
+
|
114
|
+
# TODO: find good names for this method.
|
115
|
+
def fullpath
|
116
|
+
"#{path}/#{params.join('/')}".gsub(/^\/+/, '/')
|
117
|
+
end
|
118
|
+
|
119
|
+
# TODO: find good names for this method.
|
120
|
+
def extended_path
|
121
|
+
@extended_path ||= File.join(path, *params)
|
122
|
+
end
|
123
|
+
|
104
124
|
# Hook for AspectHelper
|
105
125
|
|
106
126
|
def before_process
|
data/lib/ramaze/adapter/cgi.rb
CHANGED
@@ -4,15 +4,18 @@
|
|
4
4
|
require 'ramaze/adapter'
|
5
5
|
|
6
6
|
module Ramaze::Adapter
|
7
|
+
|
8
|
+
# Our CGI adapter acts as wrapper for the Rack::Handler::CGI.
|
7
9
|
class Cgi < Base
|
8
10
|
class << self
|
9
|
-
|
11
|
+
|
12
|
+
# start CGI in a new thread, host and port parameter are only taken
|
13
|
+
# to make it compatible with other adapters but have no influence and
|
14
|
+
# can be omitted
|
15
|
+
def start host = nil, ports = nil
|
10
16
|
global = Ramaze::Global
|
11
17
|
global.inform_to = :stderr if global.inform_to == $stdout
|
12
|
-
run_server
|
13
|
-
end
|
14
18
|
|
15
|
-
def run_server
|
16
19
|
Thread.new do
|
17
20
|
Thread.current[:task] = :cgi
|
18
21
|
Rack::Handler::CGI.run(self)
|
data/lib/ramaze/adapter/fcgi.rb
CHANGED
@@ -4,13 +4,15 @@
|
|
4
4
|
require 'ramaze/adapter'
|
5
5
|
|
6
6
|
module Ramaze::Adapter
|
7
|
+
|
8
|
+
# Our Fcgi adapter acts as wrapper for the Rack::Handler::FastCGI.
|
7
9
|
class Fcgi < Base
|
8
10
|
class << self
|
9
|
-
def start host, ports
|
10
|
-
run_server
|
11
|
-
end
|
12
11
|
|
13
|
-
|
12
|
+
# start FastCGI in a new thread, host and port parameter are only taken
|
13
|
+
# to make it compatible with other adapters but have no influence and
|
14
|
+
# can be omitted
|
15
|
+
def start host = nil, ports = nil
|
14
16
|
Thread.new do
|
15
17
|
Thread.current[:task] = :cgi
|
16
18
|
Rack::Handler::FastCGI.run(self)
|
@@ -16,8 +16,12 @@ module Ramaze
|
|
16
16
|
require 'rack/handler/mongrel'
|
17
17
|
|
18
18
|
module Adapter
|
19
|
+
|
20
|
+
# Our Mongrel adapter acts as wrapper for the Rack::Handler::Mongrel.
|
19
21
|
class Mongrel < Base
|
20
22
|
class << self
|
23
|
+
|
24
|
+
# start server on given host and port.
|
21
25
|
def run_server host, port
|
22
26
|
server = ::Mongrel::HttpServer.new(host, port)
|
23
27
|
server.register('/', ::Rack::Handler::Mongrel.new(self))
|
@@ -5,19 +5,14 @@ require 'ramaze/adapter'
|
|
5
5
|
require 'webrick'
|
6
6
|
require 'rack/handler/webrick'
|
7
7
|
|
8
|
-
module WEBrick
|
9
|
-
module HTTPServlet
|
10
|
-
class ProcHandler
|
11
|
-
alias do_PUT do_GET
|
12
|
-
alias do_DELETE do_GET
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
8
|
module Ramaze
|
18
9
|
module Adapter
|
10
|
+
|
11
|
+
# Our WEBrick adapter acts as wrapper for the Rack::Handler::WEBrick.
|
19
12
|
class WEBrick < Base
|
20
13
|
class << self
|
14
|
+
|
15
|
+
# start server on given host and port, see below for possible options.
|
21
16
|
def run_server host, port, options = {}
|
22
17
|
options = {
|
23
18
|
:Port => port,
|
@@ -41,3 +36,19 @@ module Ramaze
|
|
41
36
|
end
|
42
37
|
end
|
43
38
|
end
|
39
|
+
|
40
|
+
# Extending on WEBrick module
|
41
|
+
module WEBrick
|
42
|
+
|
43
|
+
# Extending on HTTPServlet
|
44
|
+
module HTTPServlet
|
45
|
+
|
46
|
+
# Extending on ProcHandler
|
47
|
+
#
|
48
|
+
# We alias PUT to GET and DELETE to GET so WEBrick handles them as well.
|
49
|
+
class ProcHandler
|
50
|
+
alias do_PUT do_GET
|
51
|
+
alias do_DELETE do_GET
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/ramaze/adapter.rb
CHANGED
@@ -62,33 +62,9 @@ module Ramaze
|
|
62
62
|
def values_at(*keys)
|
63
63
|
get_multi(*keys).values_at(*keys)
|
64
64
|
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# add the MemCache#clear method
|
69
|
-
|
70
|
-
class MemCache
|
71
|
-
|
72
|
-
# MemCache.clear sends 'flush_all' command to all registered MemCache
|
73
|
-
# servers.
|
74
|
-
|
75
|
-
def clear
|
76
|
-
raise MemCacheError, "Update of readonly cache" if @readonly
|
77
|
-
|
78
|
-
@servers.each do |server|
|
79
|
-
server.flush_all
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# implements the flushing of MemCache server. Flushes a single server,
|
84
|
-
# MemCache#clear can be used for clearing out all MemCache servers.
|
85
|
-
|
86
|
-
class Server
|
87
|
-
|
88
|
-
# Serverside implementation of the #clear functionality for MemCache
|
89
65
|
|
90
|
-
def
|
91
|
-
|
66
|
+
def clear
|
67
|
+
@cache.flush_all
|
92
68
|
end
|
93
69
|
end
|
94
70
|
end
|
data/lib/ramaze/cache.rb
CHANGED
@@ -12,6 +12,8 @@ module Ramaze
|
|
12
12
|
|
13
13
|
class Cache
|
14
14
|
include Enumerable
|
15
|
+
|
16
|
+
# Holds all the instances of Cache that are being added.
|
15
17
|
CACHES = {} unless defined?(CACHES)
|
16
18
|
|
17
19
|
attr_accessor :cache
|
@@ -47,33 +49,35 @@ module Ramaze
|
|
47
49
|
end
|
48
50
|
|
49
51
|
# Initializes the cache, defined by Global.cache
|
50
|
-
|
51
52
|
def initialize(cache = Global.cache)
|
52
53
|
@cache = cache.new
|
53
54
|
end
|
54
55
|
|
56
|
+
# Get key.
|
55
57
|
def [](key)
|
56
58
|
@cache["#{@cache_name}:#{key}"]
|
57
59
|
end
|
58
60
|
|
61
|
+
# Set key to value.
|
59
62
|
def []=(key, value)
|
60
63
|
@cache["#{@cache_name}:#{key}"] = value
|
61
64
|
end
|
62
65
|
|
63
66
|
# deletes the keys of each argument passed from Cache instance.
|
64
|
-
|
65
67
|
def delete(*args)
|
66
68
|
args.each do |arg|
|
67
69
|
@cache.delete("#{@cache_name}:#{arg}")
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
73
|
+
# Empty this cache
|
71
74
|
def clear
|
72
75
|
@cache.clear
|
73
76
|
end
|
74
77
|
|
75
|
-
|
76
|
-
|
78
|
+
# Answers with value for each key.
|
79
|
+
def values_at(*keys)
|
80
|
+
@cache.values_at(*keys.map {|key| "#{@cache_name}:#{key}" })
|
77
81
|
end
|
78
82
|
end
|
79
83
|
end
|
@@ -15,7 +15,7 @@ module Ramaze
|
|
15
15
|
def resolve(path)
|
16
16
|
if found = Cache.resolved[path]
|
17
17
|
if found.respond_to?(:relaxed_hash)
|
18
|
-
return found
|
18
|
+
return found.dup
|
19
19
|
else
|
20
20
|
Inform.warn("Found faulty `#{path}' in Cache.resolved, deleting it for sanity.")
|
21
21
|
Cache.resolved.delete path
|
@@ -39,7 +39,10 @@ module Ramaze
|
|
39
39
|
|
40
40
|
valid_action = (action.method or (params.empty? && template))
|
41
41
|
|
42
|
-
|
42
|
+
if valid_action
|
43
|
+
Cache.resolved[path] = action
|
44
|
+
return action.dup
|
45
|
+
end
|
43
46
|
end
|
44
47
|
end
|
45
48
|
|
@@ -47,6 +50,8 @@ module Ramaze
|
|
47
50
|
raise_no_controller(path)
|
48
51
|
end
|
49
52
|
|
53
|
+
# Try to produce an Action from the given path and paremters with the
|
54
|
+
# appropiate template if one exists.
|
50
55
|
def resolve_action(path, *parameter)
|
51
56
|
path, parameter = path.to_s, parameter.map(&:to_s)
|
52
57
|
if alternate_template = trait["#{path}_template"]
|
@@ -67,22 +72,30 @@ module Ramaze
|
|
67
72
|
:controller => self
|
68
73
|
end
|
69
74
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
75
|
+
# Search the #template_paths for a fitting template for path.
|
76
|
+
# Only the first found possibility for the generated glob is returned.
|
77
|
+
def resolve_template(path)
|
78
|
+
path = path.to_s
|
79
|
+
path_converted = path.split('__').inject{|s,v| s/v}
|
80
|
+
possible_paths = [path, path_converted].compact
|
74
81
|
|
75
|
-
paths = template_paths.map{|pa|
|
82
|
+
paths = template_paths.map{|pa| possible_paths.map{|a| pa/a } }.flatten.uniq
|
76
83
|
glob = "{#{paths.join(',')}}.{#{extension_order.join(',')}}"
|
77
84
|
|
78
85
|
Dir[glob].first
|
79
86
|
end
|
80
87
|
|
88
|
+
# Composes an array with the template-paths to look up in the right order.
|
89
|
+
# Usually this is composed of Global.template_root and the mapping of the
|
90
|
+
# controller and a second element for Global.public_root, which makes
|
91
|
+
# it possible to convert CSS on the fly and things like that.
|
92
|
+
|
81
93
|
def template_paths
|
82
94
|
@template_root ||= Global.template_root / Global.mapping.invert[self]
|
83
95
|
[ @template_root, Global.public_root ].compact
|
84
96
|
end
|
85
97
|
|
98
|
+
# Based on methodname and arity, tries to find the right method on current controller.
|
86
99
|
def resolve_method(name, *params)
|
87
100
|
if method = action_methods.delete(name)
|
88
101
|
arity = instance_method(method).arity
|
@@ -93,6 +106,7 @@ module Ramaze
|
|
93
106
|
return nil, []
|
94
107
|
end
|
95
108
|
|
109
|
+
# methodnames that may be used for current controller.
|
96
110
|
def action_methods
|
97
111
|
exclude = Controller.trait[:exclude_action_modules]
|
98
112
|
|
@@ -102,6 +116,7 @@ module Ramaze
|
|
102
116
|
meths - ancs.map(&:to_s)
|
103
117
|
end
|
104
118
|
|
119
|
+
# Generate all possible permutations for given path.
|
105
120
|
def pattern_for(path)
|
106
121
|
atoms = path.split('/').grep(/\S/)
|
107
122
|
atoms.unshift('')
|
@@ -129,6 +144,9 @@ module Ramaze
|
|
129
144
|
patterns.reverse!
|
130
145
|
end
|
131
146
|
|
147
|
+
# Uses custom defined engines and all available engines and throws it
|
148
|
+
# against the extensions for the template to find the most likely
|
149
|
+
# templating-engine to use ordered by priority and likelyhood.
|
132
150
|
def extension_order
|
133
151
|
t_extensions = Template::ENGINES
|
134
152
|
engine = trait[:engine]
|
@@ -146,7 +164,7 @@ module Ramaze
|
|
146
164
|
# Raises Ramaze::Error::NoAction
|
147
165
|
|
148
166
|
def raise_no_action(controller, path)
|
149
|
-
Thread.current[:
|
167
|
+
Thread.current[:controller] = controller
|
150
168
|
raise Ramaze::Error::NoAction, "No Action found for `#{path}' on #{controller}"
|
151
169
|
end
|
152
170
|
end
|
data/lib/ramaze/controller.rb
CHANGED
@@ -43,7 +43,12 @@ module Ramaze
|
|
43
43
|
|
44
44
|
def inherited controller
|
45
45
|
controller.trait :actions_cached => Set.new
|
46
|
+
controller.trait :layout => {:all => nil, :deny => Set.new}
|
46
47
|
Global.controllers << controller
|
48
|
+
if map = controller.mapping
|
49
|
+
Inform.debug("mapping #{map} => #{controller}")
|
50
|
+
Global.mapping[map] ||= controller
|
51
|
+
end
|
47
52
|
end
|
48
53
|
|
49
54
|
# called from Ramaze.startup, adds Cache.actions and Cache.patterns, walks
|
@@ -52,13 +57,9 @@ module Ramaze
|
|
52
57
|
|
53
58
|
def startup options = {}
|
54
59
|
Inform.debug("found Controllers: #{Global.controllers.inspect}")
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
Inform.debug("mapping #{map} => #{controller}")
|
59
|
-
Global.mapping[map] ||= controller
|
60
|
-
end
|
61
|
-
end
|
60
|
+
tr, pr = Global.template_root, Global.public_root
|
61
|
+
Inform.warn("Template root: #{tr} doesn't exist") unless File.directory?(tr)
|
62
|
+
Inform.warn("Public root: #{pr} doesn't exist") unless File.directory?(pr)
|
62
63
|
|
63
64
|
if Global.mapping.empty?
|
64
65
|
Inform.warn("No Controllers mapped, will serve /public only.")
|
@@ -87,8 +88,12 @@ module Ramaze
|
|
87
88
|
end
|
88
89
|
|
89
90
|
# Map Controller to the given syms or strings.
|
91
|
+
# Replaces old mappings.
|
92
|
+
# If you want to _add_ a mapping, just modify Global.mapping.
|
90
93
|
|
91
94
|
def map(*syms)
|
95
|
+
Global.mapping.delete_if{|k,v| v == self}
|
96
|
+
|
92
97
|
syms.each do |sym|
|
93
98
|
Global.mapping[sym.to_s] = self
|
94
99
|
end
|
@@ -100,6 +105,37 @@ module Ramaze
|
|
100
105
|
Global.mapping[mapping.to_s]
|
101
106
|
end
|
102
107
|
|
108
|
+
# Define a layout for all actions on this controller
|
109
|
+
#
|
110
|
+
# Example:
|
111
|
+
# class Foo < Ramaze::Controller
|
112
|
+
# layout :foo
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# This defines the action :foo to be layout of the controller and will
|
116
|
+
# render the layout after any other action has been rendered, assigns
|
117
|
+
# @content to the result of the action and then goes on rendering
|
118
|
+
# the layout-action where @content may or may not be used, returning
|
119
|
+
# whatever the layout returns.
|
120
|
+
|
121
|
+
def layout(meth_or_hash, &block)
|
122
|
+
if meth_or_hash.respond_to?(:to_hash)
|
123
|
+
meth_or_hash.each do |layout_name, *actions|
|
124
|
+
actions.flatten.each do |action|
|
125
|
+
trait[:layout][action.to_s] = R(self, layout_name)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
trait[:layout][:all] = R(self, meth_or_hash)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def deny_layout(*actions)
|
134
|
+
actions.each do |action|
|
135
|
+
trait[:layout][:deny] << action.to_s
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
103
139
|
# Define a template_root for Controller, returns the current template_root
|
104
140
|
# if no argument is given.
|
105
141
|
# Runs every given path through Controller::check_path
|
@@ -148,6 +184,7 @@ module Ramaze
|
|
148
184
|
|
149
185
|
def handle path
|
150
186
|
action = resolve(path)
|
187
|
+
Thread.current[:controller] = action.controller
|
151
188
|
action.render
|
152
189
|
end
|
153
190
|
end
|
@@ -3,6 +3,10 @@
|
|
3
3
|
|
4
4
|
module Ramaze
|
5
5
|
module Dispatcher
|
6
|
+
|
7
|
+
# This dispatcher is responsible for relaying requests to Controller::handle
|
8
|
+
# and filtering the results using FILTER.
|
9
|
+
|
6
10
|
class Action
|
7
11
|
|
8
12
|
# The response is passed to each filter by sending .call(response) to it.
|
@@ -20,7 +24,7 @@ module Ramaze
|
|
20
24
|
|
21
25
|
def process(path)
|
22
26
|
body = Controller.handle(path)
|
23
|
-
response =
|
27
|
+
response = Response.current.build(body)
|
24
28
|
FILTER.inject(response){|r,f| f.call(r) }
|
25
29
|
rescue Ramaze::Error => ex
|
26
30
|
ex
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
|
4
|
+
module Ramaze
|
5
|
+
module Dispatcher
|
6
|
+
|
7
|
+
# Generates a directory listing, see Ramaze::Controller::Directory for more
|
8
|
+
# information and how to create your own directory listing page
|
9
|
+
class Directory
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# Entry point from Dispatcher::filter.
|
13
|
+
# Just a forwarder to build_listing, automatticly exiting if there is
|
14
|
+
# an error (defined by returning false in build_listing)
|
15
|
+
def process(path)
|
16
|
+
if Global.list_directories
|
17
|
+
response = build_listing(path)
|
18
|
+
Response.current.build(*response) if response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Makes a request for http://yourserver/dirlist/path and returns the
|
23
|
+
# result. Due to this method, you can overwrite the action and create your
|
24
|
+
# own page. See Ramaze::Controller::Directory for more.
|
25
|
+
def build_listing(path)
|
26
|
+
dir = ::File.expand_path(Global.public_root/::File.expand_path(path, '/'))
|
27
|
+
|
28
|
+
if ::File.directory?(dir)
|
29
|
+
Inform.debug("Serving directory listing: #{dir}")
|
30
|
+
|
31
|
+
status = Ramaze::STATUS_CODE['OK']
|
32
|
+
header = {'Content-Type' => "text/html"}
|
33
|
+
body = list_for(dir)
|
34
|
+
[body, status, header]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def list_for(path)
|
39
|
+
display = path.gsub(/^#{Regexp.escape(Global.public_root)}\/?/, '/')
|
40
|
+
wrapper =
|
41
|
+
%(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
42
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
43
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
44
|
+
<head>
|
45
|
+
<title>Directory listing of #{display}</title>
|
46
|
+
|
47
|
+
<style type="text/css"> /*<![CDATA[*/ a, a:active {text-decoration: none; color: blue;} a:visited {color: #48468F;} a:hover, a:focus {text-decoration: underline; color: red;} body {background-color: #F5F5F5;} h2 {margin-bottom: 12px;} table {margin-left: 12px;} th, td { font-family: "Courier New", Courier, monospace; font-size: 10pt; text-align: left;} th { font-weight: bold; padding-right: 14px; padding-bottom: 3px;} td {padding-right: 14px;} td.s, th.s {text-align: right;} div.list { background-color: white; border-top: 1px solid #646464; border-bottom: 1px solid #646464; padding-top: 10px; padding-bottom: 14px;} div.foot { font-family: "Courier New", Courier, monospace; font-size: 10pt; color: #787878; padding-top: 4px;} /*]]>*/ </style>
|
48
|
+
</head>
|
49
|
+
<body>
|
50
|
+
<h2>Directory listing of #{display}</h2>
|
51
|
+
<div class="list">
|
52
|
+
<table summary="Directory Listing" cellpadding="0" cellspacing="0">
|
53
|
+
<thead>
|
54
|
+
<tr>
|
55
|
+
<th class="n">Name</th>
|
56
|
+
<th class="m">Last Modified</th>
|
57
|
+
<th class="s">Size</th>
|
58
|
+
<th class="t">Type</th>
|
59
|
+
</tr>
|
60
|
+
</thead>
|
61
|
+
<tbody>
|
62
|
+
<tr>
|
63
|
+
<td class="n"><a href="#{display/'..'}/">Parent Directory</a>/</td>
|
64
|
+
<td class="m"> </td>
|
65
|
+
<td class="s">- </td>
|
66
|
+
<td class="t">Directory</td>
|
67
|
+
</tr>
|
68
|
+
%s
|
69
|
+
%s
|
70
|
+
</tbody>
|
71
|
+
</table>
|
72
|
+
</div>
|
73
|
+
<div class="foot">%s</div>
|
74
|
+
</body>
|
75
|
+
</html>
|
76
|
+
)
|
77
|
+
|
78
|
+
dirs, files = Dir[path/'*'].partition{|file| ::File.directory?(file) }
|
79
|
+
dir_body, file_body = [], []
|
80
|
+
|
81
|
+
dirs.each do |dir|
|
82
|
+
basename = ::File.basename(dir)
|
83
|
+
dir_body << %[<tr>
|
84
|
+
<td class="n"><a href="#{display/basename}">#{basename}/</a></td>
|
85
|
+
<td class="m"> </td>
|
86
|
+
<td class="s">- </td>
|
87
|
+
<td class="t">Directory</td>
|
88
|
+
</tr>]
|
89
|
+
end
|
90
|
+
|
91
|
+
time_format = "%Y-%b-%d %H:%M:%S"
|
92
|
+
files.each do |file|
|
93
|
+
basename = ::File.basename(file)
|
94
|
+
time = ::File.mtime(file).strftime(time_format)
|
95
|
+
size = ::File.size(file).human_readable_filesize_format
|
96
|
+
mime = Tool::MIME.type_for(file)
|
97
|
+
file_body << %[<tr>
|
98
|
+
<td class="n"><a href="#{display/basename}">#{basename}</a></td>
|
99
|
+
<td class="m">#{time}</td>
|
100
|
+
<td class="s">#{size}</td>
|
101
|
+
<td class="t">#{mime}</td>
|
102
|
+
</tr>]
|
103
|
+
end
|
104
|
+
|
105
|
+
version = "ramaze/#{Ramaze::VERSION}"
|
106
|
+
wrapper % [
|
107
|
+
dir_body. join("\n "),
|
108
|
+
file_body.join("\n "),
|
109
|
+
version
|
110
|
+
]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|