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.
Files changed (89) hide show
  1. data/Rakefile +14 -29
  2. data/bin/ramaze +2 -3
  3. data/doc/AUTHORS +5 -2
  4. data/doc/CHANGELOG +262 -9
  5. data/doc/FAQ +6 -6
  6. data/doc/meta/announcement.txt +5 -19
  7. data/doc/tutorial/todolist.html +47 -57
  8. data/doc/tutorial/todolist.mkd +47 -55
  9. data/examples/memleak_detector.rb +31 -0
  10. data/examples/todolist/src/controller/main.rb +14 -13
  11. data/examples/todolist/src/element/page.rb +2 -2
  12. data/examples/todolist/src/model.rb +2 -2
  13. data/examples/todolist/todolist.db +0 -4
  14. data/examples/whywiki/main.rb +2 -2
  15. data/examples/whywiki/template/edit.xhtml +1 -1
  16. data/examples/whywiki/template/show.xhtml +3 -3
  17. data/lib/proto/src/controller/main.rb +18 -1
  18. data/lib/proto/template/index.xhtml +11 -2
  19. data/lib/ramaze.rb +1 -1
  20. data/lib/ramaze/action.rb +104 -5
  21. data/lib/ramaze/action/render.rb +54 -0
  22. data/lib/ramaze/adapter.rb +2 -1
  23. data/lib/ramaze/adapter/mongrel.rb +13 -4
  24. data/lib/ramaze/cache.rb +17 -8
  25. data/lib/ramaze/cache/memcached.rb +1 -5
  26. data/lib/ramaze/controller.rb +51 -18
  27. data/lib/ramaze/controller/resolve.rb +19 -14
  28. data/lib/ramaze/dispatcher.rb +13 -16
  29. data/lib/ramaze/dispatcher/action.rb +2 -3
  30. data/lib/ramaze/dispatcher/error.rb +8 -3
  31. data/lib/ramaze/dispatcher/file.rb +1 -4
  32. data/lib/ramaze/error.rb +5 -5
  33. data/lib/ramaze/global.rb +7 -1
  34. data/lib/ramaze/global/globalstruct.rb +1 -3
  35. data/lib/ramaze/helper/aspect.rb +8 -10
  36. data/lib/ramaze/helper/cgi.rb +21 -3
  37. data/lib/ramaze/helper/identity.rb +4 -6
  38. data/lib/ramaze/helper/link.rb +4 -4
  39. data/lib/ramaze/helper/pager.rb +316 -0
  40. data/lib/ramaze/helper/partial.rb +37 -0
  41. data/lib/ramaze/helper/stack.rb +1 -1
  42. data/lib/ramaze/inform.rb +9 -0
  43. data/lib/ramaze/inform/hub.rb +5 -0
  44. data/lib/ramaze/inform/informer.rb +12 -6
  45. data/lib/ramaze/inform/informing.rb +32 -7
  46. data/lib/ramaze/inform/knotify.rb +21 -0
  47. data/lib/ramaze/inform/xosd.rb +58 -24
  48. data/lib/ramaze/sourcereload.rb +30 -1
  49. data/lib/ramaze/template.rb +33 -12
  50. data/lib/ramaze/template/amrita2.rb +21 -20
  51. data/lib/ramaze/template/erubis.rb +18 -14
  52. data/lib/ramaze/template/ezamar.rb +15 -26
  53. data/lib/ramaze/template/ezamar/element.rb +1 -1
  54. data/lib/ramaze/template/ezamar/engine.rb +45 -36
  55. data/lib/ramaze/template/ezamar/morpher.rb +3 -3
  56. data/lib/ramaze/template/ezamar/render_partial.rb +26 -0
  57. data/lib/ramaze/template/haml.rb +23 -18
  58. data/lib/ramaze/template/liquid.rb +5 -3
  59. data/lib/ramaze/template/markaby.rb +14 -11
  60. data/lib/ramaze/template/remarkably.rb +11 -5
  61. data/lib/ramaze/tool/localize.rb +12 -4
  62. data/lib/ramaze/tool/tidy.rb +26 -23
  63. data/lib/ramaze/trinity/request.rb +11 -7
  64. data/lib/ramaze/trinity/session.rb +24 -8
  65. data/lib/ramaze/version.rb +1 -1
  66. data/rake_tasks/maintaince.rake +136 -11
  67. data/spec/examples/templates/template_liquid.rb +6 -3
  68. data/spec/examples/todolist.rb +1 -2
  69. data/spec/helper/minimal.rb +7 -7
  70. data/spec/ramaze/action/basics.rb +19 -0
  71. data/spec/ramaze/action/render.rb +18 -0
  72. data/spec/ramaze/controller.rb +1 -1
  73. data/spec/ramaze/controller/template_resolving.rb +1 -1
  74. data/spec/ramaze/dispatcher/file.rb +24 -0
  75. data/spec/ramaze/error.rb +28 -29
  76. data/spec/ramaze/helper/cgi.rb +43 -0
  77. data/spec/ramaze/helper/pager.rb +27 -0
  78. data/spec/ramaze/helper/partial.rb +38 -0
  79. data/spec/ramaze/helper/template/partial.xhtml +1 -0
  80. data/spec/ramaze/inform/informer.rb +1 -1
  81. data/spec/ramaze/localize.rb +1 -1
  82. data/spec/ramaze/morpher.rb +3 -3
  83. data/spec/ramaze/request.rb +1 -3
  84. data/spec/ramaze/template.rb +9 -7
  85. data/spec/ramaze/template/haml.rb +2 -1
  86. metadata +21 -7
  87. data/examples/todolist/public/404.jpg +0 -0
  88. data/examples/todolist/public/error.xhtml +0 -74
  89. 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
