ramaze 0.1.1 → 0.1.2
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/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
@@ -0,0 +1,31 @@
|
|
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
|
+
require 'ramaze'
|
5
|
+
|
6
|
+
# you can access it now with http://localhost:7000/
|
7
|
+
# This should output
|
8
|
+
# Hello, World!
|
9
|
+
# in your browser
|
10
|
+
|
11
|
+
class MainController < Ramaze::Controller
|
12
|
+
def index
|
13
|
+
"Hello, World!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def check
|
18
|
+
os = []
|
19
|
+
ObjectSpace.each_object{|o| os << o }
|
20
|
+
p os.inject(Hash.new(0)){|s,v| s[v.class] += 1; s}.sort_by{|k,v| v}
|
21
|
+
end
|
22
|
+
|
23
|
+
Thread.new do
|
24
|
+
loop do
|
25
|
+
check
|
26
|
+
sleep 5
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Ramaze::Inform.loggers.clear
|
31
|
+
Ramaze.start :adapter => :mongrel, :sourcereload => false
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
2
|
# All files in this distribution are subject to the terms of the Ruby license.
|
3
3
|
|
4
|
-
|
4
|
+
# Default url mappings are:
|
5
|
+
# a controller called Main is mapped on the root of the site: /
|
6
|
+
# a controller called Something is mapped on: /something
|
7
|
+
# If you want to override this, add a line like this inside the class
|
8
|
+
# map '/otherurl'
|
9
|
+
# this will force the controller to be mounted on: /otherurl
|
5
10
|
|
6
|
-
|
11
|
+
class MainController < Controller
|
7
12
|
|
8
13
|
def index
|
9
14
|
@tasks = []
|
10
|
-
TodoList.original.each do |title,
|
11
|
-
if
|
15
|
+
TodoList.original.each do |title, value|
|
16
|
+
if value[:done]
|
12
17
|
status = 'done'
|
13
18
|
toggle = A('Open Task', :href => Rs(:open, title))
|
14
19
|
else
|
@@ -25,7 +30,7 @@ class MainController < Controller
|
|
25
30
|
if title = request['title']
|
26
31
|
title.strip!
|
27
32
|
if title.empty?
|
28
|
-
|
33
|
+
failed("Please enter a title")
|
29
34
|
redirect '/new'
|
30
35
|
end
|
31
36
|
TodoList[title] = {:done => false}
|
@@ -44,22 +49,18 @@ class MainController < Controller
|
|
44
49
|
TodoList.delete title
|
45
50
|
end
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
def redirect_index
|
50
|
-
redirect(Rs())
|
51
|
-
end
|
52
|
+
helper :aspect
|
53
|
+
after(:create, :open, :close, :delete){ redirect(Rs()) }
|
52
54
|
|
53
55
|
private
|
54
56
|
|
55
|
-
def
|
57
|
+
def failed(message)
|
56
58
|
flash[:error] = message
|
57
59
|
end
|
58
60
|
|
59
61
|
def task_status title, status
|
60
|
-
p title
|
61
62
|
unless task = TodoList[title]
|
62
|
-
|
63
|
+
failed "No such Task: `#{title}'"
|
63
64
|
redirect_referer
|
64
65
|
end
|
65
66
|
|
data/examples/whywiki/main.rb
CHANGED
@@ -16,7 +16,7 @@ class WikiController < Controller
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def show page = 'Home'
|
19
|
-
@page = page
|
19
|
+
@page = CGI.unescape(page)
|
20
20
|
@text = Db[page].to_s
|
21
21
|
|
22
22
|
@text.gsub!(/\[\[(.*?)\]\]/) do |m|
|
@@ -28,7 +28,7 @@ class WikiController < Controller
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def edit page = 'Home'
|
31
|
-
@page = page
|
31
|
+
@page = CGI.unescape(page)
|
32
32
|
@text = Db[page]
|
33
33
|
end
|
34
34
|
|
@@ -6,14 +6,14 @@
|
|
6
6
|
a.nonexists{ color: #f00; }
|
7
7
|
</style>
|
8
8
|
</head>
|
9
|
-
#{
|
9
|
+
#{ A("< Home", :href => R(self)) unless @page == "Home" }
|
10
10
|
<body>
|
11
11
|
<h1>#{@page}</h1>
|
12
12
|
<?r if @text.empty? ?>
|
13
|
-
#{
|
13
|
+
#{ A("Create #{@page}?",:href => R(self, :edit, CGI.escape(@page))) }
|
14
14
|
<?r else ?>
|
15
15
|
<div>
|
16
|
-
#{
|
16
|
+
#{ A("Edit #{@page}?", :href => R(self, :edit, CGI.escape(@page))) }
|
17
17
|
#{@text}
|
18
18
|
</div>
|
19
19
|
<?r end ?>
|
@@ -1,8 +1,25 @@
|
|
1
1
|
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
2
|
# All files in this distribution are subject to the terms of the Ruby license.
|
3
3
|
|
4
|
+
# Default url mappings are:
|
5
|
+
# a controller called Main is mapped on the root of the site: /
|
6
|
+
# a controller called Something is mapped on: /something
|
7
|
+
# If you want to override this, add a line like this inside the class
|
8
|
+
# map '/otherurl'
|
9
|
+
# this will force the controller to be mounted on: /otherurl
|
10
|
+
|
4
11
|
class MainController < Controller
|
12
|
+
|
13
|
+
# the index action is called automatically when no other action is specified
|
5
14
|
def index
|
6
|
-
"
|
15
|
+
@welcome = "Welcome to Ramaze!"
|
7
16
|
end
|
17
|
+
|
18
|
+
# the string returned at the end of the function is used as the html body
|
19
|
+
# if there is no template for the action. if there is a template, the string
|
20
|
+
# is silently ignored
|
21
|
+
def notemplate
|
22
|
+
"there is no template associated with this action"
|
23
|
+
end
|
24
|
+
|
8
25
|
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
<Page>
|
2
|
-
<h1
|
2
|
+
<h1>#{@welcome}</h1>
|
3
|
+
<p>Ramaze is working correctly with this application, now you can start working</p
|
4
|
+
|
3
5
|
<p>
|
4
|
-
|
6
|
+
To start you can modify:
|
7
|
+
<ol>
|
8
|
+
<li><code>template/index.xhtml</code>, which this text</li>
|
9
|
+
<li><code>src/elements/page.rb</code>, which is the Element around this text</li>
|
10
|
+
<li><code>src/controllers/main.rb</code>, where you can change the header of this page and the <a href="/notemplate">notemplate</a> action</li>
|
11
|
+
<li><code>src/model.rb</code>, which is the the persistent backend for your app</li>
|
12
|
+
</ol>
|
5
13
|
</p>
|
14
|
+
<p>You can also read the tutorial in the <code>doc/</code> directory of ramaze or browse the <a href="http://ramaze.rubyforge.org/rdoc/files/doc/README.html">rdocs</a><p>
|
6
15
|
</Page>
|
data/lib/ramaze.rb
CHANGED
data/lib/ramaze/action.rb
CHANGED
@@ -5,17 +5,116 @@ module Ramaze
|
|
5
5
|
|
6
6
|
unless defined?(Action) # prevent problems for SourceReload
|
7
7
|
|
8
|
+
members = %w[method params template controller path binding engine instance]
|
9
|
+
|
8
10
|
# The Action holds information that is essential to render the action for a
|
9
11
|
# request.
|
10
12
|
|
11
|
-
class Action < Struct.new('Action',
|
12
|
-
|
13
|
-
|
13
|
+
class Action < Struct.new('Action', *members)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'ramaze/action/render'
|
18
|
+
|
19
|
+
class Action
|
20
|
+
class << self
|
21
|
+
|
22
|
+
# Instantiate with given Hash, takes both string/symbol keys.
|
23
|
+
# Only keys that match members of the Action-Struct are used.
|
24
|
+
|
25
|
+
def create(hash = {})
|
26
|
+
i = new
|
27
|
+
members.each do |key|
|
28
|
+
i.send("#{key}=", (hash[key] || hash[key.to_sym]))
|
29
|
+
end
|
30
|
+
i
|
14
31
|
end
|
15
32
|
|
16
|
-
|
17
|
-
|
33
|
+
# Thread.current[:action] returns the instance of Action you are currently in.
|
34
|
+
|
35
|
+
def current
|
36
|
+
Thread.current[:action]
|
18
37
|
end
|
19
38
|
end
|
39
|
+
|
40
|
+
# nicer representation of the Action
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
m, p, t = method.inspect, params.inspect, template.inspect
|
44
|
+
%{#<Action method=#{m}, params=#{p} template=#{t}>}
|
45
|
+
end
|
46
|
+
|
47
|
+
# Set the method, will be converted to a string and set to nil if empty.
|
48
|
+
|
49
|
+
def method=(meth)
|
50
|
+
meth = meth.to_s
|
51
|
+
self[:method] = (meth.empty? ? nil : meth)
|
52
|
+
end
|
53
|
+
|
54
|
+
# runs all parameters assigned through flatten and CGI::unescape
|
55
|
+
|
56
|
+
def params=(*par)
|
57
|
+
self[:params] = par.flatten.compact.map{|pa| CGI.unescape(pa.to_s)}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Use this as key for caches.
|
61
|
+
|
62
|
+
def relaxed_hash
|
63
|
+
[controller, method, params, template, path].hash
|
64
|
+
end
|
65
|
+
|
66
|
+
# A Hash representation of Action
|
67
|
+
|
68
|
+
def to_hash
|
69
|
+
hash = {}
|
70
|
+
members.each{|m| hash[m.to_sym] = send(m)}
|
71
|
+
hash
|
72
|
+
end
|
73
|
+
|
74
|
+
# Determines based on controller.trait[:engine] and the template extensions
|
75
|
+
# which engine has to be used.
|
76
|
+
# Defaults to Template::Ezamar
|
77
|
+
|
78
|
+
def engine
|
79
|
+
return self[:engine] if self[:engine]
|
80
|
+
default = controller.trait.fetch(:engine, Template::Ezamar)
|
81
|
+
return default unless template
|
82
|
+
|
83
|
+
engines = Template::ENGINES
|
84
|
+
return default if engines.empty?
|
85
|
+
|
86
|
+
ext = File.extname(template).gsub(/^\./, '')
|
87
|
+
ext_engine = engines.find{|e| e.last.include?(ext)}.first
|
88
|
+
|
89
|
+
self[:engine] = (ext_engine || default)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns an instance of controller, will be cached on first access.
|
93
|
+
|
94
|
+
def instance
|
95
|
+
self[:instance] ||= controller.new
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns a binding of the instance, will be cached on first access.
|
99
|
+
|
100
|
+
def binding
|
101
|
+
self[:binding] ||= instance.instance_eval{ binding }
|
102
|
+
end
|
103
|
+
|
104
|
+
# Hook for AspectHelper
|
105
|
+
|
106
|
+
def before_process
|
107
|
+
end
|
108
|
+
|
109
|
+
# Hook for AspectHelper
|
110
|
+
|
111
|
+
def after_process
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Shortcut to create new instances of Action via Action::fill
|
116
|
+
|
117
|
+
def self.Action(hash = {})
|
118
|
+
Action.create(hash)
|
20
119
|
end
|
21
120
|
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
class Action
|
6
|
+
|
7
|
+
# Render this instance of Action, this will (eventually) pass itself to
|
8
|
+
# Action#engine.transform
|
9
|
+
# Usage, given that Foo is a Controller and has the method/template
|
10
|
+
# for index:
|
11
|
+
# > Action(:controller => Foo).render
|
12
|
+
# #> 'bar'
|
13
|
+
|
14
|
+
def render
|
15
|
+
Inform.debug("The Action: #{self}")
|
16
|
+
Thread.current[:action] = self
|
17
|
+
|
18
|
+
if should_cache?
|
19
|
+
cached_render
|
20
|
+
else
|
21
|
+
uncached_render
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def cached_render
|
26
|
+
action_cache = Cache.actions
|
27
|
+
|
28
|
+
if out = action_cache[relaxed_hash]
|
29
|
+
Inform.debug("Using Cached version")
|
30
|
+
return out
|
31
|
+
end
|
32
|
+
|
33
|
+
Inform.debug("Compiling Action")
|
34
|
+
action_cache[relaxed_hash] = uncached_render
|
35
|
+
end
|
36
|
+
|
37
|
+
def uncached_render
|
38
|
+
[ before_process,
|
39
|
+
engine.transform(self),
|
40
|
+
after_process,
|
41
|
+
].join
|
42
|
+
end
|
43
|
+
|
44
|
+
def should_cache?
|
45
|
+
ctrait = controller.trait
|
46
|
+
actions_cached = ctrait[:actions_cached]
|
47
|
+
|
48
|
+
[ Global.cache_all,
|
49
|
+
ctrait[:cache_all],
|
50
|
+
actions_cached.map{|k| k.to_s}.include?(method),
|
51
|
+
].any?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/ramaze/adapter.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
2
|
# All files in this distribution are subject to the terms of the Ruby license.
|
3
3
|
|
4
|
-
require 'ramaze/adapter'
|
5
|
-
require 'mongrel'
|
6
|
-
require 'rack/handler/mongrel'
|
7
|
-
|
8
4
|
module Ramaze
|
5
|
+
if ENV['SWIFT']
|
6
|
+
require 'swiftcore/swiftiplied_mongrel'
|
7
|
+
Inform.debug "Using Swiftiplied Mongrel"
|
8
|
+
elsif ENV['EVENT']
|
9
|
+
require 'swiftcore/evented_mongrel'
|
10
|
+
Inform.debug "Using Evented Mongrel"
|
11
|
+
else
|
12
|
+
require 'mongrel'
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'ramaze/adapter'
|
16
|
+
require 'rack/handler/mongrel'
|
17
|
+
|
9
18
|
module Adapter
|
10
19
|
class Mongrel < Base
|
11
20
|
class << self
|
data/lib/ramaze/cache.rb
CHANGED
@@ -12,18 +12,27 @@ module Ramaze
|
|
12
12
|
|
13
13
|
class Cache
|
14
14
|
include Enumerable
|
15
|
-
CACHES = {}
|
15
|
+
CACHES = {} unless defined?(CACHES)
|
16
16
|
|
17
|
-
|
18
|
-
# sinleton-methods on Cache
|
17
|
+
class << self
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def startup(options)
|
20
|
+
Cache.add :compiled, :actions, :patterns, :resolved, :shield
|
21
|
+
end
|
22
|
+
|
23
|
+
# This will define a method to access a new cache directly over
|
24
|
+
# sinleton-methods on Cache
|
25
|
+
|
26
|
+
def add *keys
|
27
|
+
keys.each do |key|
|
28
|
+
CACHES[key] = new
|
29
|
+
self.class.class_eval do
|
30
|
+
define_method(key){ CACHES[key] }
|
31
|
+
end
|
25
32
|
end
|
33
|
+
Inform.debug("Added caches for: #{keys.join(', ')}")
|
26
34
|
end
|
35
|
+
|
27
36
|
end
|
28
37
|
|
29
38
|
def initialize(cache = Global.cache)
|