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.
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
@@ -1,165 +0,0 @@
1
- module Merb
2
-
3
- class Request
4
- attr_accessor :env
5
- def initialize(env, method, request)
6
- @env = env
7
- @method = method
8
- @request = request
9
- end
10
-
11
- def raw_post
12
- @request.rewind
13
- @request.read
14
- end
15
-
16
- # Returns true if the request is an Ajax request.
17
- #
18
- # Also aliased as the more memorable ajax? and xhr?.
19
- def xml_http_request?
20
- not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil?
21
- end
22
- alias xhr? :xml_http_request?
23
- alias ajax? :xml_http_request?
24
-
25
- # returns the remote IP address if it can find it.
26
- def remote_ip
27
- return @env['HTTP_CLIENT_IP'] if @env.include?('HTTP_CLIENT_IP')
28
-
29
- if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then
30
- remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip|
31
- ip =~ /^unknown$|^(127|10|172\.16|192\.168)\./i
32
- end
33
-
34
- return remote_ips.first.strip unless remote_ips.empty?
35
- end
36
-
37
- return @env[Merb::Const::REMOTE_ADDR]
38
- end
39
-
40
- # returns either 'https://' or 'http://' depending on
41
- # the HTTPS header
42
- def protocol
43
- ssl? ? 'https://' : 'http://'
44
- end
45
-
46
- # returns true if the request is an SSL request
47
- def ssl?
48
- @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
49
- end
50
-
51
- # returns the request HTTP_REFERER.
52
- def referer
53
- @env['HTTP_REFERER']
54
- end
55
-
56
- # returns he request uri.
57
- def uri
58
- @env['REQUEST_URI']
59
- end
60
-
61
- def user_agent
62
- @env['HTTP_USER_AGENT']
63
- end
64
-
65
- def server_name
66
- @env['SERVER_NAME']
67
- end
68
-
69
- def accept_encoding
70
- @env['HTTP_ACCEPT_ENCODING']
71
- end
72
-
73
- def script_name
74
- @env['SCRIPT_NAME']
75
- end
76
-
77
- def cache_control
78
- @env['HTTP_CACHE_CONTROL']
79
- end
80
-
81
- def accept_language
82
- @env['HTTP_ACCEPT_LANGUAGE']
83
- end
84
-
85
- def host
86
- @env['HTTP_HOST']
87
- end
88
-
89
- def server_software
90
- @env['SERVER_SOFTWARE']
91
- end
92
-
93
- def keep_alive
94
- @env['HTTP_KEEP_ALIVE']
95
- end
96
-
97
- def accept_charset
98
- @env['HTTP_ACCEPT_CHARSET']
99
- end
100
-
101
- def version
102
- @env['HTTP_VERSION']
103
- end
104
-
105
- def gateway
106
- @env['GATEWAY_INTERFACE']
107
- end
108
-
109
- def accept
110
- @env['HTTP_ACCEPT']
111
- end
112
-
113
- def connection
114
- @env['HTTP_CONNECTION']
115
- end
116
-
117
- def query_string
118
- @env['QUERY_STRING']
119
- end
120
-
121
- # returns the uri without the query string.
122
- def path
123
- uri ? uri.split('?').first : ''
124
- end
125
-
126
- # returns the PATH_INFO
127
- def path_info
128
- @env['PATH_INFO']
129
- end
130
-
131
- # returns the port the server is running on
132
- def port
133
- @env['SERVER_PORT'].to_i
134
- end
135
-
136
- # returns the full hostname including port
137
- def host
138
- @env['HTTP_X_FORWARDED_HOST'] || @env['HTTP_HOST']
139
- end
140
-
141
- # returns an array of all the subdomain parts of the host.
142
- def subdomains(tld_length = 1)
143
- parts = host.split('.')
144
- parts[0..-(tld_length+2)]
145
- end
146
-
147
- # returns the full domain name without the port number.
148
- def domain(tld_length = 1)
149
- host.split('.').last(1 + tld_length).join('.').sub(/:\d+$/,'')
150
- end
151
-
152
- # returns the REQUEST_METHOD
153
- def method
154
- @method ||= @env['REQUEST_METHOD'].downcase.intern
155
- end
156
-
157
- # create predicate methods for querying the REQUEST_METHOD
158
- [:get, :post, :put, :delete, :head].each do |m|
159
- define_method("#{m}?") { method == m.to_sym }
160
- end
161
-
162
- end
163
-
164
- end
165
-
@@ -1,309 +0,0 @@
1
- module Merb
2
-
3
- class Router
4
-
5
- SECTION_REGEXP = /(?::([a-z*_]+))/.freeze
6
-
7
- class << self
8
-
9
- def prepare
10
- @@matcher = RouteMatcher.new
11
- @@generator = RouteGenerator.new
12
-
13
- yield self
14
-
15
- @@matcher.compile_router
16
- end
17
-
18
- def add(*route)
19
- @@matcher.add(*route)
20
- end
21
-
22
- def matcher
23
- @@matcher
24
- end
25
-
26
- def generator
27
- @@generator
28
- end
29
-
30
- def match(path)
31
- @@matcher.route_request(path)
32
- end
33
-
34
- def generate(method, *args)
35
- @@generator.generate(method, *args)
36
- end
37
-
38
- def resources(res, opts={})
39
- opts[:prefix] ||= ""
40
- if block_given?
41
- procs = []
42
- yield Resource.new(res, procs, opts)
43
- procs.reverse.each &:call
44
- else
45
- generate_resources_routes(res,opts)
46
- end
47
- end
48
-
49
- def resource(res, opts={})
50
- opts[:prefix] ||= ""
51
- if block_given?
52
- procs = []
53
- yield Resource.new(res, procs, opts)
54
- procs.reverse.each &:call
55
- else
56
- generate_singleton_routes(res,opts)
57
- end
58
- end
59
-
60
- def default_routes(*a)
61
- @@matcher.default_routes(*a)
62
- end
63
-
64
- def compiled_statement
65
- @@matcher.compiled_statement
66
- end
67
-
68
- def compiled_regexen
69
- @@matcher.compiled_regexen
70
- end
71
-
72
- def generate_resources_routes(res, opts)
73
- [@@matcher,@@generator].each { |r| r.generate_resources_routes(res, opts) }
74
- end
75
-
76
- def generate_singleton_routes(res, opts)
77
- [@@matcher,@@generator].each { |r| r.generate_singleton_routes(res, opts) }
78
- end
79
-
80
- end # class << self
81
-
82
- class RouteMatcher
83
- attr_reader :routes, :compiled_statement, :compiled_regexen
84
-
85
- def initialize
86
- @routes = Array.new
87
- # The final compiled lambda that gets used as the body of the route_request method.
88
- @compiled_statement = String.new
89
- @compiled_regexen = Array.new
90
- end
91
-
92
- # Add a route to be compiled.
93
- def add(*route)
94
- opt = Hash === route.last ? route.pop : {}
95
- if n = opt[:namespace]
96
- path = "/#{n}#{route[0]}"
97
- else
98
- path = route[0]
99
- end
100
- @routes << [path, opt]
101
- end
102
-
103
- def raw_add(*route)
104
- @routes << [route[0], (route[1]||{})]
105
- end
106
-
107
- # Build up a string that defines a lambda that does a case statement on
108
- # the PATH_INFO against each of the compiled routes in turn. First route
109
- # that matches wins.
110
- def compile_router
111
- router_lambda = @routes.inject("lambda{|path| \n sections={}\n case path\n") { |m,r|
112
- m << compile(r)
113
- } << " else\n return {:controller=>'Noroutefound', :action=>'noroute'}\n end\n}"
114
- @compiled_statement = router_lambda
115
- meta_def(:route_request, &eval(router_lambda))
116
- end
117
-
118
- # Compile each individual route into a when /.../ component of the case
119
- # statement. Takes /:sections of the route def that start with : and
120
- # turns them into placeholders for whatever urls match against the route
121
- # in question.
122
- def compile(route)
123
- raise ArgumentError unless String === route[0]
124
- code, count = '', 0
125
- while route[0] =~ Router::SECTION_REGEXP
126
- route[0] = route[0].dup
127
- name = $1
128
- (name =~ /(\*+)(\w+)/) ? (flag = true; name = $2) : (flag = false)
129
- count += 1
130
- if flag
131
- route[0].sub!(Router::SECTION_REGEXP, "([^,?]+)")
132
- else
133
- route[0].sub!(Router::SECTION_REGEXP, "([^\/,?]+)")
134
- end
135
- code << " sections[:#{name}] = $#{count}\n"
136
- end
137
- @compiled_regexen << Regexp.new(route[0])
138
- index = @compiled_regexen.size - 1
139
- condition = " when @compiled_regexen[#{index}] "
140
- statement = "#{condition}\n#{code}"
141
- statement << " return #{route[1].inspect}.update(sections)\n"
142
- statement
143
- end
144
-
145
- def generate_resources_routes(res,opt)
146
- with_options opt.merge(:controller => res.to_s, :rest => true) do |r|
147
- r.raw_add "#{opt[:prefix]}/#{res}/:id[;/]edit", :allowed => {:get => 'edit'}
148
- r.raw_add "#{opt[:prefix]}/#{res}/new[;/]:action", :allowed => {:get => 'new', :post => 'new', :put => 'new', :delete => 'new'}
149
- r.raw_add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
150
- if mem = opt[:member]
151
- mem.keys.sort_by{|x| "#{x}"}.each {|action|
152
- allowed = mem[action].injecting({}) {|h, verb| h[verb] = "#{action}"}
153
- r.raw_add "#{opt[:prefix]}/#{res}/:id[;/]+#{action}", :allowed => allowed
154
- }
155
- end
156
- if coll = opt[:collection]
157
- coll.keys.sort_by{|x| "#{x}"}.each {|action|
158
- allowed = coll[action].injecting({}) {|h, verb| h[verb] = "#{action}"}
159
- r.raw_add "#{opt[:prefix]}/#{res}[;/]#{action}", :allowed => allowed
160
- }
161
- end
162
- r.raw_add "#{opt[:prefix]}/#{res}/:id\\.:format", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
163
- r.raw_add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'index', :post => 'create'}
164
- r.raw_add "#{opt[:prefix]}/#{res}/:id", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
165
- r.raw_add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'index', :post => 'create'}
166
- end
167
- end
168
-
169
- def generate_singleton_routes(res,opt)
170
- with_options opt.merge(:controller => res.to_s, :rest => true ) do |r|
171
- r.raw_add "#{opt[:prefix]}/#{res}[;/]edit", :allowed => {:get => 'edit'}
172
- r.raw_add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'show'}
173
- r.raw_add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
174
- r.raw_add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'show', :post => 'create', :put => 'update', :delete => 'destroy'}
175
- end
176
- end
177
-
178
- def default_routes(opt={})
179
- namespace = opt[:namespace] ? "/#{opt[:namespace]}" : ""
180
- with_options opt do |r|
181
- r.raw_add namespace + "/:controller/:action/:id\\.:format"
182
- r.raw_add namespace + "/:controller/:action/:id"
183
- r.raw_add namespace + "/:controller/:action\\.:format"
184
- r.raw_add namespace + "/:controller/:action"
185
- r.raw_add namespace + "/:controller\\.:format", :action => 'index'
186
- r.raw_add namespace + "/:controller", :action => 'index'
187
- end
188
- end
189
- end
190
-
191
- class RouteGenerator
192
-
193
- attr_accessor :paths
194
-
195
- def initialize
196
- @paths = {}
197
- end
198
-
199
- def add(name, path)
200
- @paths[name.to_sym] = path
201
- end
202
-
203
- def generate(name, *args)
204
- options = Hash === args.last ? args.pop : {}
205
- obj = args[0]
206
- options.each do |key, value|
207
- next unless value.respond_to?(:to_param)
208
- unless key.to_s =~ /_?id$/
209
- old_key = key
210
- options[old_key] = value.to_param
211
- key = "#{key}_id".intern
212
- end
213
- options[key] = value.to_param
214
- end
215
-
216
- path = @paths[name].dup
217
- while path =~ Router::SECTION_REGEXP
218
- if obj.respond_to?($1) && ! obj.nil?
219
- path.sub!(Router::SECTION_REGEXP, obj.send($1).to_s)
220
- else
221
- path.sub!(Router::SECTION_REGEXP, options[$1.intern].to_s)
222
- end
223
- end
224
- if f = options[:format]
225
- "#{path}.#{f}"
226
- else
227
- path
228
- end
229
- end
230
-
231
- def generate_singleton_routes(res,opt)
232
- res = res.to_s
233
- if opt[:namespace]
234
- namespace = "#{opt[:namespace]}_"
235
- name = "/#{opt[:namespace]}"
236
- else
237
- namespace = ''
238
- name = ''
239
- end
240
- add namespace + "edit_#{res}", name + "#{opt[:prefix]}/#{res}/edit"
241
- add namespace + "new_#{res}", name + "#{opt[:prefix]}/#{res}/new"
242
- add namespace + res, name + "#{opt[:prefix]}/#{res}"
243
- end
244
-
245
- def generate_resources_routes(res,opt)
246
- res = res.to_s
247
- res_singular = res.singularize
248
- if opt[:namespace]
249
- namespace = "#{opt[:namespace]}_"
250
- name = "/#{opt[:namespace]}"
251
- else
252
- namespace = ''
253
- name = ''
254
- end
255
- add namespace + res, name + "#{opt[:prefix]}/#{res}"
256
- add namespace + res_singular, name + "#{opt[:prefix]}/#{res}/:id"
257
- add namespace + "new_#{res_singular}", name + "#{opt[:prefix]}/#{res}/new"
258
- add namespace + "custom_new_#{res_singular}", name + "#{opt[:prefix]}/#{res}/new/:action"
259
- add namespace + "edit_#{res_singular}", name + "#{opt[:prefix]}/#{res}/:id/edit"
260
- if mem = opt[:member]
261
- mem.keys.sort_by{|x| "#{x}"}.each {|action|
262
- add namespace + "#{action}_#{res_singular}", name + "#{opt[:prefix]}/#{res}/:id/#{action}"
263
- }
264
- end
265
- if coll = opt[:collection]
266
- coll.keys.sort_by{|x| "#{x}"}.each {|action|
267
- add namespace + "#{action}_#{res_singular}", name + "#{opt[:prefix]}/#{res}/#{action}"
268
- }
269
- end
270
- end
271
- end
272
-
273
- class Resource
274
-
275
- def initialize(resource, procs=[], opts={})
276
- @resource, @procs, @opts = resource, procs, opts
277
- @procs << proc do
278
- [::Merb::Router.matcher, ::Merb::Router.generator].each {|r| r.generate_resources_routes(@resource, @opts) }
279
- end
280
- end
281
-
282
- def resources(res, opts={})
283
- (opts[:prefix]||='') << "/#{@resource}/:#{@resource.to_s.singularize}_id"
284
-
285
- opts[:prefix] = @opts[:prefix] + opts[:prefix]
286
- if block_given?
287
- yield self.class.new(res, @procs, opts)
288
- else
289
- @procs << proc do
290
- [::Merb::Router.matcher, ::Merb::Router.generator].each {|r| r.generate_resources_routes(res, opts) }
291
- end
292
- end
293
- end
294
-
295
- def resource(res, opts={})
296
- (opts[:prefix]||='') << "/#{@resource}/:#{@resource.to_s.singularize}_id"
297
-
298
- opts[:prefix] = @opts[:prefix] + opts[:prefix]
299
- if block_given?
300
- yield self.class.new(res, @procs, opts)
301
- else
302
- @procs << proc do
303
- [::Merb::Router.matcher, ::Merb::Router.generator].each { |r| r.generate_singleton_routes(res, opts) }
304
- end
305
- end
306
- end
307
- end
308
- end
309
- end