@@ -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
- %w[Main Base Index].include?(name) ? '/' : "/#{name.snake_case}"
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
- def public_root path = nil
90
- if path
91
- message = "#{self}.public_root is #{path} which does not exist"
92
- check_path(path, message)
93
- @public_root = path
94
- else
95
- @public_root
96
- end
97
- end
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
- Thread.current[:controller]
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
- controller, action = *resolve(path)
110
- controller.render(action)
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
- #Inform.debug("resolve_controller('#{path}')")
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 controller, action if valid_action
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
- hash = {:method => method, :params => params, :template => template}
56
- Action.fill(hash)
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
- first_path =
72
- if template_root = @template_root
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 = Controller.trait[:template_extensions]
132
+ t_extensions = Template::ENGINES
132
133
  engine = trait[:engine]
133
- c_extensions = t_extensions.reject{|k,v| v != engine}.keys
134
- all_extensions = t_extensions.keys
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
@@ -14,21 +14,9 @@ require 'ramaze/dispatcher/file'
14
14
  module Ramaze
15
15
  module Dispatcher
16
16
 
17
- trait :dispatch => [
18
- Dispatcher::File,
19
- Dispatcher::Action,
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
- trait[:dispatch].each do |dispatcher|
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
- trait :filter => [
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
- filter = ancestral_trait[:filter]
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| handle_error[a]}
17
- status, path = *handle_error[key || Exception]
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
- [ (BASEDIR/'proto'/'public'),
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)
@@ -5,17 +5,17 @@ module Ramaze
5
5
 
6
6
  # The general Namespace for Ramazes Errorclasses
7
7
 
8
- module Error
8
+ class Error < StandardError
9
9
  # No action found on Controller
10
- class NoAction < StandardError; end
10
+ class NoAction < Error; end
11
11
 
12
12
  # No Controller found for request
13
- class NoController < StandardError; end
13
+ class NoController < Error; end
14
14
 
15
15
  # Wrong parameter count for action
16
- class WrongParameterCount < StandardError; end
16
+ class WrongParameterCount < Error; end
17
17
 
18
18
  # Error while transformation in template
19
- class Template < StandardError; end
19
+ class Template < Error; end
20
20
  end
21
21
  end
@@ -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
- :public_root => ( BASEDIR / 'proto' / 'public' )
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
 
@@ -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
- def before_process(action)
61
- block = ancestral_trait[:aspects][:before][action.method]
62
- before = action.controller.instance_eval(&block) if block
63
- before
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(action)
67
- block = ancestral_trait[:aspects][:after][action.method]
68
- after = action.controller.instance_eval(&block) if block
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