ramaze 0.3.5 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. data/Rakefile +5 -20
  2. data/bin/ramaze +0 -4
  3. data/doc/AUTHORS +5 -0
  4. data/doc/meta/announcement.txt +2 -1
  5. data/doc/tutorial/todolist.html +20 -21
  6. data/doc/tutorial/todolist.mkd +10 -9
  7. data/examples/blog/{src/controller.rb → controller/main.rb} +2 -0
  8. data/examples/blog/{src/model.rb → model/entry.rb} +0 -0
  9. data/examples/blog/spec/blog.rb +3 -3
  10. data/examples/blog/start.rb +2 -3
  11. data/examples/blog/view/edit.xhtml +17 -0
  12. data/examples/blog/view/index.xhtml +17 -0
  13. data/examples/blog/view/layout.xhtml +11 -0
  14. data/examples/blog/view/new.xhtml +16 -0
  15. data/examples/facebook.rb +15 -8
  16. data/examples/identity.rb +1 -1
  17. data/examples/memleak_detector.rb +1 -1
  18. data/examples/rammit/src/model.rb +1 -1
  19. data/examples/rapaste/controller/paste.rb +7 -7
  20. data/examples/rapaste/model/paste.rb +1 -3
  21. data/examples/rapaste/public/css/display.css +2 -1
  22. data/examples/rapaste/start.rb +2 -3
  23. data/examples/sourceview/sourceview.rb +1 -1
  24. data/examples/templates/template/external.tenjin +28 -0
  25. data/examples/templates/template_amrita2.rb +0 -3
  26. data/examples/templates/template_tenjin.rb +57 -0
  27. data/examples/todolist/spec/todolist.rb +13 -2
  28. data/examples/todolist/src/controller/main.rb +1 -1
  29. data/examples/todolist/template/index.xhtml +1 -1
  30. data/examples/wiktacular/spec/wiktacular.rb +18 -0
  31. data/examples/wiktacular/src/controller.rb +2 -2
  32. data/examples/wiktacular/src/model.rb +8 -2
  33. data/lib/proto/public/css/ramaze_error.css +4 -0
  34. data/lib/proto/public/dispatch.fcgi +11 -0
  35. data/lib/proto/spec/main.rb +1 -1
  36. data/lib/proto/start.ru +8 -0
  37. data/lib/proto/view/error.xhtml +2 -0
  38. data/lib/ramaze.rb +28 -5
  39. data/lib/ramaze/action.rb +9 -2
  40. data/lib/ramaze/action/render.rb +40 -24
  41. data/lib/ramaze/adapter.rb +10 -17
  42. data/lib/ramaze/adapter/base.rb +8 -12
  43. data/lib/ramaze/adapter/cgi.rb +14 -13
  44. data/lib/ramaze/adapter/ebb.rb +34 -0
  45. data/lib/ramaze/adapter/evented_mongrel.rb +1 -1
  46. data/lib/ramaze/adapter/fcgi.rb +14 -14
  47. data/lib/ramaze/adapter/lsws.rb +15 -11
  48. data/lib/ramaze/adapter/mongrel.rb +2 -1
  49. data/lib/ramaze/adapter/scgi.rb +24 -0
  50. data/lib/ramaze/adapter/swiftiplied_mongrel.rb +1 -1
  51. data/lib/ramaze/adapter/thin.rb +4 -5
  52. data/lib/ramaze/adapter/webrick.rb +5 -5
  53. data/lib/ramaze/cache.rb +1 -1
  54. data/lib/ramaze/cache/memcached.rb +1 -1
  55. data/lib/ramaze/contrib.rb +70 -10
  56. data/lib/ramaze/contrib/auto_params.rb +1 -1
  57. data/lib/ramaze/contrib/email.rb +15 -15
  58. data/lib/ramaze/contrib/facebook.rb +2 -2
  59. data/lib/ramaze/contrib/facebook/facebook.rb +7 -4
  60. data/lib/ramaze/contrib/file_cache.rb +65 -0
  61. data/lib/ramaze/contrib/gettext.rb +56 -55
  62. data/lib/ramaze/contrib/profiling.rb +36 -0
  63. data/lib/ramaze/contrib/sequel_cache.rb +92 -0
  64. data/lib/ramaze/controller.rb +80 -47
  65. data/lib/ramaze/controller/error.rb +10 -5
  66. data/lib/ramaze/controller/resolve.rb +36 -48
  67. data/lib/ramaze/current.rb +70 -0
  68. data/lib/ramaze/{trinity → current}/request.rb +62 -15
  69. data/lib/ramaze/current/response.rb +19 -0
  70. data/lib/ramaze/{trinity → current}/session.rb +32 -110
  71. data/lib/ramaze/current/session/flash.rb +67 -0
  72. data/lib/ramaze/current/session/hash.rb +65 -0
  73. data/lib/ramaze/dispatcher.rb +1 -28
  74. data/lib/ramaze/dispatcher/action.rb +6 -3
  75. data/lib/ramaze/dispatcher/directory.rb +1 -1
  76. data/lib/ramaze/dispatcher/error.rb +26 -5
  77. data/lib/ramaze/dispatcher/file.rb +13 -2
  78. data/lib/ramaze/gestalt.rb +3 -1
  79. data/lib/ramaze/global.rb +6 -3
  80. data/lib/ramaze/global/globalstruct.rb +3 -1
  81. data/lib/ramaze/helper.rb +66 -20
  82. data/lib/ramaze/helper/aspect.rb +25 -17
  83. data/lib/ramaze/helper/auth.rb +4 -3
  84. data/lib/ramaze/helper/cache.rb +5 -4
  85. data/lib/ramaze/helper/cgi.rb +11 -9
  86. data/lib/ramaze/helper/flash.rb +28 -3
  87. data/lib/ramaze/helper/formatting.rb +1 -3
  88. data/lib/ramaze/helper/identity.rb +2 -3
  89. data/lib/ramaze/helper/inform.rb +7 -6
  90. data/lib/ramaze/helper/link.rb +15 -17
  91. data/lib/ramaze/helper/markaby.rb +2 -4
  92. data/lib/ramaze/helper/maruku.rb +1 -1
  93. data/lib/ramaze/helper/nitroform.rb +4 -4
  94. data/lib/ramaze/helper/pager.rb +4 -6
  95. data/lib/ramaze/helper/partial.rb +24 -21
  96. data/lib/ramaze/helper/redirect.rb +8 -5
  97. data/lib/ramaze/helper/{file.rb → sendfile.rb} +1 -3
  98. data/lib/ramaze/helper/sequel.rb +1 -3
  99. data/lib/ramaze/helper/stack.rb +1 -3
  100. data/lib/ramaze/helper/tagz.rb +19 -0
  101. data/lib/ramaze/helper/user.rb +63 -0
  102. data/lib/ramaze/inform.rb +2 -24
  103. data/lib/ramaze/log.rb +28 -0
  104. data/lib/ramaze/{inform → log}/analogger.rb +3 -3
  105. data/lib/ramaze/{inform → log}/growl.rb +2 -2
  106. data/lib/ramaze/{inform → log}/hub.rb +4 -6
  107. data/lib/ramaze/{inform → log}/informer.rb +4 -4
  108. data/lib/ramaze/{inform → log}/knotify.rb +2 -2
  109. data/lib/ramaze/log/logger.rb +22 -0
  110. data/lib/ramaze/{inform/informing.rb → log/logging.rb} +16 -16
  111. data/lib/ramaze/{inform → log}/syslog.rb +0 -0
  112. data/lib/ramaze/{inform → log}/xosd.rb +2 -2
  113. data/lib/ramaze/route.rb +64 -36
  114. data/lib/ramaze/snippets/array/put_within.rb +13 -0
  115. data/lib/ramaze/snippets/binding/locals.rb +13 -0
  116. data/lib/ramaze/snippets/kernel/__dir__.rb +10 -8
  117. data/lib/ramaze/snippets/kernel/aquire.rb +1 -1
  118. data/lib/ramaze/snippets/kernel/constant.rb +1 -1
  119. data/lib/ramaze/snippets/object/pretty.rb +6 -0
  120. data/lib/ramaze/snippets/object/scope.rb +11 -0
  121. data/lib/ramaze/snippets/object/thread_accessor.rb +5 -0
  122. data/lib/ramaze/snippets/ordered_set.rb +1 -1
  123. data/lib/ramaze/snippets/proc/locals.rb +11 -0
  124. data/lib/ramaze/snippets/ramaze/thread_accessor.rb +44 -0
  125. data/lib/ramaze/snippets/string/esc.rb +29 -0
  126. data/lib/ramaze/snippets/string/start_with.rb +7 -0
  127. data/lib/ramaze/snippets/string/unindent.rb +6 -1
  128. data/lib/ramaze/snippets/struct/values_at.rb +1 -5
  129. data/lib/ramaze/sourcereload.rb +16 -14
  130. data/lib/ramaze/spec.rb +1 -0
  131. data/lib/ramaze/spec/helper.rb +11 -3
  132. data/lib/ramaze/spec/helper/browser.rb +25 -1
  133. data/lib/ramaze/spec/helper/pretty_output.rb +11 -11
  134. data/lib/ramaze/template.rb +5 -4
  135. data/lib/ramaze/template/amrita2.rb +2 -3
  136. data/lib/ramaze/template/ezamar/element.rb +2 -3
  137. data/lib/ramaze/template/ezamar/morpher.rb +1 -2
  138. data/lib/ramaze/template/ezamar/render_partial.rb +1 -1
  139. data/lib/ramaze/template/haml.rb +5 -2
  140. data/lib/ramaze/template/markaby.rb +2 -0
  141. data/lib/ramaze/template/tagz.rb +79 -0
  142. data/lib/ramaze/template/tenjin.rb +34 -0
  143. data/lib/ramaze/tool/create.rb +0 -3
  144. data/lib/ramaze/tool/localize.rb +107 -105
  145. data/lib/ramaze/tool/mime.rb +0 -2
  146. data/lib/ramaze/trinity.rb +1 -26
  147. data/lib/ramaze/version.rb +1 -1
  148. data/lib/vendor/bacon.rb +47 -41
  149. data/rake_tasks/conf.rake +18 -0
  150. data/rake_tasks/darcs.rake +5 -0
  151. data/rake_tasks/maintenance.rake +37 -24
  152. data/rake_tasks/spec.rake +1 -1
  153. data/spec/contrib/auto_params.rb +3 -1
  154. data/spec/contrib/profiling.rb +26 -0
  155. data/spec/examples/templates/template_redcloth.rb +1 -1
  156. data/spec/examples/templates/template_tenjin.rb +28 -0
  157. data/spec/helper.rb +0 -1
  158. data/spec/ramaze/action/layout.rb +28 -0
  159. data/spec/ramaze/controller/actionless_templates.rb +32 -0
  160. data/spec/ramaze/controller/template/other_wrapper.xhtml +1 -0
  161. data/spec/ramaze/controller/template_resolving.rb +37 -0
  162. data/spec/ramaze/{trinity → current}/request.rb +12 -2
  163. data/spec/ramaze/current/session.rb +97 -0
  164. data/spec/ramaze/dispatcher/directory.rb +2 -1
  165. data/spec/ramaze/dispatcher/file.rb +8 -3
  166. data/spec/ramaze/dispatcher/public/file name.txt +1 -0
  167. data/spec/ramaze/gestalt.rb +11 -0
  168. data/spec/ramaze/helper/aspect.rb +28 -22
  169. data/spec/ramaze/helper/cgi.rb +2 -2
  170. data/spec/ramaze/helper/flash.rb +33 -15
  171. data/spec/ramaze/helper/formatting.rb +2 -2
  172. data/spec/ramaze/helper/link.rb +46 -18
  173. data/spec/ramaze/helper/pager.rb +8 -5
  174. data/spec/ramaze/helper/partial.rb +8 -1
  175. data/spec/ramaze/helper/template/recursive_local_ivars.xhtml +7 -0
  176. data/spec/ramaze/helper/user.rb +46 -0
  177. data/spec/ramaze/{inform → log}/informer.rb +0 -0
  178. data/spec/ramaze/{inform → log}/syslog.rb +1 -1
  179. data/spec/ramaze/request.rb +14 -10
  180. data/spec/ramaze/route.rb +23 -0
  181. data/spec/ramaze/template.rb +48 -1
  182. data/spec/ramaze/template/haml.rb +6 -16
  183. data/spec/ramaze/template/haml/locals.haml +2 -1
  184. data/spec/ramaze/template/tagz.rb +62 -0
  185. data/spec/ramaze/template/tagz/external.tagz +8 -0
  186. data/spec/ramaze/template/tagz/sum.tagz +1 -0
  187. data/spec/ramaze/template/tenjin.rb +49 -0
  188. data/spec/ramaze/template/tenjin/external.tenjin +1 -0
  189. data/spec/snippets/string/unindent.rb +15 -0
  190. metadata +509 -475
  191. data/doc/README.html +0 -729
  192. data/doc/changes.txt +0 -5757
  193. data/doc/changes.xml +0 -5759
  194. data/examples/blog/src/view.rb +0 -16
  195. data/examples/blog/template/edit.xhtml +0 -19
  196. data/examples/blog/template/index.xhtml +0 -19
  197. data/examples/blog/template/new.xhtml +0 -18
  198. data/examples/wiktacular/mkd/newpagename/current.mkd +0 -1
  199. data/examples/wiktacular/mkd/newpagename/current.mkd.bak +0 -1
  200. data/lib/ramaze/contrib/email.rb-darcs-backup0 +0 -81
  201. data/lib/ramaze/template/bijou.rb +0 -39
  202. data/lib/ramaze/trinity/response.rb +0 -32
  203. data/spec/ramaze/template/bijou.rb +0 -25
  204. data/spec/ramaze/trinity/session.rb +0 -29
