ramaze 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +14 -29
- data/bin/ramaze +2 -3
- data/doc/AUTHORS +5 -2
- data/doc/CHANGELOG +262 -9
- data/doc/FAQ +6 -6
- data/doc/meta/announcement.txt +5 -19
- data/doc/tutorial/todolist.html +47 -57
- data/doc/tutorial/todolist.mkd +47 -55
- data/examples/memleak_detector.rb +31 -0
- data/examples/todolist/src/controller/main.rb +14 -13
- data/examples/todolist/src/element/page.rb +2 -2
- data/examples/todolist/src/model.rb +2 -2
- data/examples/todolist/todolist.db +0 -4
- data/examples/whywiki/main.rb +2 -2
- data/examples/whywiki/template/edit.xhtml +1 -1
- data/examples/whywiki/template/show.xhtml +3 -3
- data/lib/proto/src/controller/main.rb +18 -1
- data/lib/proto/template/index.xhtml +11 -2
- data/lib/ramaze.rb +1 -1
- data/lib/ramaze/action.rb +104 -5
- data/lib/ramaze/action/render.rb +54 -0
- data/lib/ramaze/adapter.rb +2 -1
- data/lib/ramaze/adapter/mongrel.rb +13 -4
- data/lib/ramaze/cache.rb +17 -8
- data/lib/ramaze/cache/memcached.rb +1 -5
- data/lib/ramaze/controller.rb +51 -18
- data/lib/ramaze/controller/resolve.rb +19 -14
- data/lib/ramaze/dispatcher.rb +13 -16
- data/lib/ramaze/dispatcher/action.rb +2 -3
- data/lib/ramaze/dispatcher/error.rb +8 -3
- data/lib/ramaze/dispatcher/file.rb +1 -4
- data/lib/ramaze/error.rb +5 -5
- data/lib/ramaze/global.rb +7 -1
- data/lib/ramaze/global/globalstruct.rb +1 -3
- data/lib/ramaze/helper/aspect.rb +8 -10
- data/lib/ramaze/helper/cgi.rb +21 -3
- data/lib/ramaze/helper/identity.rb +4 -6
- data/lib/ramaze/helper/link.rb +4 -4
- data/lib/ramaze/helper/pager.rb +316 -0
- data/lib/ramaze/helper/partial.rb +37 -0
- data/lib/ramaze/helper/stack.rb +1 -1
- data/lib/ramaze/inform.rb +9 -0
- data/lib/ramaze/inform/hub.rb +5 -0
- data/lib/ramaze/inform/informer.rb +12 -6
- data/lib/ramaze/inform/informing.rb +32 -7
- data/lib/ramaze/inform/knotify.rb +21 -0
- data/lib/ramaze/inform/xosd.rb +58 -24
- data/lib/ramaze/sourcereload.rb +30 -1
- data/lib/ramaze/template.rb +33 -12
- data/lib/ramaze/template/amrita2.rb +21 -20
- data/lib/ramaze/template/erubis.rb +18 -14
- data/lib/ramaze/template/ezamar.rb +15 -26
- data/lib/ramaze/template/ezamar/element.rb +1 -1
- data/lib/ramaze/template/ezamar/engine.rb +45 -36
- data/lib/ramaze/template/ezamar/morpher.rb +3 -3
- data/lib/ramaze/template/ezamar/render_partial.rb +26 -0
- data/lib/ramaze/template/haml.rb +23 -18
- data/lib/ramaze/template/liquid.rb +5 -3
- data/lib/ramaze/template/markaby.rb +14 -11
- data/lib/ramaze/template/remarkably.rb +11 -5
- data/lib/ramaze/tool/localize.rb +12 -4
- data/lib/ramaze/tool/tidy.rb +26 -23
- data/lib/ramaze/trinity/request.rb +11 -7
- data/lib/ramaze/trinity/session.rb +24 -8
- data/lib/ramaze/version.rb +1 -1
- data/rake_tasks/maintaince.rake +136 -11
- data/spec/examples/templates/template_liquid.rb +6 -3
- data/spec/examples/todolist.rb +1 -2
- data/spec/helper/minimal.rb +7 -7
- data/spec/ramaze/action/basics.rb +19 -0
- data/spec/ramaze/action/render.rb +18 -0
- data/spec/ramaze/controller.rb +1 -1
- data/spec/ramaze/controller/template_resolving.rb +1 -1
- data/spec/ramaze/dispatcher/file.rb +24 -0
- data/spec/ramaze/error.rb +28 -29
- data/spec/ramaze/helper/cgi.rb +43 -0
- data/spec/ramaze/helper/pager.rb +27 -0
- data/spec/ramaze/helper/partial.rb +38 -0
- data/spec/ramaze/helper/template/partial.xhtml +1 -0
- data/spec/ramaze/inform/informer.rb +1 -1
- data/spec/ramaze/localize.rb +1 -1
- data/spec/ramaze/morpher.rb +3 -3
- data/spec/ramaze/request.rb +1 -3
- data/spec/ramaze/template.rb +9 -7
- data/spec/ramaze/template/haml.rb +2 -1
- metadata +21 -7
- data/examples/todolist/public/404.jpg +0 -0
- data/examples/todolist/public/error.xhtml +0 -74
- data/lib/ramaze/controller/render.rb +0 -90
@@ -11,7 +11,7 @@ module Ramaze
|
|
11
11
|
# For your own usage you should use another namespace.
|
12
12
|
|
13
13
|
def initialize(host = 'localhost', port = '11211', namespace = 'ramaze')
|
14
|
-
@cache = MemCache.new("#{host}:#{port}", :namespace => namespace)
|
14
|
+
@cache = MemCache.new("#{host}:#{port}", :namespace => namespace, :multithread => true)
|
15
15
|
end
|
16
16
|
|
17
17
|
# please read the documentation of memcache-client for further methods.
|
@@ -73,11 +73,7 @@ class MemCache
|
|
73
73
|
|
74
74
|
class Server
|
75
75
|
def flush_all
|
76
|
-
@mutex.lock if @multithread
|
77
|
-
|
78
76
|
socket.write "flush_all\r\n"
|
79
|
-
ensure
|
80
|
-
@mutex.unlock if @multithread
|
81
77
|
end
|
82
78
|
end
|
83
79
|
end
|
data/lib/ramaze/controller.rb
CHANGED
@@ -6,7 +6,6 @@ require 'ramaze/template'
|
|
6
6
|
require 'ramaze/action'
|
7
7
|
|
8
8
|
require 'ramaze/controller/resolve'
|
9
|
-
require 'ramaze/controller/render'
|
10
9
|
require 'ramaze/controller/error'
|
11
10
|
|
12
11
|
module Ramaze
|
@@ -19,8 +18,6 @@ module Ramaze
|
|
19
18
|
|
20
19
|
helper :redirect, :link, :file, :flash, :cgi
|
21
20
|
|
22
|
-
trait[:template_extensions] ||= {}
|
23
|
-
|
24
21
|
# Whether or not to map this controller on startup automatically
|
25
22
|
|
26
23
|
trait[:automap] ||= true
|
@@ -29,24 +26,33 @@ module Ramaze
|
|
29
26
|
|
30
27
|
trait[:map] ||= nil
|
31
28
|
|
29
|
+
# Modules that are excluded from the Action lookup
|
30
|
+
|
32
31
|
trait :exclude_action_modules => [Kernel, Object, PP::ObjectMixin]
|
33
32
|
|
33
|
+
# Caches patterns for the given path.
|
34
|
+
|
34
35
|
trait :pattern_cache => Hash.new{|h,k| h[k] = Controller.pattern_for(k) }
|
35
36
|
|
36
37
|
class << self
|
37
38
|
include Ramaze::Helper
|
38
39
|
extend Ramaze::Helper
|
39
40
|
|
41
|
+
# When Controller is subclassed the resulting class is placed in
|
42
|
+
# Global.controllers and a new trait :actions_cached is set on it.
|
43
|
+
|
40
44
|
def inherited controller
|
41
45
|
controller.trait :actions_cached => Set.new
|
42
46
|
Global.controllers << controller
|
43
47
|
end
|
44
48
|
|
49
|
+
# called from Ramaze.startup, adds Cache.actions and Cache.patterns, walks
|
50
|
+
# all controllers subclassed so far and adds them to the Global.mapping if
|
51
|
+
# they are not assigned yet.
|
52
|
+
|
45
53
|
def startup options = {}
|
46
54
|
Inform.debug("found Controllers: #{Global.controllers.inspect}")
|
47
55
|
|
48
|
-
Cache.add :actions, :patterns
|
49
|
-
|
50
56
|
Global.controllers.each do |controller|
|
51
57
|
if map = controller.mapping
|
52
58
|
Inform.debug("mapping #{map} => #{controller}")
|
@@ -57,25 +63,37 @@ module Ramaze
|
|
57
63
|
Inform.debug("mapped Controllers: #{Global.mapping.inspect}")
|
58
64
|
end
|
59
65
|
|
66
|
+
# checks paths for existance and logs a warning if it doesn't exist yet.
|
67
|
+
|
60
68
|
def check_path(path, message)
|
61
69
|
Inform.warn(message) unless File.directory?(path)
|
62
70
|
end
|
63
71
|
|
72
|
+
# if trait[:automap] is set and controller is not in Global.mapping yet
|
73
|
+
# this will build a new default mapping-point, (Main|Base|Index)* are put
|
74
|
+
# at '/' by default.
|
75
|
+
|
64
76
|
def mapping
|
65
77
|
global_mapping = Global.mapping.invert[self]
|
66
78
|
return global_mapping if global_mapping
|
67
79
|
if ancestral_trait[:automap]
|
68
80
|
name = self.to_s.gsub('Controller', '').split('::').last
|
69
|
-
|
81
|
+
name == 'Main' ? '/' : "/#{name.snake_case}"
|
70
82
|
end
|
71
83
|
end
|
72
84
|
|
85
|
+
# Map Controller to the given syms or strings.
|
86
|
+
|
73
87
|
def map(*syms)
|
74
88
|
syms.each do |sym|
|
75
89
|
Global.mapping[sym.to_s] = self
|
76
90
|
end
|
77
91
|
end
|
78
92
|
|
93
|
+
# Define a template_root for Controller, returns the current template_root
|
94
|
+
# if no argument is given.
|
95
|
+
# Runs every given path through Controller::check_path
|
96
|
+
|
79
97
|
def template_root path = nil
|
80
98
|
if path
|
81
99
|
message = "#{self}.template_root is #{path} which does not exist"
|
@@ -86,33 +104,48 @@ module Ramaze
|
|
86
104
|
end
|
87
105
|
end
|
88
106
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
107
|
+
# This is used for template rerouting, takes action, optionally a
|
108
|
+
# controller and action to route to.
|
109
|
+
#
|
110
|
+
# Usage:
|
111
|
+
# class MainController
|
112
|
+
# template :index, OtherController, :list
|
113
|
+
# template :foo, :bar
|
114
|
+
#
|
115
|
+
# def index
|
116
|
+
# 'will use template from OtherController#list'
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# def foo
|
120
|
+
# 'will use template from self#bar'
|
121
|
+
# end
|
122
|
+
# end
|
98
123
|
|
99
124
|
def template(this, from, that = nil)
|
100
125
|
from, that = self, from unless that
|
101
126
|
trait "#{this}_template" => [from, that.to_s]
|
102
127
|
end
|
103
128
|
|
129
|
+
# Return Controller of current Action
|
130
|
+
|
104
131
|
def current
|
105
|
-
|
132
|
+
action = Action.current
|
133
|
+
action.instance || action.controller
|
106
134
|
end
|
107
135
|
|
136
|
+
# Entering point for Dispatcher, first Controller::resolve(path) and then
|
137
|
+
# renders the resulting Action.
|
138
|
+
|
108
139
|
def handle path
|
109
|
-
|
110
|
-
|
140
|
+
action = resolve(path)
|
141
|
+
action.render
|
111
142
|
end
|
112
143
|
end
|
113
144
|
|
114
145
|
private
|
115
146
|
|
147
|
+
# Simplistic render, rerouting to Controller.handle(*args)
|
148
|
+
|
116
149
|
def render *args
|
117
150
|
self.class.handle(*args)
|
118
151
|
end
|
@@ -13,7 +13,10 @@ module Ramaze
|
|
13
13
|
# manveru: everything further down is considered 500
|
14
14
|
|
15
15
|
def resolve(path)
|
16
|
-
|
16
|
+
if found = Cache.resolved[path]
|
17
|
+
return found
|
18
|
+
end
|
19
|
+
|
17
20
|
mapping = Global.mapping
|
18
21
|
controllers = Global.controllers
|
19
22
|
|
@@ -31,7 +34,7 @@ module Ramaze
|
|
31
34
|
|
32
35
|
valid_action = (action.method or (params.empty? && action.template))
|
33
36
|
|
34
|
-
return
|
37
|
+
return Cache.resolved[path] = action if valid_action
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -52,8 +55,11 @@ module Ramaze
|
|
52
55
|
template ||= resolve_template(path)
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
Action.create :path => path,
|
59
|
+
:method => method,
|
60
|
+
:params => params,
|
61
|
+
:template => template,
|
62
|
+
:controller => self
|
57
63
|
end
|
58
64
|
|
59
65
|
def resolve_template(action)
|
@@ -68,13 +74,8 @@ module Ramaze
|
|
68
74
|
end
|
69
75
|
|
70
76
|
def template_paths
|
71
|
-
|
72
|
-
|
73
|
-
template_root
|
74
|
-
else
|
75
|
-
Global.template_root / Global.mapping.invert[self]
|
76
|
-
end
|
77
|
-
[ first_path, public_root, Global.public_root ].compact
|
77
|
+
@template_root ||= Global.template_root / Global.mapping.invert[self]
|
78
|
+
[ @template_root, Global.public_root, Global.public_proto ].compact
|
78
79
|
end
|
79
80
|
|
80
81
|
def resolve_method(name, *params)
|
@@ -128,17 +129,21 @@ module Ramaze
|
|
128
129
|
end
|
129
130
|
|
130
131
|
def extension_order
|
131
|
-
t_extensions =
|
132
|
+
t_extensions = Template::ENGINES
|
132
133
|
engine = trait[:engine]
|
133
|
-
c_extensions = t_extensions.
|
134
|
-
all_extensions = t_extensions.
|
134
|
+
c_extensions = t_extensions.select{|k,v| k == engine}.map{|k,v| v}.flatten
|
135
|
+
all_extensions = t_extensions.map{|k,v| v}.flatten
|
135
136
|
(c_extensions + all_extensions).uniq
|
136
137
|
end
|
137
138
|
|
139
|
+
# Raises Ramaze::Error::NoController
|
140
|
+
|
138
141
|
def raise_no_controller(path)
|
139
142
|
raise Ramaze::Error::NoController, "No Controller found for `#{path}'"
|
140
143
|
end
|
141
144
|
|
145
|
+
# Raises Ramaze::Error::NoAction
|
146
|
+
|
142
147
|
def raise_no_action(controller, path)
|
143
148
|
raise Ramaze::Error::NoAction, "No Action found for `#{path}' on #{controller}"
|
144
149
|
end
|
data/lib/ramaze/dispatcher.rb
CHANGED
@@ -14,21 +14,9 @@ require 'ramaze/dispatcher/file'
|
|
14
14
|
module Ramaze
|
15
15
|
module Dispatcher
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
]
|
21
|
-
|
22
|
-
trait :handle_error => {
|
23
|
-
Exception =>
|
24
|
-
[ STATUS_CODE["Internal Server Error"], '/error' ],
|
25
|
-
Ramaze::Error::NoAction =>
|
26
|
-
[ STATUS_CODE["Not Found"], '/error' ],
|
27
|
-
Ramaze::Error::NoController =>
|
28
|
-
[ STATUS_CODE["Not Found"], '/error' ],
|
29
|
-
}
|
30
|
-
|
31
|
-
Cache.add :shield
|
17
|
+
# requests are passed to every
|
18
|
+
|
19
|
+
FILTER = [ Dispatcher::File, Dispatcher::Action ] unless defined?(FILTER)
|
32
20
|
|
33
21
|
trait :shielded => [ STATUS_CODE["Not Found"] ]
|
34
22
|
|
@@ -88,14 +76,20 @@ module Ramaze
|
|
88
76
|
end
|
89
77
|
end
|
90
78
|
|
79
|
+
# Calls .process(path) on every class in Dispatcher::FILTER until one
|
80
|
+
# returns something else than false/nil.
|
81
|
+
# Raises NoAction otherwise.
|
82
|
+
|
91
83
|
def filter path
|
92
|
-
|
84
|
+
FILTER.each do |dispatcher|
|
93
85
|
result = dispatcher.process(path)
|
94
86
|
return result if result
|
95
87
|
end
|
96
88
|
raise Ramaze::Error::NoAction, "No Dispatcher found for `#{path}'"
|
97
89
|
end
|
98
90
|
|
91
|
+
# build a response, default values are from the current response.
|
92
|
+
|
99
93
|
def build_response body = response.body, status = response.status, head = response.header
|
100
94
|
set_cookie if Global.cookies
|
101
95
|
head.each do |key, value|
|
@@ -107,6 +101,9 @@ module Ramaze
|
|
107
101
|
return response
|
108
102
|
end
|
109
103
|
|
104
|
+
# finalizes the session and assigns the key to the response via
|
105
|
+
# set_cookie.
|
106
|
+
|
110
107
|
def set_cookie
|
111
108
|
session.finalize
|
112
109
|
hash = {:value => session.session_id, :path => '/'}
|
@@ -10,7 +10,7 @@ module Ramaze
|
|
10
10
|
|
11
11
|
# The response is passed to each filter by sending .call(response) to it.
|
12
12
|
|
13
|
-
|
13
|
+
FILTER = [
|
14
14
|
# Ramaze::Tool::Localize,
|
15
15
|
# Ramaze::Tool::Tidy
|
16
16
|
]
|
@@ -19,8 +19,7 @@ module Ramaze
|
|
19
19
|
def process(path)
|
20
20
|
body = Controller.handle(path)
|
21
21
|
response = Dispatcher.build_response(body)
|
22
|
-
|
23
|
-
filter.inject(response){|r,f| f.call(r) }
|
22
|
+
FILTER.inject(response){|r,f| f.call(r) }
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
@@ -4,6 +4,12 @@
|
|
4
4
|
module Ramaze
|
5
5
|
module Dispatcher
|
6
6
|
class Error
|
7
|
+
HANDLE_ERROR = {
|
8
|
+
Exception => [ 500, '/error' ],
|
9
|
+
Ramaze::Error::NoAction => [ 404, '/error' ],
|
10
|
+
Ramaze::Error::NoController => [ 404, '/error' ],
|
11
|
+
}
|
12
|
+
|
7
13
|
class << self
|
8
14
|
trait :last_error => nil
|
9
15
|
|
@@ -11,10 +17,9 @@ module Ramaze
|
|
11
17
|
log_error(error)
|
12
18
|
|
13
19
|
Thread.current[:exception] = error
|
14
|
-
handle_error = Dispatcher.trait[:handle_error]
|
15
20
|
|
16
|
-
key = error.class.ancestors.find{|a|
|
17
|
-
status, path = *
|
21
|
+
key = error.class.ancestors.find{|a| HANDLE_ERROR[a]}
|
22
|
+
status, path = *HANDLE_ERROR[key || Exception]
|
18
23
|
|
19
24
|
unless error.message =~ %r(`#{path.split('/').last}')
|
20
25
|
Response.current.status = status
|
@@ -11,10 +11,7 @@ module Ramaze
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def lookup_paths
|
14
|
-
[
|
15
|
-
Global.controllers.map{|c| c.trait[:public]},
|
16
|
-
'./public'
|
17
|
-
].flatten.select{|f| ::File.directory?(f.to_s)}.map{|f| ::File.expand_path(f)}
|
14
|
+
[ Global.public_proto, Global.public_root ].flatten
|
18
15
|
end
|
19
16
|
|
20
17
|
def open_file(path)
|
data/lib/ramaze/error.rb
CHANGED
@@ -5,17 +5,17 @@ module Ramaze
|
|
5
5
|
|
6
6
|
# The general Namespace for Ramazes Errorclasses
|
7
7
|
|
8
|
-
|
8
|
+
class Error < StandardError
|
9
9
|
# No action found on Controller
|
10
|
-
class NoAction <
|
10
|
+
class NoAction < Error; end
|
11
11
|
|
12
12
|
# No Controller found for request
|
13
|
-
class NoController <
|
13
|
+
class NoController < Error; end
|
14
14
|
|
15
15
|
# Wrong parameter count for action
|
16
|
-
class WrongParameterCount <
|
16
|
+
class WrongParameterCount < Error; end
|
17
17
|
|
18
18
|
# Error while transformation in template
|
19
|
-
class Template <
|
19
|
+
class Template < Error; end
|
20
20
|
end
|
21
21
|
end
|
data/lib/ramaze/global.rb
CHANGED
@@ -29,6 +29,9 @@ module Ramaze
|
|
29
29
|
o "Turn on cookies for all requests.",
|
30
30
|
:cookies => true, :cli => true
|
31
31
|
|
32
|
+
o "Compile Templates",
|
33
|
+
:compile => false, :cli => false
|
34
|
+
|
32
35
|
o "All subclasses of Controller are collected here.",
|
33
36
|
:controllers => Set.new
|
34
37
|
|
@@ -51,7 +54,10 @@ module Ramaze
|
|
51
54
|
:port => 7000, :cli => 7000
|
52
55
|
|
53
56
|
o "Specify the shadowing public directory (default in proto)",
|
54
|
-
:
|
57
|
+
:public_proto => ( BASEDIR / 'proto' / 'public' )
|
58
|
+
|
59
|
+
o "Specify the public directory of your application serving static files",
|
60
|
+
:public_root => File.expand_path('./public')
|
55
61
|
|
56
62
|
o "Record all Request objects by assigning a filtering Proc to me.",
|
57
63
|
:record => false
|
@@ -56,7 +56,7 @@ module Ramaze
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def ports
|
59
|
-
(port..(port + (spawn - 1)))
|
59
|
+
(port.to_i..(port.to_i + (spawn.to_i - 1)))
|
60
60
|
end
|
61
61
|
|
62
62
|
def sourcereload=(interval)
|
@@ -71,8 +71,6 @@ module Ramaze
|
|
71
71
|
keys.map{|key| __send__(key)}
|
72
72
|
end
|
73
73
|
|
74
|
-
private # Internal helpers
|
75
|
-
|
76
74
|
def create_member key, value = nil
|
77
75
|
Inform.warn "Create #{key}=#{value.inspect} on Global"
|
78
76
|
|
data/lib/ramaze/helper/aspect.rb
CHANGED
@@ -56,19 +56,17 @@ module Ramaze
|
|
56
56
|
meths = instance_methods(false)
|
57
57
|
wrap(*meths, &block)
|
58
58
|
end
|
59
|
+
end
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
class Action
|
62
|
+
def before_process
|
63
|
+
block = controller.ancestral_trait[:aspects][:before][method]
|
64
|
+
instance.instance_eval(&block) if block
|
64
65
|
end
|
65
66
|
|
66
|
-
def after_process
|
67
|
-
block = ancestral_trait[:aspects][:after][
|
68
|
-
|
69
|
-
after
|
67
|
+
def after_process
|
68
|
+
block = controller.ancestral_trait[:aspects][:after][method]
|
69
|
+
instance.instance_eval(&block) if block
|
70
70
|
end
|
71
|
-
|
72
|
-
module_function :before_process, :after_process
|
73
71
|
end
|
74
72
|
end
|