ramaze 0.3.5 → 0.3.9

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 (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