@@ -0,0 +1,65 @@
1
+ module Ramaze
2
+ class Session
3
+
4
+ # The Session::Hash acts as the wrapper for a simple Hash
5
+ #
6
+ # Its purpose is to notify the underlying cache, in which the sessions
7
+ # are stored, about updates.
8
+ class Hash
9
+
10
+ # Sets @hash to an empty Hash
11
+
12
+ def initialize
13
+ @hash = {}
14
+ end
15
+
16
+ # relays all the methods to the @hash and updates the session_cache in
17
+ # Session.current.sessions if anything changes.
18
+
19
+ def method_missing(*args, &block)
20
+ old = @hash.dup
21
+ result = @hash.send(*args, &block)
22
+ unless old == @hash
23
+ Cache.sessions[Current.session.session_id] = self
24
+ end
25
+ result
26
+ end
27
+
28
+ # Calls #inspect on the wrapped @hash
29
+
30
+ def inspect
31
+ @hash.inspect
32
+ end
33
+
34
+ # Use client side session variables
35
+
36
+ def client
37
+ Request.current['session.client'] ||= unmarshal(Request.current.cookies["#{Session::SESSION_KEY}-client"]) || {}
38
+ end
39
+
40
+ private
41
+
42
+ # Marshal a session hash into safe cookie data. Include an integrity hash.
43
+ def marshal(session)
44
+ data = [ Marshal.dump(session) ].pack('m').chop
45
+ "#{data}--#{generate_digest(data)}"
46
+ end
47
+
48
+ # Unmarshal cookie data to a hash and verify its integrity.
49
+ def unmarshal(cookie)
50
+ if cookie
51
+ data, digest = cookie.split('--')
52
+ return nil unless digest == generate_digest(data)
53
+ Marshal.load(data.unpack('m').first)
54
+ end
55
+ end
56
+
57
+ # Generate the inline SHA512 message digest. Larger (128 bytes) than SHA256
58
+ # (64 bytes) or RMD160 (40 bytes), but small relative to the 4096 byte
59
+ # max cookie size.
60
+ def generate_digest(data)
61
+ Digest::SHA512.hexdigest "#{data}#{Session.trait[:secret]}"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,10 +1,7 @@
1
1
  # Copyright (c) 2008 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 'timeout'
