merb 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. data/README +25 -26
  2. data/Rakefile +48 -36
  3. data/app_generators/merb/USAGE +5 -0
  4. data/app_generators/merb/merb_generator.rb +107 -0
  5. data/app_generators/merb/templates/Rakefile +99 -0
  6. data/{examples/skeleton/dist → app_generators/merb/templates}/app/controllers/application.rb +1 -1
  7. data/app_generators/merb/templates/app/controllers/exceptions.rb +13 -0
  8. data/{examples/skeleton/dist → app_generators/merb/templates}/app/helpers/global_helper.rb +0 -0
  9. data/{examples/skeleton/dist/app/mailers → app_generators/merb/templates/app/mailers/views}/layout/application.erb +0 -0
  10. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +207 -0
  11. data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +38 -0
  12. data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +40 -0
  13. data/app_generators/merb/templates/app/views/layout/application.html.erb +11 -0
  14. data/app_generators/merb/templates/config/boot.rb +11 -0
  15. data/app_generators/merb/templates/config/dependencies.rb +41 -0
  16. data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/development.rb +0 -0
  17. data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/production.rb +0 -0
  18. data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/test.rb +0 -0
  19. data/app_generators/merb/templates/config/merb.yml +64 -0
  20. data/app_generators/merb/templates/config/merb_init.rb +16 -0
  21. data/app_generators/merb/templates/config/plugins.yml +1 -0
  22. data/app_generators/merb/templates/config/router.rb +32 -0
  23. data/{lib/merb/core_ext/merb_array.rb → app_generators/merb/templates/config/upload.conf} +0 -0
  24. data/app_generators/merb/templates/public/images/merb.jpg +0 -0
  25. data/app_generators/merb/templates/public/merb.fcgi +6 -0
  26. data/app_generators/merb/templates/public/stylesheets/master.css +119 -0
  27. data/app_generators/merb/templates/script/destroy +28 -0
  28. data/app_generators/merb/templates/script/generate +28 -0
  29. data/{examples/skeleton → app_generators/merb/templates}/script/stop_merb +0 -0
  30. data/app_generators/merb/templates/script/win_script.cmd +1 -0
  31. data/app_generators/merb/templates/spec/spec.opts +6 -0
  32. data/app_generators/merb/templates/spec/spec_helper.rb +10 -0
  33. data/app_generators/merb/templates/test/test_helper.rb +13 -0
  34. data/app_generators/merb_plugin/USAGE +5 -0
  35. data/app_generators/merb_plugin/merb_plugin_generator.rb +64 -0
  36. data/app_generators/merb_plugin/templates/LICENSE +20 -0
  37. data/app_generators/merb_plugin/templates/README +4 -0
  38. data/app_generators/merb_plugin/templates/Rakefile +35 -0
  39. data/app_generators/merb_plugin/templates/TODO +5 -0
  40. data/app_generators/merb_plugin/templates/merbtasks.rb +6 -0
  41. data/app_generators/merb_plugin/templates/sampleplugin.rb +10 -0
  42. data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +7 -0
  43. data/app_generators/merb_plugin/templates/spec_helper.rb +2 -0
  44. data/bin/merb +1 -1
  45. data/lib/autotest/discover.rb +3 -0
  46. data/lib/autotest/merb_rspec.rb +79 -0
  47. data/lib/merb.rb +72 -93
  48. data/lib/merb/{merb_abstract_controller.rb → abstract_controller.rb} +28 -5
  49. data/lib/merb/caching/action_cache.rb +65 -29
  50. data/lib/merb/caching/fragment_cache.rb +9 -4
  51. data/lib/merb/caching/store/file_cache.rb +22 -14
  52. data/lib/merb/caching/store/memory_cache.rb +26 -8
  53. data/lib/merb/{merb_constants.rb → constants.rb} +9 -7
  54. data/lib/merb/controller.rb +178 -0
  55. data/lib/merb/core_ext.rb +13 -11
  56. data/lib/merb/core_ext/array.rb +0 -0
  57. data/lib/merb/core_ext/{merb_class.rb → class.rb} +0 -0
  58. data/lib/merb/core_ext/{merb_enumerable.rb → enumerable.rb} +0 -0
  59. data/lib/merb/core_ext/get_args.rb +52 -0
  60. data/lib/merb/core_ext/{merb_hash.rb → hash.rb} +40 -11
  61. data/lib/merb/core_ext/{merb_inflections.rb → inflections.rb} +0 -0
  62. data/lib/merb/core_ext/{merb_inflector.rb → inflector.rb} +1 -1
  63. data/lib/merb/core_ext/{merb_kernel.rb → kernel.rb} +56 -3
  64. data/lib/merb/core_ext/mash.rb +88 -0
  65. data/lib/merb/core_ext/{merb_module.rb → module.rb} +0 -0
  66. data/lib/merb/core_ext/{merb_numeric.rb → numeric.rb} +0 -0
  67. data/lib/merb/core_ext/{merb_object.rb → object.rb} +10 -47
  68. data/lib/merb/core_ext/string.rb +56 -0
  69. data/lib/merb/core_ext/{merb_symbol.rb → symbol.rb} +0 -0
  70. data/lib/merb/dispatcher.rb +109 -0
  71. data/lib/merb/{merb_drb_server.rb → drb_server.rb} +0 -0
  72. data/lib/merb/erubis_ext.rb +10 -0
  73. data/lib/merb/exceptions.rb +173 -0
  74. data/lib/merb/generators/merb_app/merb_app.rb +5 -25
  75. data/lib/merb/generators/merb_generator_helpers.rb +317 -0
  76. data/lib/merb/generators/merb_plugin.rb +19 -0
  77. data/lib/merb/logger.rb +65 -0
  78. data/lib/merb/{merb_mail_controller.rb → mail_controller.rb} +102 -49
  79. data/lib/merb/{merb_mailer.rb → mailer.rb} +31 -27
  80. data/lib/merb/mixins/{basic_authentication_mixin.rb → basic_authentication.rb} +3 -3
  81. data/lib/merb/mixins/{controller_mixin.rb → controller.rb} +131 -112
  82. data/lib/merb/mixins/{erubis_capture_mixin.rb → erubis_capture.rb} +12 -21
  83. data/lib/merb/mixins/{form_control_mixin.rb → form_control.rb} +6 -12
  84. data/lib/merb/mixins/render.rb +401 -0
  85. data/lib/merb/mixins/responder.rb +378 -0
  86. data/lib/merb/mixins/{view_context_mixin.rb → view_context.rb} +65 -10
  87. data/lib/merb/mixins/web_controller.rb +29 -0
  88. data/lib/merb/{merb_handler.rb → mongrel_handler.rb} +59 -38
  89. data/lib/merb/part_controller.rb +19 -0
  90. data/lib/merb/plugins.rb +16 -0
  91. data/lib/merb/rack_adapter.rb +37 -0
  92. data/lib/merb/request.rb +421 -0
  93. data/lib/merb/router.rb +576 -0
  94. data/lib/merb/{merb_server.rb → server.rb} +275 -71
  95. data/lib/merb/session.rb +10 -10
  96. data/lib/merb/session/cookie_store.rb +125 -0
  97. data/lib/merb/session/{merb_mem_cache_session.rb → mem_cache_session.rb} +22 -9
  98. data/lib/merb/session/{merb_memory_session.rb → memory_session.rb} +15 -11
  99. data/lib/merb/template.rb +35 -8
  100. data/lib/merb/template/erubis.rb +16 -10
  101. data/lib/merb/template/haml.rb +33 -20
  102. data/lib/merb/template/markaby.rb +16 -14
  103. data/lib/merb/template/xml_builder.rb +8 -4
  104. data/lib/merb/test/{merb_fake_request.rb → fake_request.rb} +11 -5
  105. data/lib/merb/test/helper.rb +31 -0
  106. data/lib/merb/test/hpricot.rb +136 -0
  107. data/lib/merb/test/{merb_multipart.rb → multipart.rb} +1 -1
  108. data/lib/merb/test/rspec.rb +93 -0
  109. data/lib/merb/{merb_upload_handler.rb → upload_handler.rb} +5 -6
  110. data/lib/merb/{merb_upload_progress.rb → upload_progress.rb} +1 -1
  111. data/lib/merb/{merb_view_context.rb → view_context.rb} +27 -42
  112. data/lib/{merb_tasks.rb → tasks.rb} +0 -0
  113. data/lib/tasks/merb.rake +21 -11
  114. data/merb_default_generators/model/USAGE +0 -0
  115. data/merb_default_generators/model/model_generator.rb +16 -0
  116. data/merb_default_generators/model/templates/new_model_template.erb +5 -0
  117. data/merb_default_generators/resource_controller/USAGE +0 -0
  118. data/merb_default_generators/resource_controller/resource_controller_generator.rb +26 -0
  119. data/merb_default_generators/resource_controller/templates/controller.rb +30 -0
  120. data/merb_default_generators/resource_controller/templates/edit.html.erb +1 -0
  121. data/merb_default_generators/resource_controller/templates/helper.rb +5 -0
  122. data/merb_default_generators/resource_controller/templates/index.html.erb +1 -0
  123. data/merb_default_generators/resource_controller/templates/new.html.erb +1 -0
  124. data/merb_default_generators/resource_controller/templates/show.html.erb +1 -0
  125. data/merb_generators/controller/USAGE +5 -0
  126. data/merb_generators/controller/controller_generator.rb +16 -0
  127. data/merb_generators/controller/templates/controller.rb +8 -0
  128. data/merb_generators/controller/templates/helper.rb +5 -0
  129. data/merb_generators/controller/templates/index.html.erb +3 -0
  130. data/merb_generators/resource/USAGE +0 -0
  131. data/merb_generators/resource/resource_generator.rb +60 -0
  132. data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +67 -0
  133. data/rspec_generators/merb_controller_test/templates/controller_spec.rb +8 -0
  134. data/rspec_generators/merb_controller_test/templates/edit_spec.rb +12 -0
  135. data/rspec_generators/merb_controller_test/templates/helper_spec.rb +5 -0
  136. data/rspec_generators/merb_controller_test/templates/index_spec.rb +12 -0
  137. data/rspec_generators/merb_controller_test/templates/new_spec.rb +12 -0
  138. data/rspec_generators/merb_controller_test/templates/show_spec.rb +5 -0
  139. data/rspec_generators/merb_model_test/merb_model_test_generator.rb +26 -0
  140. data/rspec_generators/merb_model_test/templates/model_spec_template.erb +7 -0
  141. data/script/destroy +14 -0
  142. data/script/generate +14 -0
  143. data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +53 -0
  144. data/test_unit_generators/merb_controller_test/templates/functional_test.rb +17 -0
  145. data/test_unit_generators/merb_controller_test/templates/helper_test.rb +9 -0
  146. data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +29 -0
  147. data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +9 -0
  148. metadata +172 -94
  149. data/examples/README_EXAMPLES +0 -10
  150. data/examples/skeleton/Rakefile +0 -68
  151. data/examples/skeleton/dist/app/views/layout/application.herb +0 -12
  152. data/examples/skeleton/dist/conf/database.yml +0 -23
  153. data/examples/skeleton/dist/conf/merb.yml +0 -57
  154. data/examples/skeleton/dist/conf/merb_init.rb +0 -24
  155. data/examples/skeleton/dist/conf/router.rb +0 -22
  156. data/examples/skeleton/dist/conf/upload.conf +0 -5
  157. data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +0 -14
  158. data/examples/skeleton/script/new_migration +0 -21
  159. data/lib/merb/core_ext/merb_string.rb +0 -18
  160. data/lib/merb/merb_controller.rb +0 -206
  161. data/lib/merb/merb_dispatcher.rb +0 -87
  162. data/lib/merb/merb_exceptions.rb +0 -319
  163. data/lib/merb/merb_part_controller.rb +0 -42
  164. data/lib/merb/merb_plugins.rb +0 -293
  165. data/lib/merb/merb_request.rb +0 -165
  166. data/lib/merb/merb_router.rb +0 -309
  167. data/lib/merb/merb_yaml_store.rb +0 -31
  168. data/lib/merb/mixins/render_mixin.rb +0 -283
  169. data/lib/merb/mixins/responder_mixin.rb +0 -159
  170. data/lib/merb/session/merb_ar_session.rb +0 -131
  171. data/lib/merb/vendor/paginator/README.txt +0 -84
  172. data/lib/merb/vendor/paginator/paginator.rb +0 -124
  173. data/lib/tasks/db.rake +0 -55
