merb 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +71 -14
- data/Rakefile +20 -31
- data/examples/skeleton.tar +0 -0
- data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +1 -1
- data/lib/merb.rb +3 -2
- data/lib/merb/caching.rb +5 -0
- data/lib/merb/caching/action_cache.rb +56 -0
- data/lib/merb/caching/fragment_cache.rb +38 -0
- data/lib/merb/caching/store/file_cache.rb +82 -0
- data/lib/merb/caching/store/memory_cache.rb +67 -0
- data/lib/merb/core_ext.rb +1 -1
- data/lib/merb/core_ext/merb_hash.rb +35 -0
- data/lib/merb/core_ext/merb_object.rb +88 -2
- data/lib/merb/merb_controller.rb +71 -69
- data/lib/merb/merb_dispatcher.rb +72 -0
- data/lib/merb/merb_exceptions.rb +6 -1
- data/lib/merb/merb_handler.rb +19 -47
- data/lib/merb/merb_mailer.rb +1 -1
- data/lib/merb/merb_request.rb +11 -3
- data/lib/merb/merb_router.rb +113 -8
- data/lib/merb/merb_server.rb +71 -12
- data/lib/merb/merb_upload_handler.rb +8 -6
- data/lib/merb/merb_upload_progress.rb +1 -1
- data/lib/merb/merb_view_context.rb +13 -3
- data/lib/merb/mixins/basic_authentication_mixin.rb +1 -3
- data/lib/merb/mixins/controller_mixin.rb +149 -17
- data/lib/merb/mixins/form_control_mixin.rb +1 -0
- data/lib/merb/mixins/render_mixin.rb +148 -151
- data/lib/merb/mixins/responder_mixin.rb +133 -18
- data/lib/merb/mixins/view_context_mixin.rb +24 -0
- data/lib/merb/session/merb_ar_session.rb +4 -4
- data/lib/merb/session/merb_memory_session.rb +6 -5
- data/lib/merb/template.rb +10 -0
- data/lib/merb/template/erubis.rb +52 -0
- data/lib/merb/template/haml.rb +77 -0
- data/lib/merb/template/markaby.rb +48 -0
- data/lib/merb/template/xml_builder.rb +34 -0
- metadata +19 -17
- data/lib/merb/mixins/merb_status_codes.rb +0 -59
@@ -31,6 +31,30 @@ module Merb
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
|
35
|
+
# Helper method to cache a fragment.
|
36
|
+
# <h1>Article list</h1>
|
37
|
+
#
|
38
|
+
# <% cache(:article_list) do %>
|
39
|
+
# <ul>
|
40
|
+
# <% @articles.each do |a| %>
|
41
|
+
# <li><%= a.title %></li>
|
42
|
+
# <% end %>
|
43
|
+
# </ul>
|
44
|
+
# <% end %>
|
45
|
+
|
46
|
+
def cache(name, &block)
|
47
|
+
return block.call unless caching_enabled?
|
48
|
+
buffer = eval("_buf", block.binding)
|
49
|
+
if fragment = ::Merb::Caching::Fragment.get(name)
|
50
|
+
buffer.concat(fragment)
|
51
|
+
else
|
52
|
+
pos = buffer.length
|
53
|
+
block.call
|
54
|
+
::Merb::Caching::Fragment.put(name, buffer[pos..-1])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
34
58
|
# Requiring javascripts and stylesheets:
|
35
59
|
# you can use require_js(:prototype) or require_css(:shinystyles)
|
36
60
|
# from any view or layout and the scripts will only be included once
|
@@ -6,10 +6,10 @@ 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::Session.persist(cookies[session_id_key])
|
9
|
+
before = @cookies[ancestral_trait[:session_id_key]]
|
10
|
+
@session, @cookies[ancestral_trait[:session_id_key]] = Merb::Session.persist(@cookies[ancestral_trait[:session_id_key]])
|
11
11
|
@_fingerprint_before = Marshal.dump(@session).hash
|
12
|
-
@_new_cookie = cookies[session_id_key] != before
|
12
|
+
@_new_cookie = @cookies[ancestral_trait[:session_id_key]] != before
|
13
13
|
end
|
14
14
|
|
15
15
|
def finalize_session
|
@@ -17,7 +17,7 @@ module Merb
|
|
17
17
|
unless Marshal.dump(@session).hash == @_fingerprint_before
|
18
18
|
@session.save
|
19
19
|
end
|
20
|
-
set_cookie(session_id_key, cookies[session_id_key], Time.now+Merb::Const::WEEK*2) if @_new_cookie
|
20
|
+
set_cookie(ancestral_trait[:session_id_key], @cookies[ancestral_trait[:session_id_key]], Time.now+Merb::Const::WEEK*2) if @_new_cookie
|
21
21
|
end
|
22
22
|
|
23
23
|
end
|
@@ -4,14 +4,14 @@ 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[ancestral_trait[:session_id_key]]
|
8
|
+
@session , @cookies[ancestral_trait[:session_id_key]] = Merb::MemorySession.persist(@cookies[ancestral_trait[:session_id_key]])
|
9
|
+
@_new_cookie = @cookies[ancestral_trait[: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, cookies[session_id_key], Time.now+Merb::Const::WEEK*2) if @_new_cookie
|
14
|
+
set_cookie(ancestral_trait[:session_id_key], @cookies[ancestral_trait[:session_id_key]], Time.now+Merb::Const::WEEK*2) if @_new_cookie
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
@@ -73,6 +73,7 @@ module Merb
|
|
73
73
|
def delete(key)
|
74
74
|
@mutex.synchronize {
|
75
75
|
@sessions.delete(key)
|
76
|
+
@timestamps.delete(key)
|
76
77
|
}
|
77
78
|
end
|
78
79
|
|
@@ -102,4 +103,4 @@ module Merb
|
|
102
103
|
|
103
104
|
end # end DRbSession
|
104
105
|
|
105
|
-
end
|
106
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Merb
|
2
|
+
module Template
|
3
|
+
|
4
|
+
|
5
|
+
module Erubis
|
6
|
+
::Merb::Controller.register_engine self, %w[ herb jerb erb ]
|
7
|
+
class << self
|
8
|
+
|
9
|
+
@@erbs = {}
|
10
|
+
@@mtimes = {}
|
11
|
+
|
12
|
+
def exempt_from_layout?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def transform(options = {})
|
17
|
+
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
18
|
+
eruby = new_eruby_obj(file)
|
19
|
+
view_context.class.send(:include, ::Merb::ErubisCaptureMixin)
|
20
|
+
eruby.evaluate(view_context)
|
21
|
+
end
|
22
|
+
|
23
|
+
def new_eruby_obj(path)
|
24
|
+
if @@erbs[path] && !cache_template?(path)
|
25
|
+
return @@erbs[path]
|
26
|
+
else
|
27
|
+
begin
|
28
|
+
returning ::Erubis::MEruby.new(IO.read(path)) do |eruby|
|
29
|
+
eruby.init_evaluator :filename => path
|
30
|
+
if cache_template?(path)
|
31
|
+
@@erbs[path], @@mtimes[path] = eruby, Time.now
|
32
|
+
end
|
33
|
+
end
|
34
|
+
rescue Errno::ENOENT
|
35
|
+
raise "No template found at path: #{path}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache_template?(path)
|
41
|
+
return false unless ::Merb::Server.config[:cache_templates]
|
42
|
+
return true unless @@erbs[path]
|
43
|
+
@@mtimes[path] < File.mtime(path) ||
|
44
|
+
(File.symlink?(path) && (@@mtimes[path] < File.lstat(path).mtime))
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'haml/engine'
|
5
|
+
rescue LoadError
|
6
|
+
puts "you must install the haml gem to use .haml templates"
|
7
|
+
end
|
8
|
+
module ActionView
|
9
|
+
# stub, in case the requires for that active_* stuff of Haml doesn't fail
|
10
|
+
# but we are not running Rails ;)
|
11
|
+
class Base
|
12
|
+
# stub
|
13
|
+
def concat
|
14
|
+
end
|
15
|
+
# stub
|
16
|
+
def form_tag
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
module Merb
|
23
|
+
module Template
|
24
|
+
module Haml
|
25
|
+
|
26
|
+
# Custom HAML-options to be merged.
|
27
|
+
|
28
|
+
trait :haml_options => {
|
29
|
+
:locals => {}
|
30
|
+
}
|
31
|
+
|
32
|
+
::Merb::Controller.register_engine self, %w[ haml ]
|
33
|
+
|
34
|
+
class << self
|
35
|
+
@@hamls ||= {}
|
36
|
+
@@mtimes ||= {}
|
37
|
+
def exempt_from_layout?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def transform(options = {})
|
42
|
+
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
43
|
+
opts = ancestral_trait[:haml_options].merge(opts)
|
44
|
+
if precompiled = get_precompiled(file)
|
45
|
+
opts[:precompiled] ||= precompiled
|
46
|
+
haml = ::Haml::Engine.new("", opts)
|
47
|
+
else
|
48
|
+
haml = ::Haml::Engine.new(IO.read(file), opts)
|
49
|
+
set_precompiled(file, haml.precompiled)
|
50
|
+
end
|
51
|
+
haml.to_html(view_context)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def get_precompiled(path, opts={})
|
57
|
+
if @@hamls[path] && !cache_template?(path)
|
58
|
+
return @@hamls[path]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_precompiled(path, precompiled)
|
63
|
+
@@hamls[path], @@mtimes[path] = precompiled, Time.now
|
64
|
+
end
|
65
|
+
|
66
|
+
def cache_template?(path)
|
67
|
+
return false unless ::Merb::Server.config[:cache_templates]
|
68
|
+
return true unless @@hamls[path]
|
69
|
+
@@mtimes[path] < File.mtime(path) ||
|
70
|
+
(File.symlink?(path) && (@@mtimes[path] < File.lstat(path).mtime))
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'markaby'
|
4
|
+
rescue LoadError
|
5
|
+
puts "you must install the markaby gem to use .mab templates"
|
6
|
+
end
|
7
|
+
|
8
|
+
module Markaby
|
9
|
+
class Builder
|
10
|
+
def _buf; self end
|
11
|
+
def throw_content(name, &block)
|
12
|
+
@helpers.instance_variable_set "@_#{name}_content",
|
13
|
+
eval("@_#{name}_content = (@_#{name}_content|| '') + capture(&block)")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Merb
|
19
|
+
|
20
|
+
module Template
|
21
|
+
|
22
|
+
module Markaby
|
23
|
+
|
24
|
+
::Merb::Controller.register_engine self, %w[ mab ]
|
25
|
+
|
26
|
+
class << self
|
27
|
+
|
28
|
+
def exempt_from_layout?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
# OPTIMIZE : add mab template caching. what does this mean for mab?
|
33
|
+
# mab is just ruby, there's no two phase compile and run
|
34
|
+
def transform(options = {})
|
35
|
+
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
36
|
+
mab = ::Markaby::Builder.new({}, view_context) {
|
37
|
+
instance_eval(File.read(file))
|
38
|
+
}
|
39
|
+
mab.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Merb
|
2
|
+
|
3
|
+
module Template
|
4
|
+
|
5
|
+
module XMLBuilder
|
6
|
+
|
7
|
+
::Merb::Controller.register_engine self, %w[ rxml xerb builder]
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def exempt_from_layout?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def transform(options = {})
|
16
|
+
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
17
|
+
xml_body = IO.read(file)
|
18
|
+
view_context.headers['Content-Type'] = 'application/xml'
|
19
|
+
view_context.headers['Encoding'] = 'UTF-8'
|
20
|
+
view_context.instance_eval %{
|
21
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
22
|
+
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
23
|
+
#{xml_body}
|
24
|
+
return xml.target!
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: merb
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-03-18 00:00:00 -07:00
|
8
8
|
summary: Merb == Mongrel + Erb. Pocket rocket web framework.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -38,11 +38,14 @@ files:
|
|
38
38
|
- lib/merb.rb
|
39
39
|
- lib/merb_tasks.rb
|
40
40
|
- lib/tasks
|
41
|
+
- lib/merb/caching
|
42
|
+
- lib/merb/caching.rb
|
41
43
|
- lib/merb/core_ext
|
42
44
|
- lib/merb/core_ext.rb
|
43
45
|
- lib/merb/generators
|
44
46
|
- lib/merb/merb_constants.rb
|
45
47
|
- lib/merb/merb_controller.rb
|
48
|
+
- lib/merb/merb_dispatcher.rb
|
46
49
|
- lib/merb/merb_drb_server.rb
|
47
50
|
- lib/merb/merb_exceptions.rb
|
48
51
|
- lib/merb/merb_handler.rb
|
@@ -56,7 +59,14 @@ files:
|
|
56
59
|
- lib/merb/merb_yaml_store.rb
|
57
60
|
- lib/merb/mixins
|
58
61
|
- lib/merb/session
|
62
|
+
- lib/merb/template
|
63
|
+
- lib/merb/template.rb
|
59
64
|
- lib/merb/vendor
|
65
|
+
- lib/merb/caching/action_cache.rb
|
66
|
+
- lib/merb/caching/fragment_cache.rb
|
67
|
+
- lib/merb/caching/store
|
68
|
+
- lib/merb/caching/store/file_cache.rb
|
69
|
+
- lib/merb/caching/store/memory_cache.rb
|
60
70
|
- lib/merb/core_ext/merb_class.rb
|
61
71
|
- lib/merb/core_ext/merb_enumerable.rb
|
62
72
|
- lib/merb/core_ext/merb_hash.rb
|
@@ -72,12 +82,15 @@ files:
|
|
72
82
|
- lib/merb/mixins/controller_mixin.rb
|
73
83
|
- lib/merb/mixins/erubis_capture_mixin.rb
|
74
84
|
- lib/merb/mixins/form_control_mixin.rb
|
75
|
-
- lib/merb/mixins/merb_status_codes.rb
|
76
85
|
- lib/merb/mixins/render_mixin.rb
|
77
86
|
- lib/merb/mixins/responder_mixin.rb
|
78
87
|
- lib/merb/mixins/view_context_mixin.rb
|
79
88
|
- lib/merb/session/merb_ar_session.rb
|
80
89
|
- lib/merb/session/merb_memory_session.rb
|
90
|
+
- lib/merb/template/erubis.rb
|
91
|
+
- lib/merb/template/haml.rb
|
92
|
+
- lib/merb/template/markaby.rb
|
93
|
+
- lib/merb/template/xml_builder.rb
|
81
94
|
- lib/merb/vendor/paginator
|
82
95
|
- lib/merb/vendor/paginator/paginator.rb
|
83
96
|
- lib/merb/vendor/paginator/README.txt
|
@@ -120,19 +133,8 @@ files:
|
|
120
133
|
- examples/skeleton/test/unit
|
121
134
|
test_files: []
|
122
135
|
|
123
|
-
rdoc_options:
|
124
|
-
|
125
|
-
- --title
|
126
|
-
- Merb Documentation
|
127
|
-
- --opname
|
128
|
-
- index.html
|
129
|
-
- --line-numbers
|
130
|
-
- TODO
|
131
|
-
- --main
|
132
|
-
- README
|
133
|
-
- --inline-source
|
134
|
-
- --exclude
|
135
|
-
- ^(app|uploads)
|
136
|
+
rdoc_options: []
|
137
|
+
|
136
138
|
extra_rdoc_files:
|
137
139
|
- README
|
138
140
|
- LICENSE
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Merb
|
2
|
-
# thanks to Michael Fellinger
|
3
|
-
STATUS_CODEs = {
|
4
|
-
# 1xx Informational (Request received, continuing process.)
|
5
|
-
:continue => 100,
|
6
|
-
:switching_protocols => 101,
|
7
|
-
|
8
|
-
# 2xx Success (The action was successfully received, understood, and accepted.)
|
9
|
-
:ok => 200,
|
10
|
-
:created => 201,
|
11
|
-
:accepted => 202,
|
12
|
-
:non_authorative_information => 203,
|
13
|
-
:no_content => 204,
|
14
|
-
:resent_content => 205,
|
15
|
-
:partial_content => 206,
|
16
|
-
:multi_status => 207,
|
17
|
-
|
18
|
-
# 3xx Redirection (The client must take additional action to complete the request.)
|
19
|
-
:multiple_choices => 300,
|
20
|
-
:moved_permamently => 301,
|
21
|
-
:moved_temporarily => 302,
|
22
|
-
:found => 302,
|
23
|
-
:see_other => 303,
|
24
|
-
:not_modified => 304,
|
25
|
-
:use_proxy => 305,
|
26
|
-
:switch_proxy => 306,
|
27
|
-
:temporary_redirect => 307,
|
28
|
-
|
29
|
-
# 4xx Client Error (The request contains bad syntax or cannot be fulfilled.)
|
30
|
-
:bad_request => 400,
|
31
|
-
:unauthorized => 401,
|
32
|
-
:payment_required => 402,
|
33
|
-
:forbidden => 403,
|
34
|
-
:not_found => 404,
|
35
|
-
:method_not_allowed => 405,
|
36
|
-
:not_aceptable => 406,
|
37
|
-
:proxy_authentication_required => 407,
|
38
|
-
:request_timeout => 408,
|
39
|
-
:conflict => 409,
|
40
|
-
:gone => 410,
|
41
|
-
:length_required => 411,
|
42
|
-
:precondition_failed => 412,
|
43
|
-
:request_entity_too_large => 413,
|
44
|
-
:request_uri_too_long => 414,
|
45
|
-
:unsupported_media_type => 415,
|
46
|
-
:requested_range_not_satisfiable => 416,
|
47
|
-
:expectation_failed => 417,
|
48
|
-
:retry_with => 449,
|
49
|
-
|
50
|
-
# 5xx Server Error (The server failed to fulfill an apparently valid request.)
|
51
|
-
:internal_server_error => 500,
|
52
|
-
:not_implemented => 501,
|
53
|
-
:bad_gateway => 502,
|
54
|
-
:service_unavailable => 503,
|
55
|
-
:gateway_timeout => 504,
|
56
|
-
:http_version_not_supported => 505,
|
57
|
-
:bandwidth_limit_exceeded => 509, # (not official)
|
58
|
-
}
|
59
|
-
end
|