5
-
6
4
  require 'ramaze/error'
7
- require 'ramaze/adapter'
8
5
  require 'ramaze/tool/mime'
9
6
 
10
7
  require 'ramaze/dispatcher/action'
@@ -31,9 +28,7 @@ module Ramaze
31
28
  # Entry point for Adapter#respond, takes a Rack::Request and
32
29
  # Rack::Response, sets up the environment and the goes on to dispatch
33
30
  # for the given path from rack_request.
34
- def handle rack_request, rack_response
35
- setup_environment(rack_request, rack_response)
36
-
31
+ def handle
37
32
  path = request.path_info.squeeze('/')
38
33
 
39
34
  case path
@@ -124,28 +119,6 @@ module Ramaze
124
119
  }
125
120
  Dispatcher::Error.process(result, meta)
126
121
  end
127
-
128
- # finalizes the session and assigns the key to the response via
129
- # set_cookie.
130
-
131
- def set_cookie
132
- session.finalize
133
- hash = {:value => session.session_id}.merge(Session::COOKIE)
134
- response.set_cookie(Session::SESSION_KEY, hash)
135
- end
136
-
137
- # Setup the Trinity (Request, Response, Session) and store them as
138
- # thread-variables in Thread.current
139
- # Thread.current[:request] == Request.current
140
- # Thread.current[:response] == Response.current
141
- # Thread.current[:session] == Session.current
142
-
143
- def setup_environment rack_request, rack_response
144
- this = Thread.current
145
- this[:request] = rack_request
146
- this[:session] = Session.new(request) if Global.sessions
147
- this[:response] = rack_response
148
- end
149
122
  end