@@ -2,16 +2,16 @@ module Merb
2
2
  module SessionMixin
3
3
 
4
4
  def rand_uuid
5
- sid = "%04x%04x%04x%04x%04x%06x%06x" % [
6
- rand(0x0010000),
7
- rand(0x0010000),
8
- rand(0x0010000),
9
- rand(0x0010000),
10
- rand(0x0010000),
11
- rand(0x1000000),
12
- rand(0x1000000),
13
- ]
14
- sid
5
+ values = [
6
+ rand(0x0010000),
7
+ rand(0x0010000),
8
+ rand(0x0010000),
9
+ rand(0x0010000),
10
+ rand(0x0010000),
11
+ rand(0x1000000),
12
+ rand(0x1000000),
13
+ ]
14
+ "%04x%04x%04x%04x%04x%06x%06x" % values
15
15
  end
16
16
 
17
17
  def needs_new_cookie!
@@ -0,0 +1,125 @@
1
+ require 'base64' # to convert Marshal.dump to ASCII
2
+ require 'openssl' # to generate the HMAC message digest
3
+
4
+ # Most of this code is taken from bitsweat's implementation in rails
5
+
6
+ module Merb
7
+
8
+ module SessionMixin
9
+ def setup_session
10
+ MERB_LOGGER.info("Setting Cookie Store Sessions")
11
+ unless secret = Merb::Server.config[:session_secret_key]
12
+ raise 'You must set :session_secret_key in config/merb.yml for cookie sessions'
13
+ end
14
+ request.session = Merb::CookieStore.new(cookies[_session_id_key], secret)
15
+ end
16
+
17
+ def finalize_session
18
+ MERB_LOGGER.info("Finalize Cookie Store Session")
19
+ if request.session.modified?
20
+ set_cookie(_session_id_key, request.session.read_cookie, _session_expiry)
21
+ end
22
+ end
23
+
24
+ def session_store_type
25
+ "cookie"
26
+ end
27
+ end
28
+
29
+ # If you have more than 4K of session data or don't want your data to be
30
+ # visible to the user, pick another session store.
31
+ #
32
+ # CookieOverflow is raised if you attempt to store more than 4K of data.
33
+ # TamperedWithCookie is raised if the data integrity check fails.
34
+ #
35
+ # A message digest is included with the cookie to ensure data integrity:
36
+ # a user cannot alter his user_id without knowing the secret key included in
37
+ # the hash.
38
+ #
39
+ # To use Cookie Sessions, set in config/merb.yml
40
+ # :session_secret_key - your secret digest key
41
+ # :cookie_store_session - to true
42
+ class CookieStore
43
+ # TODO (maybe):
44
+ # include request ip address
45
+ # AES encrypt marshaled data
46
+
47
+ # Raised when storing more than 4K of session data.
48
+ class CookieOverflow < StandardError; end
49
+
50
+ # Raised when the cookie fails its integrity check.
51
+ class TamperedWithCookie < StandardError; end
52
+
53
+ # Cookies can typically store 4096 bytes.
54
+ MAX = 4096
55
+ DIGEST = OpenSSL::Digest::Digest.new('SHA1') # or MD5, RIPEMD160, SHA256?
56
+
57
+ attr_reader :data
58
+
59
+ def initialize(cookie, secret)
60
+ if secret.nil? or secret.blank?
61
+ raise ArgumentError, 'A secret is required to generate an integrity hash for cookie session data.'
62
+ end
63
+ @secret = secret
64
+ @data = unmarshal(cookie) || Hash.new
65
+ @modified = false
66
+ end
67
+
68
+ # return a cookie value. raises CookieOverflow if session contains too
69
+ # much information
70
+ def read_cookie
71
+ unless @data.nil? or @data.empty?
72
+ updated = marshal(@data)
73
+ raise CookieOverflow if updated.size > MAX
74
+ updated
75
+ end
76
+ end
77
+
78
+ # returns true if the session has been modified since initialization
79
+ def modified?; @modified; end
80
+
81
+ # assigns a key value pair
82
+ def []=(k, v)
83
+ unless @data[k]==v
84
+ @modified = true
85
+ @data[k] = v
86
+ end
87
+ end
88
+
89
+ def [](k)
90
+ @data[k]
91
+ end
92
+
93
+ # delete a key
94
+ def delete(key)
95
+ if @data.has_key(key)
96
+ @modified = true
97
+ @data.delete(key)
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ # Generate the HMAC keyed message digest. Uses SHA1.
104
+ def generate_digest(data)
105
+ OpenSSL::HMAC.hexdigest(DIGEST, @secret, data)
106
+ end
107
+
108
+ # Marshal a session hash into safe cookie data. Include an integrity hash.
109
+ def marshal(session)
110
+ data = Base64.encode64(Marshal.dump(session)).chop
111
+ Mongrel::HttpRequest.escape "#{data}--#{generate_digest(data)}"
112
+ end
113
+
114
+ # Unmarshal cookie data to a hash and verify its integrity.
115
+ def unmarshal(cookie)
116
+ if cookie
117
+ data, digest = Mongrel::HttpRequest.unescape(cookie).split('--')
118
+ unless digest == generate_digest(data)
119
+ raise TamperedWithCookie, "Maybe the site's session_secret_key has changed?"
120
+ end
121
+ Marshal.load(Base64.decode64(data))
122
+ end
123
+ end
124
+ end
125
+ end
@@ -6,18 +6,23 @@ module Merb
6
6
 
