merb 0.3.7 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +25 -26
- data/Rakefile +48 -36
- data/app_generators/merb/USAGE +5 -0
- data/app_generators/merb/merb_generator.rb +107 -0
- data/app_generators/merb/templates/Rakefile +99 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/controllers/application.rb +1 -1
- data/app_generators/merb/templates/app/controllers/exceptions.rb +13 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/helpers/global_helper.rb +0 -0
- data/{examples/skeleton/dist/app/mailers → app_generators/merb/templates/app/mailers/views}/layout/application.erb +0 -0
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +207 -0
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +38 -0
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +40 -0
- data/app_generators/merb/templates/app/views/layout/application.html.erb +11 -0
- data/app_generators/merb/templates/config/boot.rb +11 -0
- data/app_generators/merb/templates/config/dependencies.rb +41 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/development.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/production.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/test.rb +0 -0
- data/app_generators/merb/templates/config/merb.yml +64 -0
- data/app_generators/merb/templates/config/merb_init.rb +16 -0
- data/app_generators/merb/templates/config/plugins.yml +1 -0
- data/app_generators/merb/templates/config/router.rb +32 -0
- data/{lib/merb/core_ext/merb_array.rb → app_generators/merb/templates/config/upload.conf} +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +6 -0
- data/app_generators/merb/templates/public/stylesheets/master.css +119 -0
- data/app_generators/merb/templates/script/destroy +28 -0
- data/app_generators/merb/templates/script/generate +28 -0
- data/{examples/skeleton → app_generators/merb/templates}/script/stop_merb +0 -0
- data/app_generators/merb/templates/script/win_script.cmd +1 -0
- data/app_generators/merb/templates/spec/spec.opts +6 -0
- data/app_generators/merb/templates/spec/spec_helper.rb +10 -0
- data/app_generators/merb/templates/test/test_helper.rb +13 -0
- data/app_generators/merb_plugin/USAGE +5 -0
- data/app_generators/merb_plugin/merb_plugin_generator.rb +64 -0
- data/app_generators/merb_plugin/templates/LICENSE +20 -0
- data/app_generators/merb_plugin/templates/README +4 -0
- data/app_generators/merb_plugin/templates/Rakefile +35 -0
- data/app_generators/merb_plugin/templates/TODO +5 -0
- data/app_generators/merb_plugin/templates/merbtasks.rb +6 -0
- data/app_generators/merb_plugin/templates/sampleplugin.rb +10 -0
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +7 -0
- data/app_generators/merb_plugin/templates/spec_helper.rb +2 -0
- data/bin/merb +1 -1
- data/lib/autotest/discover.rb +3 -0
- data/lib/autotest/merb_rspec.rb +79 -0
- data/lib/merb.rb +72 -93
- data/lib/merb/{merb_abstract_controller.rb → abstract_controller.rb} +28 -5
- data/lib/merb/caching/action_cache.rb +65 -29
- data/lib/merb/caching/fragment_cache.rb +9 -4
- data/lib/merb/caching/store/file_cache.rb +22 -14
- data/lib/merb/caching/store/memory_cache.rb +26 -8
- data/lib/merb/{merb_constants.rb → constants.rb} +9 -7
- data/lib/merb/controller.rb +178 -0
- data/lib/merb/core_ext.rb +13 -11
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/{merb_class.rb → class.rb} +0 -0
- data/lib/merb/core_ext/{merb_enumerable.rb → enumerable.rb} +0 -0
- data/lib/merb/core_ext/get_args.rb +52 -0
- data/lib/merb/core_ext/{merb_hash.rb → hash.rb} +40 -11
- data/lib/merb/core_ext/{merb_inflections.rb → inflections.rb} +0 -0
- data/lib/merb/core_ext/{merb_inflector.rb → inflector.rb} +1 -1
- data/lib/merb/core_ext/{merb_kernel.rb → kernel.rb} +56 -3
- data/lib/merb/core_ext/mash.rb +88 -0
- data/lib/merb/core_ext/{merb_module.rb → module.rb} +0 -0
- data/lib/merb/core_ext/{merb_numeric.rb → numeric.rb} +0 -0
- data/lib/merb/core_ext/{merb_object.rb → object.rb} +10 -47
- data/lib/merb/core_ext/string.rb +56 -0
- data/lib/merb/core_ext/{merb_symbol.rb → symbol.rb} +0 -0
- data/lib/merb/dispatcher.rb +109 -0
- data/lib/merb/{merb_drb_server.rb → drb_server.rb} +0 -0
- data/lib/merb/erubis_ext.rb +10 -0
- data/lib/merb/exceptions.rb +173 -0
- data/lib/merb/generators/merb_app/merb_app.rb +5 -25
- data/lib/merb/generators/merb_generator_helpers.rb +317 -0
- data/lib/merb/generators/merb_plugin.rb +19 -0
- data/lib/merb/logger.rb +65 -0
- data/lib/merb/{merb_mail_controller.rb → mail_controller.rb} +102 -49
- data/lib/merb/{merb_mailer.rb → mailer.rb} +31 -27
- data/lib/merb/mixins/{basic_authentication_mixin.rb → basic_authentication.rb} +3 -3
- data/lib/merb/mixins/{controller_mixin.rb → controller.rb} +131 -112
- data/lib/merb/mixins/{erubis_capture_mixin.rb → erubis_capture.rb} +12 -21
- data/lib/merb/mixins/{form_control_mixin.rb → form_control.rb} +6 -12
- data/lib/merb/mixins/render.rb +401 -0
- data/lib/merb/mixins/responder.rb +378 -0
- data/lib/merb/mixins/{view_context_mixin.rb → view_context.rb} +65 -10
- data/lib/merb/mixins/web_controller.rb +29 -0
- data/lib/merb/{merb_handler.rb → mongrel_handler.rb} +59 -38
- data/lib/merb/part_controller.rb +19 -0
- data/lib/merb/plugins.rb +16 -0
- data/lib/merb/rack_adapter.rb +37 -0
- data/lib/merb/request.rb +421 -0
- data/lib/merb/router.rb +576 -0
- data/lib/merb/{merb_server.rb → server.rb} +275 -71
- data/lib/merb/session.rb +10 -10
- data/lib/merb/session/cookie_store.rb +125 -0
- data/lib/merb/session/{merb_mem_cache_session.rb → mem_cache_session.rb} +22 -9
- data/lib/merb/session/{merb_memory_session.rb → memory_session.rb} +15 -11
- data/lib/merb/template.rb +35 -8
- data/lib/merb/template/erubis.rb +16 -10
- data/lib/merb/template/haml.rb +33 -20
- data/lib/merb/template/markaby.rb +16 -14
- data/lib/merb/template/xml_builder.rb +8 -4
- data/lib/merb/test/{merb_fake_request.rb → fake_request.rb} +11 -5
- data/lib/merb/test/helper.rb +31 -0
- data/lib/merb/test/hpricot.rb +136 -0
- data/lib/merb/test/{merb_multipart.rb → multipart.rb} +1 -1
- data/lib/merb/test/rspec.rb +93 -0
- data/lib/merb/{merb_upload_handler.rb → upload_handler.rb} +5 -6
- data/lib/merb/{merb_upload_progress.rb → upload_progress.rb} +1 -1
- data/lib/merb/{merb_view_context.rb → view_context.rb} +27 -42
- data/lib/{merb_tasks.rb → tasks.rb} +0 -0
- data/lib/tasks/merb.rake +21 -11
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +16 -0
- data/merb_default_generators/model/templates/new_model_template.erb +5 -0
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +26 -0
- data/merb_default_generators/resource_controller/templates/controller.rb +30 -0
- data/merb_default_generators/resource_controller/templates/edit.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/helper.rb +5 -0
- data/merb_default_generators/resource_controller/templates/index.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/new.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/show.html.erb +1 -0
- data/merb_generators/controller/USAGE +5 -0
- data/merb_generators/controller/controller_generator.rb +16 -0
- data/merb_generators/controller/templates/controller.rb +8 -0
- data/merb_generators/controller/templates/helper.rb +5 -0
- data/merb_generators/controller/templates/index.html.erb +3 -0
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +60 -0
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +67 -0
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +8 -0
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +5 -0
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +5 -0
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +26 -0
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +7 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +53 -0
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +17 -0
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +9 -0
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +29 -0
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +9 -0
- metadata +172 -94
- data/examples/README_EXAMPLES +0 -10
- data/examples/skeleton/Rakefile +0 -68
- data/examples/skeleton/dist/app/views/layout/application.herb +0 -12
- data/examples/skeleton/dist/conf/database.yml +0 -23
- data/examples/skeleton/dist/conf/merb.yml +0 -57
- data/examples/skeleton/dist/conf/merb_init.rb +0 -24
- data/examples/skeleton/dist/conf/router.rb +0 -22
- data/examples/skeleton/dist/conf/upload.conf +0 -5
- data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +0 -14
- data/examples/skeleton/script/new_migration +0 -21
- data/lib/merb/core_ext/merb_string.rb +0 -18
- data/lib/merb/merb_controller.rb +0 -206
- data/lib/merb/merb_dispatcher.rb +0 -87
- data/lib/merb/merb_exceptions.rb +0 -319
- data/lib/merb/merb_part_controller.rb +0 -42
- data/lib/merb/merb_plugins.rb +0 -293
- data/lib/merb/merb_request.rb +0 -165
- data/lib/merb/merb_router.rb +0 -309
- data/lib/merb/merb_yaml_store.rb +0 -31
- data/lib/merb/mixins/render_mixin.rb +0 -283
- data/lib/merb/mixins/responder_mixin.rb +0 -159
- data/lib/merb/session/merb_ar_session.rb +0 -131
- data/lib/merb/vendor/paginator/README.txt +0 -84
- data/lib/merb/vendor/paginator/paginator.rb +0 -124
- data/lib/tasks/db.rake +0 -55
data/lib/merb/session.rb
CHANGED
|
@@ -2,16 +2,16 @@ module Merb
|
|
|
2
2
|
module SessionMixin
|
|
3
3
|
|
|
4
4
|
def rand_uuid
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 =
|
|
10
|
-
|
|
11
|
-
@_fingerprint = Marshal.dump(
|
|
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
|
-
|
|
18
|
-
|
|
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 '
|
|
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
|
-
# :
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
8
|
-
|
|
9
|
-
@_new_cookie =
|
|
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,
|
|
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 =
|
|
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(
|
|
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 =
|
|
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])
|
data/lib/merb/template.rb
CHANGED
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
module Merb
|
|
2
2
|
module Template
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
data/lib/merb/template/erubis.rb
CHANGED
|
@@ -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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
data/lib/merb/template/haml.rb
CHANGED
|
@@ -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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
73
|
+
if locals
|
|
61
74
|
locals.keys.each do |key|
|
|
62
75
|
locals_code << "- #{key} = @_merb_partial_locals[:#{key}]\n"
|
|
63
76
|
end
|