150
123
  end
151
124
  end
@@ -23,9 +23,12 @@ module Ramaze
23
23
  # post-processing.
24
24
 
25
25
  def process(path)
26
- Inform.info("Dynamic request from #{request.ip}: #{request.request_uri}")
27
- body = Controller.handle(path)
28
- response = Response.current.build(body)
26
+ Log.info("Dynamic request from #{request.ip}: #{request.request_uri}")
27
+
28
+ catch(:respond) {
29
+ body = Controller.handle(path)
30
+ response = Response.current.build(body)
31
+ }
29
32
  FILTER.inject(response){|r,f| f.call(r) }
30
33
  rescue Ramaze::Error => ex
31
34
  ex
@@ -26,7 +26,7 @@ module Ramaze
26
26
  dir = ::File.expand_path(Global.public_root/::File.expand_path(path, '/'))
27
27
 
28
28
  if ::File.directory?(dir)
29
- Inform.debug("Serving directory listing: #{dir}")
29
+ Log.debug("Serving directory listing: #{dir}")
30
30
 
31
31
  status = Ramaze::STATUS_CODE['OK']
32
32
  header = {'Content-Type' => "text/html"}
@@ -44,7 +44,7 @@ module Ramaze
44
44
  action_response = Dispatcher::Action.process(newpath)