7
7
  def setup_session
8
8
  MERB_LOGGER.info("Setting up session")
9
- before = @_cookies[_session_id_key]
10
- @_session, @_cookies[_session_id_key] = Merb::MemCacheSession.persist(@_cookies[_session_id_key])
11
- @_fingerprint = Marshal.dump(@_session.data).hash
9
+ before = cookies[_session_id_key]
10
+ request.session, cookies[_session_id_key] = Merb::MemCacheSession.persist(cookies[_session_id_key])
11
+ @_fingerprint = Marshal.dump(request.session.data).hash
12
12
  @_new_cookie = cookies[_session_id_key] != before
13
13
  end
14
14
 
15
15
  def finalize_session
16
16
  MERB_LOGGER.info("Finalize session")
17
- ::Cache.put("session:#{@_session.session_id}", @_session) if @_fingerprint != Marshal.dump(@_session.data).hash
18
- set_cookie(_session_id_key, @_session.session_id, _session_expiry) if (@_new_cookie || @_session.needs_new_cookie)
17
+ if @_fingerprint != Marshal.dump(request.session.data).hash
18
+ ::Cache.put("session:#{@_session.session_id}", request.session.data)
19
+ end
20
+ set_cookie(_session_id_key, request.session.session_id, _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
19
21
  end
20
22
 
23
+ def session_store_type
24
+ "memcache"
25
+ end
21
26
  end
22
27
 
23
28
  ##
@@ -25,12 +30,12 @@ module Merb
25
30
  #
26
31
  # Requires setup in your +merb_init.rb+:
27
32
  #
28
- # require 'memcache_util'
33
+ # require 'memcache'
29
34
  # CACHE = MemCache.new('127.0.0.1:11211', { :namespace => 'my_app' })
30
35
  #
31
36
  # And a setting in +merb.yml+:
32
37
  #
33
- # :mem_cache_session: true
38
+ # :session_store: mem_cache
34
39
 
35
40
  class MemCacheSession
36
41
 
@@ -53,7 +58,7 @@ module Merb
53
58
  # Gets the existing session based on the <tt>session_id</tt> available in cookies.
54
59
  # If none is found, generates a new session.
55
60
  def persist(session_id)
56
- if session_id
61
+ unless session_id.blank?
57
62
  session = ::Cache.get("session:#{session_id}")
58
63
  if session.nil?
59
64
  # Not in memcached, but assume that cookie exists
@@ -63,7 +68,15 @@ module Merb
63
68
  # No cookie...make a new session_id
64
69
  session = generate
65
70
  end
66
- [session, session.session_id]
71
+ if session.is_a?( MemCacheSession )
72
+ [session, session.session_id]
73
+ else
74
+ # recreate using the rails session as the data
75
+ session_object = MemCacheSession.new(session_id)
76
+ session_object.data = session
77
+ [session_object, session_object.session_id]
78
+ end
79
+
67
80
  end
68
81
 
69
82
  # Don't try to reload in dev mode.
@@ -4,16 +4,19 @@ module Merb
4
4
 
5
5
  def setup_session
6
6
  MERB_LOGGER.info("Setting up session")
7
- before = @_cookies[_session_id_key]
8
- @_session , @_cookies[_session_id_key] = Merb::MemorySession.persist(@_cookies[_session_id_key])
9
- @_new_cookie = @_cookies[_session_id_key] != before
7
+ before = cookies[_session_id_key]
8
+ request.session , cookies[_session_id_key] = Merb::MemorySession.persist(cookies[_session_id_key])
9
+ @_new_cookie = cookies[_session_id_key] != before
10
10
  end
11
11
 
12
12
  def finalize_session
13
13
  MERB_LOGGER.info("Finalize session")
14
- set_cookie(_session_id_key, @_session.session_id, _session_expiry) if (@_new_cookie || @_session.needs_new_cookie)
15
- end
16
-
14
+ set_cookie(_session_id_key, request.session.session_id, _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
15
+ end
16
+
17
+ def session_store_type
18
+ "memory"
19
+ end
17
20
  end
18
21
 
19
22
  class MemorySession
@@ -38,7 +41,7 @@ module Merb
38
41
  # If none is found, generates a new session.
39
42
  def persist(session_id)
40
43
  if session_id
41
- session = session = MemorySessionContainer[session_id]
44
+ session = MemorySessionContainer[session_id]
42
45
  end
43
46
  unless session
44
47
  session = generate
@@ -87,12 +90,11 @@ module Merb
87
90
  class MemorySessionContainer
88
91
  class << self
89
92
 
90
- def setup(opts={})
91
- @opts = opts
93
+ def setup(ttl=nil)
92
94
  @sessions = Hash.new
93
95
  @timestamps = Hash.new
94
96
  @mutex = Mutex.new
95
- @session_ttl = opts.fetch(:session_ttl, 60*60) # default 1 hour
97
+ @session_ttl = ttl || 60*60 # default 1 hour
96
98
  start_timer
97
99
  self
98
100
  end
@@ -148,4 +150,6 @@ module Merb
148
150
  end # end singleton class
149
151
 
150
152
  end # end MemorySessionContainer
151
- end
153
+ end
154
+
155
+ Merb::MemorySessionContainer.setup(Merb::Server.config[:memory_session_ttl])
@@ -1,10 +1,37 @@
1
1
  module Merb
2
2
  module Template
3
- # TODO : pull up common methods from template engines.
4
- end
5
- end
6
-
7
- template = __DIR__+'/merb/template'
8
-
9
- %w[ erubis markaby xml_builder haml
10
- ].each {|fn| require File.join(template, fn)}
3
+ autoload :Erubis, 'merb/template/erubis'
4
+ autoload :Haml, 'merb/template/haml'
5
+ autoload :Markaby, 'merb/template/markaby'
6
+ autoload :XMLBuilder, 'merb/template/xml_builder'
7
+
8
+ EXTENSIONS = {} unless defined?(EXTENSIONS)
9
+
10
+ # lookup the template_extensions for the extname of the filename
11
+ # you pass. Answers with the engine that matches the extension
12
+ def self.engine_for(file)
13
+ engine_for_extension(File.extname(file)[1..-1])
14
+ end
15
+
16
+ def self.engine_for_extension(ext)
17
+ const_get EXTENSIONS[ext]
18
+ end
19
+
20
+ def self.register_extensions(engine,extensions)
21
+ raise ArgumentError unless engine.is_a?(Symbol) && extensions.is_a?(Array)
22
+ extensions.each{ |ext| EXTENSIONS[ext] = engine }
23
+ end
24
+
25
+ # Register the default extensions. They must be here
26
+ # since the template engines will not be loaded until they
27
+ # are directly referenced, or a file with their extension is found.
28
+ # If these are declared inside the template engine then
29
+ # they will never be found :(
30
+ register_extensions( :Erubis, %w[erb herb jerb rhtml])
31
+ register_extensions( :Haml, %w[haml])
32
+ register_extensions( :Markaby, %w[mab])
33
+ register_extensions( :XMLBuilder, %w[builder rxml xerb])
34
+
35
+ end
36
+
37
+ end
@@ -1,10 +1,13 @@
1
1
  module Merb # :nodoc:
2
2
  module Template # :nodoc:
3
3
 
4
+ class ErubisViewContext < ViewContext
5
+ include ::Merb::ErubisCaptureMixin
6
+ end
7
+
4
8
  # Module to allow you to use Embedded Ruby templates through Erubis["http://www.kuwata-lab.com/erubis/"].
5
9
  # Your template must end in .herb (HTML and ERb), .jerb (JavaScript ERb), .erb (Embedded Ruby), or .rhtml (Ruby HTML) for Merb to use it.
6
10
  module Erubis
7
- ::Merb::AbstractController.register_engine self, %w[ herb jerb erb rhtml html.erb js.erb ]
8
11
  class << self
9
12
 
10
13
  @@erbs = {}
@@ -21,24 +24,27 @@ module Merb # :nodoc:
21
24
  # by calling <tt>new_eruby_obj</tt>, which will compile the template and return an Erubis
22
25
  # object holding the parsed template.
23
26
  def transform(options = {})
24
- opts, file, view_context = options.values_at(:opts, :file, :view_context)
25
- eruby = new_eruby_obj(file)
26
- view_context.extend(::Merb::ErubisCaptureMixin)
27
+ opts, text, file, view_context = options.values_at(:opts, :text, :file, :view_context)
28
+ eruby = text ? ::Erubis::MEruby.new(text) : new_eruby_obj(file)
27
29
  eruby.evaluate(view_context)
28
30
  end
29
31
 
32
+ def view_context_klass
33
+ ErubisViewContext
34
+ end
35
+
30
36
  # Creates a new Erubis object to parse the template given in +path+.
31
37
  def new_eruby_obj(path)
32
38
  if @@erbs[path] && !cache_template?(path)
33
39
  return @@erbs[path]
34
40
  else
35
41
  begin
36
- returning ::Erubis::MEruby.new(IO.read(path)) do |eruby|
37
- eruby.init_evaluator :filename => path
38
- if cache_template?(path)
39
- @@erbs[path], @@mtimes[path] = eruby, Time.now
40
- end
41
- end
42
+ eruby = ::Erubis::MEruby.new(IO.read(path))
43
+ eruby.init_evaluator :filename => path
44
+ if cache_template?(path)
45
+ @@erbs[path], @@mtimes[path] = eruby, Time.now
46
+ end
47
+ eruby
42
48
  rescue Errno::ENOENT
43
49
  raise "No template found at path: #{path}"
44
50
  end
@@ -1,18 +1,27 @@
1
-
2
-
3
1
  begin
4
2
  require 'haml/engine'
5
3
  rescue LoadError
6
4
  puts "you must install the haml gem to use .haml templates"
7
5
  end
6
+ require File.join( File.dirname(__FILE__), "..", "template")
8
7
 
8
+ module Haml
9
+ module Helpers
10
+
11
+ def _buffer( binding )
12
+ @_buffer ||= eval( "_erbout", binding )
13
+ end
14
+
15
+ alias_method :capture, :capture_haml
16
+
17
+ end
18
+ end
9
19
 
10
20
  module Merb
11
21
  module Template
12
- module Haml
13
-
14
- ::Merb::AbstractController.register_engine self, %w[ haml ]
15
22
 
23
+ module Haml
24
+
16
25
  class << self
17
26
 
18
27
  @@hamls ||= {}
@@ -23,23 +32,27 @@ module Merb
23
32
  end
24
33
 
25
34
  def transform(options = {})
26
- opts, file, view_context = options.values_at(:opts, :file, :view_context)
35
+ opts, text, file, view_context = options.values_at(:opts, :text, :file, :view_context)
27
36
 
28
- begin
29
- locals_code = build_locals(opts[:locals])
30
- opts[:locals] = {}
31
-
32
- template = load_template(file)
33
-
34
- haml = ::Haml::Engine.new("#{locals_code}#{template}", opts)
35
- haml.to_html(view_context)
36
- rescue
37
- # ::Haml::Engine often inserts a bogus "(haml):#{line_number}" entry in the backtrace.
38
- # Let's replace it with the path of the actual template
39
- $@[0].sub! /\(haml\)/, file
40
- raise # Raise the exception again
37
+ begin
38
+ locals_code = build_locals(opts[:locals])
39
+ opts[:locals] = {}
40
+
41
+ template = text ? text : load_template(file)
42
+
43
+ haml = ::Haml::Engine.new("#{locals_code}#{template}", opts)
44
+ haml.to_html(view_context)
45
+ rescue
46
+ # ::Haml::Engine often inserts a bogus "(haml):#{line_number}" entry in the backtrace.
47
+ # Let's replace it with the path of the actual template
48
+ $@[0].sub! /\(haml\)/, file
49
+ raise # Raise the exception again
41
50
  end
42
51
  end
52
+
53
+ def view_context_klass
54
+ ::Merb::ViewContext
55
+ end
43
56
 
44
57
  private
45
58
  def load_template(file)
@@ -57,7 +70,7 @@ module Merb
57
70
 
58
71
  def build_locals(locals)
59
72
  locals_code = ""
60
- if locals
73
+ if locals
61
74
  locals.keys.each do |key|
62
75
  locals_code << "- #{key} = @_merb_partial_locals[:#{key}]\n"
63
76
  end