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