45
45
  case action_response
46
46
  when Ramaze::Error
47
- Inform.debug("No custom error page found on #{controller}, going to #{path}")
47
+ Log.debug("No custom error page found on #{controller}, going to #{path}")
48
48
  else
49
49
  action_response.status = status
50
50
  return action_response
@@ -58,8 +58,29 @@ module Ramaze
58
58
  response.build(error.message, status)
59
59
  end
60
60
  rescue Object => ex
61
- Inform.error(ex)
62
- response.build(ex.message, status)
61
+ Log.error(ex)
62
+ begin
63
+ m = ex.message
64
+ c = ex.class
65
+ b = (ex.backtrace || []).join("\n")
66
+ body = <<-html
67
+ ==== Error ====\n
68
+ #{ m } (#{ c })
69
+ #{ b }\n
70
+ ==== Request ====\n
71
+ #{ Request.current.pretty }\n
72
+ ==== Request ====\n
73
+ #{ Response.current.pretty }\n
74
+ ==== Session ====\n
75
+ #{ Session.current.pretty }\n
76
+ ==== Global ====\n
77
+ #{ Global.pretty }\n
78
+ html
79
+ response['Content-Type'] = 'text/plain'
80
+ response.build(body.unindent, status)
81
+ rescue Object
82
+ raise
83
+ end
63
84
  end
64
85
 
65
86
  # Only logs new errors with full backtrace, repeated errors are shown
@@ -68,10 +89,10 @@ module Ramaze
68
89
  error_message = error.message
69
90
 
70
91
  if trait[:last_error] == error_message or error.is_a? Ramaze::Error::NoAction
71
- Inform.error(error_message)
92
+ Log.error(error_message)
72
93
  else
73
94
  trait[:last_error] = error_message
74
- Inform.error(error)
95
+ Log.error(error)
75
96
  end
76
97
  end
77
98
 
@@ -22,7 +22,7 @@ module Ramaze
22
22
  # searches for the file and builds a response with status 200 if found.
23
23
 
24
24
  def process(path)
25
- return unless file = open_file(path)
25
+ return unless file = open_file(CGI.unescape(path))
26
26
  if file == :NotModified
27
27
  return response.build([], STATUS_CODE['Not Modified'])
28
28
  end
@@ -36,6 +36,7 @@ module Ramaze
36
36
  file = resolve_path(path)
37
37
 
38
38
  if ::File.file?(file) or ::File.file?(file=file/'index')
39
+ return unless in_public?(file)
39
40
  response['Content-Type'] = Tool::MIME.type_for(file) unless ::File.extname(file).empty?
40
41
  mtime = ::File.mtime(file)
41
42
  response['Last-Modified'] = mtime.httpdate
@@ -63,11 +64,21 @@ module Ramaze
63
64
  end
64
65
  end
65
66
 
67
+ def in_public?(path)
68
+ expand(path).start_with?(expand(Global.public_root))
69
+ end
70
+
71
+ private
72
+
73
+ def expand(path)
74
+ ::File.expand_path(path)
75
+ end
76
+
66
77
  def log(file)
67
78
  case file
68
79
  when *Global.boring
69
80
  else
70
- Inform.debug("Serving static: #{file}")
81
+ Log.debug("Serving static: #{file}")
71
82
  end
72
83
  end
73
84
  end
@@ -117,7 +117,9 @@ module Ramaze
117
117
  gsub(/>/, '&gt;')
118
118
  end
119
119
 
120
- # @out.to_s
120
+ def tag(name, *args, &block)
121
+ _gestalt_call_tag(name.to_s, args, &block)
122
+ end
121
123
 
122
124
  def to_s
123
125
  @out.to_s
@@ -1,9 +1,6 @@
1
1
  # Copyright (c) 2008 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 'ostruct'
5
- require 'set'
6
-
7
4
  require 'ramaze/global/dsl'
8
5
 
9
6
  module Ramaze
@@ -70,6 +67,9 @@ module Ramaze
70
67
  o "All paths to controllers are mapped here.",
71
68
  :mapping => {}
72
69
 
70
+ o "For your own modes to decide on",
71
+ :mode => :live, :cli => [:live, :dev]
72
+
73
73
  o "The place ramaze was started from, useful mostly for debugging",
74
74
  :origin => :main
75
75
 
@@ -108,6 +108,9 @@ module Ramaze
108
108
 
109
109
  o "Enable directory listing",
110
110
  :list_directories => false, :cli => false
111
+
112
+ o "Disable templates without actions",
113
+ :actionless_templates => true, :cli => true
111
114
  end
112
115
 
113
116
  require 'ramaze/global/globalstruct'
@@ -19,7 +19,9 @@ module Ramaze
19
19
  ADAPTER_ALIAS = {
20
20
  :cgi => :Cgi,
21
21
  :fcgi => :Fcgi,
22
+ :scgi => :Scgi,
22
23
  :thin => :Thin,
24
+ :ebb => :Ebb,
23
25
  :lsws => :Lsws,
24
26
  :webrick => :WEBrick,
25
27
  :mongrel => :Mongrel,
@@ -134,7 +136,7 @@ module Ramaze
134
136
 
135
137
  # Creates a new attr_accessor like method-pair.
136
138
  def create_member key, value = nil
137
- Inform.warn "Create #{key}=#{value.inspect} on Global"
139
+ Log.warn "Create #{key}=#{value.inspect} on Global"
138
140
 
139
141
  @table ||= {}
140
142
  key = key.to_sym
@@ -10,28 +10,74 @@ module Ramaze
10
10
  # and also a helper method, look below for more information about it
11
11
 
12
12
  module Helper
13
- include Trinity
14
-
15
- private
16
-
17
- # This loads the helper-files from /ramaze/helper/helpername.rb and
18
- # includes it into Ramaze::Template (or wherever it is called)
19
- #
20
- # Usage:
21
- # helper :redirect, :link
22
-
23
- def helper *syms
24
- syms.each do |sym|
25
- mod_name = sym.to_s.capitalize + 'Helper'
26
- begin
27
- include ::Ramaze.const_get(mod_name)
28
- extend ::Ramaze.const_get(mod_name)
29
- rescue NameError
30
- files = Dir["{helper,#{BASEDIR/:ramaze/:helper}}/#{sym}.{rb,so}"]
31
- raise LoadError, "#{mod_name} not found" unless files.any?
32
- require(files.first) ? retry : raise
13
+ LOOKUP = Set.new
14
+ trait :ignore => [
15
+ /#{Regexp.escape(File.expand_path(BASEDIR/'../spec/ramaze/helper/'))}\//
16
+ ]
17
+
18
+ module Methods
19
+ private
20
+
21
+ # This loads the helper-files from /ramaze/helper/helpername.rb and
22
+ # includes it into Ramaze::Template (or wherever it is called)
23
+ #
24
+ # Usage:
25
+ # helper :redirect, :link
26
+
27
+ def helper(*syms)
28
+ syms.each do |sym|
29
+ name = sym.to_s
30
+ if mod = find_helper(name)
31
+ use_helper(mod)
32
+ else
33
+ if require_helper(name)
34
+ redo
35
+ else
36
+ raise LoadError, "#{name} not found"
37
+ end
38
+ end
33
39
  end
34
40
  end
41
+
42
+ # Will be going to be much simpler after deprecation *sigh*
43
+ def find_helper(name)
44
+ ramaze_helper_consts = ::Ramaze::Helper.constants.grep(/^#{name}$/i)
45
+ ramaze_consts = ::Ramaze.constants.grep(/^#{name}Helper$/i)
46
+ if mod_name = ramaze_helper_consts.first
47
+ ::Ramaze::Helper.const_get(mod_name)
48
+ elsif mod_name = ramaze_consts.first
49
+ mod = ::Ramaze.const_get(mod_name)
50
+ new_name = "Ramaze::Helper::" << mod_name.split('::').last[/^(.*)Helper$/, 1]
51
+ Log.warn "#{mod_name} is being deprecated, use #{new_name} instead"
52
+ mod
53
+ end
54
+ end
55
+
56
+ def require_helper(name)
57
+ glob = "{,#{APPDIR},#{BASEDIR/:ramaze}}/helper/#{name}.{so,bundle,rb}"
58
+ files = Dir[glob]
59
+ ignore = Helper.trait[:ignore]
60
+ files.reject!{|f| ignore.any?{|i| f =~ i }}
61
+ raise LoadError, "#{name} not found" unless file = files.first
62
+ require(file)
63
+ end
64
+
65
+ def use_helper(mod)
66
+ include mod
67
+ extend mod
68
+ end
69
+
70
+ def Methods.included other
71
+ other.send :extend, Trinity
72
+ other.send :include, Trinity
73
+ other.send :extend, Methods
74
+ super
75
+ end
76
+
77
+ def Methods.extend_object other
78
+ other.send :extend, Trinity
79
+ super
80
+ end
35
81
  end
36
82
  end
37
83
  end
@@ -16,56 +16,64 @@ module Ramaze
16
16
  #
17
17
  # helper :aspect
18
18
 
19
- module AspectHelper
19
+ module Helper::Aspect
20
20
 
21
- # Define traits on class this module is included into.
21
+ private
22
22
 
23
- def self.included(klass)
24
- klass.trait[:aspects] ||= { :before => {}, :after => {} }
23
+ # lazily and smartly inherit copy of aspects trait from parent, or
24
+ # bootstrap our own
25
+ def aspects
26
+ trait[:aspects] ||= (
27
+ if hash = ancestral_trait[:aspects]
28
+ { :before => hash[:before].dup, :after => hash[:after].dup }
29
+ else
30
+ { :before => {}, :after => {} }
31
+ end
32
+ )
25
33
  end
26
34
 
27
- private
28
-
29
- # run block before given actions.
35
+ # run block before given actions or, if no actions specified, all actions.
30
36
  def before(*meths, &block)
31
- aspects = trait[:aspects][:before]
37
+ return before_all(*meths, &block) if meths.empty?
32
38
  meths.each do |meth|
33
- aspects[meth.to_s] = block
39
+ aspects[:before][meth.to_s] = block
34
40
  end
35
41
  end
36
42
  alias pre before
37
43
 
38
44
  # Run block before all actions.
39
45
  def before_all(&block)
40
- trait[:aspects][:before][:all] = block
46
+ aspects[:before][:all] = block
41
47
  end
42
48
  alias pre_all before_all
43
49
 
44
- # run block after given actions.
50
+ # run block after given actions or, if no actions specified, all actions.
45
51
  def after(*meths, &block)
46
- aspects = trait[:aspects][:after]
52
+ return after_all(*meths, &block) if meths.empty?
47
53
  meths.each do |meth|
48
- aspects[meth.to_s] = block
54
+ aspects[:after][meth.to_s] = block
49
55
  end
50
56
  end
51
57
  alias post after
52
58
 
53
59
  # Run block after all actions.
54
60
  def after_all(&block)
55
- trait[:aspects][:after][:all] = block
61
+ aspects[:after][:all] = block
56
62
  end
57
63
  alias post_all after_all
58
64
 
59
- # run block before and after given actions.
65
+ # run block before and after given actions, or, if no actions specified.
66
+ # all actions
60
67
  def wrap(*meths, &block)
68
+ return wrap_all(*meths, &block) if meths.empty?
61
69
  before(*meths, &block)
62
70
  after(*meths, &block)
63
71
  end
64
72
 
65
73
  # run block before and after all actions.
66
74
  def wrap_all(&block)
67
- trait[:aspects][:before][:all] = block
68
- trait[:aspects][:after][:all] = block
75
+ aspects[:before][:all] = block
76
+ aspects[:after][:all] = block
69
77
  end
70
78
  end
71
79