merb 0.5.3 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (294) hide show
  1. data/LICENSE +0 -20
  2. data/README +0 -277
  3. data/Rakefile +80 -199
  4. data/TODO +0 -3
  5. metadata +19 -438
  6. data/SVN_REVISION +0 -1
  7. data/app_generators/merb/USAGE +0 -5
  8. data/app_generators/merb/merb_generator.rb +0 -108
  9. data/app_generators/merb/templates/Rakefile +0 -124
  10. data/app_generators/merb/templates/app/controllers/application.rb +0 -3
  11. data/app_generators/merb/templates/app/controllers/exceptions.rb +0 -13
  12. data/app_generators/merb/templates/app/helpers/global_helper.rb +0 -5
  13. data/app_generators/merb/templates/app/mailers/views/layout/application.html.erb +0 -1
  14. data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +0 -1
  15. data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +0 -1
  16. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +0 -216
  17. data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +0 -38
  18. data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +0 -40
  19. data/app_generators/merb/templates/app/views/layout/application.html.erb +0 -11
  20. data/app_generators/merb/templates/config/boot.rb +0 -11
  21. data/app_generators/merb/templates/config/dependencies.rb +0 -41
  22. data/app_generators/merb/templates/config/environments/development.rb +0 -1
  23. data/app_generators/merb/templates/config/environments/production.rb +0 -1
  24. data/app_generators/merb/templates/config/environments/test.rb +0 -1
  25. data/app_generators/merb/templates/config/merb.yml +0 -82
  26. data/app_generators/merb/templates/config/merb_init.rb +0 -17
  27. data/app_generators/merb/templates/config/plugins.yml +0 -1
  28. data/app_generators/merb/templates/config/router.rb +0 -35
  29. data/app_generators/merb/templates/config/upload.conf +0 -0
  30. data/app_generators/merb/templates/public/images/merb.jpg +0 -0
  31. data/app_generators/merb/templates/public/merb.fcgi +0 -6
  32. data/app_generators/merb/templates/public/stylesheets/master.css +0 -119
  33. data/app_generators/merb/templates/script/destroy +0 -32
  34. data/app_generators/merb/templates/script/generate +0 -32
  35. data/app_generators/merb/templates/script/stop_merb +0 -13
  36. data/app_generators/merb/templates/script/win_script.cmd +0 -1
  37. data/app_generators/merb/templates/spec/spec.opts +0 -6
  38. data/app_generators/merb/templates/spec/spec_helper.rb +0 -15
  39. data/app_generators/merb/templates/test/test_helper.rb +0 -14
  40. data/app_generators/merb_plugin/USAGE +0 -5
  41. data/app_generators/merb_plugin/merb_plugin_generator.rb +0 -68
  42. data/app_generators/merb_plugin/templates/LICENSE +0 -20
  43. data/app_generators/merb_plugin/templates/README +0 -4
  44. data/app_generators/merb_plugin/templates/Rakefile +0 -35
  45. data/app_generators/merb_plugin/templates/TODO +0 -5
  46. data/app_generators/merb_plugin/templates/merbtasks.rb +0 -6
  47. data/app_generators/merb_plugin/templates/sampleplugin.rb +0 -10
  48. data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +0 -7
  49. data/app_generators/merb_plugin/templates/spec_helper.rb +0 -2
  50. data/bin/merb +0 -4
  51. data/lib/autotest/discover.rb +0 -3
  52. data/lib/autotest/merb_rspec.rb +0 -80
  53. data/lib/merb.rb +0 -188
  54. data/lib/merb/abstract_controller.rb +0 -399
  55. data/lib/merb/assets.rb +0 -160
  56. data/lib/merb/assets.rb.orig +0 -119
  57. data/lib/merb/boot_loader.rb +0 -286
  58. data/lib/merb/boot_loader.rb.orig +0 -235
  59. data/lib/merb/caching.rb +0 -5
  60. data/lib/merb/caching/action_cache.rb +0 -92
  61. data/lib/merb/caching/fragment_cache.rb +0 -39
  62. data/lib/merb/caching/store/file_cache.rb +0 -90
  63. data/lib/merb/caching/store/memory_cache.rb +0 -85
  64. data/lib/merb/config.rb +0 -290
  65. data/lib/merb/constants.rb +0 -50
  66. data/lib/merb/controller.rb +0 -220
  67. data/lib/merb/cookies.rb +0 -95
  68. data/lib/merb/core_ext.rb +0 -15
  69. data/lib/merb/core_ext/array.rb +0 -0
  70. data/lib/merb/core_ext/class.rb +0 -180
  71. data/lib/merb/core_ext/enumerable.rb +0 -49
  72. data/lib/merb/core_ext/get_args.rb +0 -76
  73. data/lib/merb/core_ext/hash.rb +0 -306
  74. data/lib/merb/core_ext/inflections.rb +0 -112
  75. data/lib/merb/core_ext/inflector.rb +0 -275
  76. data/lib/merb/core_ext/kernel.rb +0 -242
  77. data/lib/merb/core_ext/mash.rb +0 -88
  78. data/lib/merb/core_ext/module.rb +0 -67
  79. data/lib/merb/core_ext/numeric.rb +0 -72
  80. data/lib/merb/core_ext/object.rb +0 -183
  81. data/lib/merb/core_ext/string.rb +0 -53
  82. data/lib/merb/core_ext/symbol.rb +0 -6
  83. data/lib/merb/dispatcher.rb +0 -109
  84. data/lib/merb/drb_server.rb +0 -19
  85. data/lib/merb/erubis_ext.rb +0 -10
  86. data/lib/merb/exceptions.rb +0 -192
  87. data/lib/merb/generators/merb_app/merb_app.rb +0 -22
  88. data/lib/merb/generators/merb_generator_helpers.rb +0 -318
  89. data/lib/merb/generators/merb_plugin.rb +0 -22
  90. data/lib/merb/logger.rb +0 -78
  91. data/lib/merb/mail_controller.rb +0 -268
  92. data/lib/merb/mailer.rb +0 -87
  93. data/lib/merb/mixins/basic_authentication.rb +0 -35
  94. data/lib/merb/mixins/controller.rb +0 -160
  95. data/lib/merb/mixins/erubis_capture.rb +0 -68
  96. data/lib/merb/mixins/general_controller.rb +0 -253
  97. data/lib/merb/mixins/inline_partial.rb +0 -32
  98. data/lib/merb/mixins/render.rb +0 -465
  99. data/lib/merb/mixins/responder.rb +0 -449
  100. data/lib/merb/mixins/view_context.rb +0 -558
  101. data/lib/merb/mixins/web_controller.rb +0 -36
  102. data/lib/merb/mongrel_handler.rb +0 -168
  103. data/lib/merb/part_controller.rb +0 -29
  104. data/lib/merb/plugins.rb +0 -16
  105. data/lib/merb/rack_adapter.rb +0 -37
  106. data/lib/merb/request.rb +0 -465
  107. data/lib/merb/router.rb +0 -646
  108. data/lib/merb/server.rb +0 -169
  109. data/lib/merb/session.rb +0 -23
  110. data/lib/merb/session/cookie_store.rb +0 -118
  111. data/lib/merb/session/mem_cache_session.rb +0 -131
  112. data/lib/merb/session/memory_session.rb +0 -176
  113. data/lib/merb/template.rb +0 -37
  114. data/lib/merb/template/erubis.rb +0 -68
  115. data/lib/merb/template/haml.rb +0 -87
  116. data/lib/merb/template/markaby.rb +0 -59
  117. data/lib/merb/template/xml_builder.rb +0 -50
  118. data/lib/merb/test/fake_request.rb +0 -74
  119. data/lib/merb/test/helper.rb +0 -260
  120. data/lib/merb/test/hpricot.rb +0 -136
  121. data/lib/merb/test/multipart.rb +0 -66
  122. data/lib/merb/test/rspec.rb +0 -18
  123. data/lib/merb/test/rspec_matchers/controller_matchers.rb +0 -117
  124. data/lib/merb/test/rspec_matchers/markup_matchers.rb +0 -98
  125. data/lib/merb/upload_handler.rb +0 -80
  126. data/lib/merb/upload_progress.rb +0 -48
  127. data/lib/merb/version.rb +0 -49
  128. data/lib/merb/view_context.rb +0 -79
  129. data/lib/tasks.rb +0 -7
  130. data/lib/tasks/merb.rake +0 -54
  131. data/merb_default_generators/model/USAGE +0 -0
  132. data/merb_default_generators/model/model_generator.rb +0 -16
  133. data/merb_default_generators/model/templates/new_model_template.erb +0 -5
  134. data/merb_default_generators/resource_controller/USAGE +0 -0
  135. data/merb_default_generators/resource_controller/resource_controller_generator.rb +0 -26
  136. data/merb_default_generators/resource_controller/templates/controller.rb +0 -30
  137. data/merb_default_generators/resource_controller/templates/edit.html.erb +0 -1
  138. data/merb_default_generators/resource_controller/templates/helper.rb +0 -5
  139. data/merb_default_generators/resource_controller/templates/index.html.erb +0 -1
  140. data/merb_default_generators/resource_controller/templates/new.html.erb +0 -1
  141. data/merb_default_generators/resource_controller/templates/show.html.erb +0 -1
  142. data/merb_generators/controller/USAGE +0 -5
  143. data/merb_generators/controller/controller_generator.rb +0 -16
  144. data/merb_generators/controller/templates/controller.rb +0 -8
  145. data/merb_generators/controller/templates/helper.rb +0 -5
  146. data/merb_generators/controller/templates/index.html.erb +0 -3
  147. data/merb_generators/part_controller/USAGE +0 -5
  148. data/merb_generators/part_controller/part_controller_generator.rb +0 -27
  149. data/merb_generators/part_controller/templates/controller.rb +0 -8
  150. data/merb_generators/part_controller/templates/helper.rb +0 -5
  151. data/merb_generators/part_controller/templates/index.html.erb +0 -3
  152. data/merb_generators/resource/USAGE +0 -0
  153. data/merb_generators/resource/resource_generator.rb +0 -67
  154. data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +0 -67
  155. data/rspec_generators/merb_controller_test/templates/controller_spec.rb +0 -8
  156. data/rspec_generators/merb_controller_test/templates/edit_spec.rb +0 -12
  157. data/rspec_generators/merb_controller_test/templates/helper_spec.rb +0 -5
  158. data/rspec_generators/merb_controller_test/templates/index_spec.rb +0 -12
  159. data/rspec_generators/merb_controller_test/templates/new_spec.rb +0 -12
  160. data/rspec_generators/merb_controller_test/templates/show_spec.rb +0 -5
  161. data/rspec_generators/merb_model_test/merb_model_test_generator.rb +0 -26
  162. data/rspec_generators/merb_model_test/templates/model_spec_template.erb +0 -7
  163. data/script/destroy +0 -14
  164. data/script/generate +0 -14
  165. data/spec/fixtures/config/environments/environment_config_test.yml +0 -1
  166. data/spec/fixtures/config/merb.yml +0 -18
  167. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +0 -235
  168. data/spec/fixtures/controllers/render_spec_controllers.rb +0 -184
  169. data/spec/fixtures/foo.rb +0 -3
  170. data/spec/fixtures/mailers/views/layout/application.html.erb +0 -3
  171. data/spec/fixtures/mailers/views/layout/application.text.erb +0 -3
  172. data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +0 -1
  173. data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +0 -1
  174. data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +0 -1
  175. data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +0 -1
  176. data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +0 -1
  177. data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +0 -1
  178. data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +0 -1
  179. data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +0 -1
  180. data/spec/fixtures/models/router_spec_models.rb +0 -30
  181. data/spec/fixtures/parts/views/layout/todo_part.html.erb +0 -3
  182. data/spec/fixtures/parts/views/layout/todo_part.xml.erb +0 -3
  183. data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +0 -1
  184. data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +0 -1
  185. data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +0 -1
  186. data/spec/fixtures/parts/views/todo_part/list.html.erb +0 -3
  187. data/spec/fixtures/sample.txt +0 -1
  188. data/spec/fixtures/views/erubis.html.erb +0 -1
  189. data/spec/fixtures/views/examples/_erubis.html.erb +0 -1
  190. data/spec/fixtures/views/examples/_haml.html.haml +0 -1
  191. data/spec/fixtures/views/examples/_markaby.html.mab +0 -1
  192. data/spec/fixtures/views/examples/_throw_content.html.erb +0 -6
  193. data/spec/fixtures/views/examples/hello.xml.builder +0 -1
  194. data/spec/fixtures/views/examples/js.js.erb +0 -1
  195. data/spec/fixtures/views/examples/template_catch_content.html.erb +0 -15
  196. data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +0 -6
  197. data/spec/fixtures/views/examples/template_throw_content.html.erb +0 -10
  198. data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +0 -3
  199. data/spec/fixtures/views/exceptions/admin_access_required.html.erb +0 -1
  200. data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +0 -1
  201. data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +0 -1
  202. data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +0 -1
  203. data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +0 -1
  204. data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +0 -1
  205. data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +0 -1
  206. data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +0 -1
  207. data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
  208. data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +0 -1
  209. data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +0 -1
  210. data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +0 -1
  211. data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
  212. data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
  213. data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +0 -1
  214. data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +0 -1
  215. data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +0 -1
  216. data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +0 -4
  217. data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +0 -1
  218. data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +0 -1
  219. data/spec/fixtures/views/haml.html.haml +0 -1
  220. data/spec/fixtures/views/haml.xml.haml +0 -2
  221. data/spec/fixtures/views/layout/application.html.erb +0 -1
  222. data/spec/fixtures/views/layout/application.xml.erb +0 -1
  223. data/spec/fixtures/views/layout/nested/example.html.erb +0 -1
  224. data/spec/fixtures/views/markaby.html.mab +0 -1
  225. data/spec/fixtures/views/nested/example/test.html.erb +0 -1
  226. data/spec/fixtures/views/partials/_erubis.html.erb +0 -1
  227. data/spec/fixtures/views/partials/_erubis_collection.html.erb +0 -1
  228. data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +0 -1
  229. data/spec/fixtures/views/partials/_erubis_new.html.erb +0 -1
  230. data/spec/fixtures/views/partials/_haml.html.haml +0 -1
  231. data/spec/fixtures/views/partials/_haml_collection.html.haml +0 -1
  232. data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +0 -1
  233. data/spec/fixtures/views/partials/_haml_new.html.haml +0 -1
  234. data/spec/fixtures/views/partials/_markaby.html.mab +0 -1
  235. data/spec/fixtures/views/partials/_markaby_collection.html.mab +0 -1
  236. data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +0 -1
  237. data/spec/fixtures/views/partials/_markaby_new.html.mab +0 -1
  238. data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +0 -1
  239. data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +0 -1
  240. data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +0 -1
  241. data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +0 -4
  242. data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +0 -7
  243. data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +0 -7
  244. data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +0 -15
  245. data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +0 -15
  246. data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +0 -4
  247. data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +0 -12
  248. data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +0 -11
  249. data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +0 -14
  250. data/spec/fixtures/views/test.dir/the_template.html.erb +0 -1
  251. data/spec/merb/abstract_controller_spec.rb +0 -38
  252. data/spec/merb/assets_spec.rb +0 -207
  253. data/spec/merb/caching_spec.rb +0 -102
  254. data/spec/merb/config_spec.rb +0 -29
  255. data/spec/merb/controller_filters_spec.rb +0 -253
  256. data/spec/merb/controller_spec.rb +0 -126
  257. data/spec/merb/cookie_store_spec.rb +0 -72
  258. data/spec/merb/cookies_spec.rb +0 -96
  259. data/spec/merb/core_ext/class_spec.rb +0 -97
  260. data/spec/merb/core_ext/enumerable_spec.rb +0 -27
  261. data/spec/merb/core_ext/hash_spec.rb +0 -251
  262. data/spec/merb/core_ext/inflector_spec.rb +0 -34
  263. data/spec/merb/core_ext/kernel_spec.rb +0 -25
  264. data/spec/merb/core_ext/numeric_spec.rb +0 -26
  265. data/spec/merb/core_ext/object_spec.rb +0 -47
  266. data/spec/merb/core_ext/string_spec.rb +0 -22
  267. data/spec/merb/core_ext/symbol_spec.rb +0 -7
  268. data/spec/merb/dependency_spec.rb +0 -22
  269. data/spec/merb/dispatch_spec.rb +0 -528
  270. data/spec/merb/fake_request_spec.rb +0 -80
  271. data/spec/merb/generator_spec.rb +0 -248
  272. data/spec/merb/handler_spec.rb +0 -169
  273. data/spec/merb/mail_controller_spec.rb +0 -177
  274. data/spec/merb/mailer_spec.rb +0 -87
  275. data/spec/merb/multipart_spec.rb +0 -50
  276. data/spec/merb/part_controller_spec.rb +0 -124
  277. data/spec/merb/plugins_spec.rb +0 -80
  278. data/spec/merb/render_spec.rb +0 -469
  279. data/spec/merb/request_spec.rb +0 -287
  280. data/spec/merb/responder_spec.rb +0 -562
  281. data/spec/merb/router_spec.rb +0 -900
  282. data/spec/merb/server_spec.rb +0 -19
  283. data/spec/merb/template_spec.rb +0 -41
  284. data/spec/merb/upload_handler_spec.rb +0 -108
  285. data/spec/merb/version_spec.rb +0 -33
  286. data/spec/merb/view_context_spec.rb +0 -366
  287. data/spec/spec_generator_helper.rb +0 -34
  288. data/spec/spec_helper.rb +0 -101
  289. data/spec/spec_helpers/url_shared_behaviour.rb +0 -112
  290. data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +0 -53
  291. data/test_unit_generators/merb_controller_test/templates/functional_test.rb +0 -17
  292. data/test_unit_generators/merb_controller_test/templates/helper_test.rb +0 -9
  293. data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +0 -29
  294. data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +0 -9
data/lib/merb/router.rb DELETED
@@ -1,646 +0,0 @@
1
- module Merb
2
- class Router
3
- SEGMENT_REGEXP = /(:([a-z_][a-z0-9_]*|:))/
4
- SEGMENT_REGEXP_WITH_BRACKETS = /(:[a-z_]+)(\[(\d+)\])?/
5
- JUST_BRACKETS = /\[(\d+)\]/
6
- PARENTHETICAL_SEGMENT_STRING = "([^\/.,;?]+)".freeze
7
-
8
- @@named_routes = {}
9
- @@routes = []
10
- cattr_accessor :routes, :named_routes
11
-
12
- class << self
13
- def append(&block)
14
- prepare(@@routes, [], &block)
15
- end
16
-
17
- def prepend(&block)
18
- prepare([], @@routes, &block)
19
- end
20
-
21
- def prepare(first = [], last = [], &block)
22
- @@routes = []
23
- yield Behavior.new({}, { :action => 'index' }) # defaults
24
- @@routes = first + @@routes + last
25
- compile
26
- end
27
-
28
- def compiled_statement
29
- @@compiled_statement = "lambda { |request, params|\n"
30
- @@compiled_statement << " cached_path = request.path\n cached_method = request.method.to_s\n "
31
- # @@compiled_statement << " puts cached_path.inspect; puts cached_method.inspect\n"
32
- @@routes.each_with_index { |route, i| @@compiled_statement << route.compile(i == 0) }
33
- @@compiled_statement << " else\n [nil, {}]\n"
34
- @@compiled_statement << " end\n"
35
- @@compiled_statement << "}"
36
- end
37
-
38
- def compile
39
- meta_def(:match, &eval(compiled_statement))
40
- end
41
-
42
- def generate(name, params = {}, fallback = {})
43
- name = name.to_sym
44
- unless @@named_routes.key? name
45
- raise "Named route not found: #{name}"
46
- else
47
- @@named_routes[name].generate(params, fallback)
48
- end
49
- end
50
- end # self
51
-
52
- # Cache procs for future reference in eval statement
53
- class CachedProc
54
- @@index = 0
55
- @@list = []
56
-
57
- attr_accessor :cache, :index
58
-
59
- def initialize(cache)
60
- @cache, @index = cache, CachedProc.register(self)
61
- end
62
-
63
- # Make each CachedProc object embeddable within a string
64
- def to_s
65
- "CachedProc[#{@index}].cache"
66
- end
67
-
68
- class << self
69
- def register(cached_code)
70
- CachedProc[@@index] = cached_code
71
- @@index += 1
72
- @@index - 1
73
- end
74
- def []=(index, code) @@list[index] = code end
75
- def [](index) @@list[index] end
76
- end
77
- end # CachedProc
78
-
79
- class Route
80
- attr_reader :conditions, :conditional_block
81
- attr_reader :params, :behavior, :segments, :index, :symbol
82
-
83
- def initialize(conditions, params, behavior = nil, &conditional_block)
84
- @conditions, @params, @behavior = conditions, params, behavior
85
- @conditional_block = conditional_block
86
- if @behavior && (path = @behavior.merged_original_conditions[:path])
87
- @segments = segments_from_path(path)
88
- end
89
- end
90
-
91
- def to_s
92
- segments.inject('') do |str,seg|
93
- str << (seg.is_a?(Symbol) ? ":#{seg}" : seg)
94
- end
95
- end
96
-
97
- # Registers itself in the Router.routes array
98
- def register
99
- @index = Router.routes.size
100
- Router.routes << self
101
- self
102
- end
103
-
104
- # Get the symbols out of the segments array
105
- def symbol_segments
106
- segments.select{ |s| s.is_a?(Symbol) }
107
- end
108
-
109
- # Turn a path into string and symbol segments so it can be reconstructed, as in the
110
- # case of a named route.
111
- def segments_from_path(path)
112
- # Remove leading ^ and trailing $ from each segment (left-overs from regexp joining)
113
- strip = proc { |str| str.gsub(/^\^/, '').gsub(/\$$/, '') }
114
- segments = []
115
- while match = (path.match(SEGMENT_REGEXP))
116
- segments << strip[match.pre_match] unless match.pre_match.empty?
117
- segments << match[2].intern
118
- path = strip[match.post_match]
119
- end
120
- segments << strip[path] unless path.empty?
121
- segments
122
- end
123
-
124
- # Name this route
125
- def name(symbol = nil)
126
- raise ArgumentError unless (@symbol = symbol).is_a?(Symbol)
127
- Router.named_routes[@symbol] = self
128
- end
129
-
130
- def regexp?
131
- behavior.regexp? || behavior.send(:ancestors).any? { |a| a.regexp? }
132
- end
133
-
134
- # Given a hash of +params+, returns a string using the stored route segments
135
- # for reconstruction of the URL.
136
- def generate(params = {}, fallback = {})
137
- url = @segments.map do |segment|
138
- value =
139
- if segment.is_a? Symbol
140
- if params.is_a? Hash
141
- params[segment] || fallback[segment]
142
- else
143
- if segment == :id && params.respond_to?(:to_param)
144
- params.to_param
145
- elsif params.respond_to?(segment)
146
- params.send(segment)
147
- else
148
- fallback[segment]
149
- end
150
- end
151
- elsif segment.respond_to? :to_s
152
- segment
153
- else
154
- raise "Segment type '#{segment.class}' can't be converted to a string"
155
- end
156
- (value.respond_to?(:to_param) ? value.to_param : value).to_s
157
- end.join
158
- end
159
-
160
- def if_conditions(params_as_string)
161
- cond = []
162
- condition_string = proc do |key, value, regexp_string|
163
- max = Behavior.count_parens_up_to(value.source, value.source.size)
164
- captures = if max == 0 then "" else
165
- " && (" +
166
- (1..max).to_a.map{ |n| "#{key}#{n}" }.join(", ") + " = " +
167
- (1..max).to_a.map{ |n| "$#{n}"}.join(", ") +
168
- ")"
169
- end
170
- " (#{value.inspect} =~ #{regexp_string}" + captures + ")"
171
- end
172
- @conditions.each_pair do |key, value|
173
-
174
- # Note: =~ is slightly faster than .match
175
- cond << case key
176
- when :path then condition_string[key, value, "cached_path"]
177
- when :method then condition_string[key, value, "cached_method"]
178
- else condition_string[key, value, "request.#{key}.to_s"]
179
- end
180
- end
181
- if @conditional_block
182
- str = " # #{@conditional_block.inspect.scan(/@([^>]+)/).flatten.first}\n"
183
- str << " (block_result = #{CachedProc.new(@conditional_block)}.call(request, params.merge({#{params_as_string}})))" if @conditional_block
184
- cond << str
185
- end
186
- cond
187
- end
188
-
189
- def compile(first = false)
190
- code = ""
191
- default_params = { :action => "index" }
192
- get_value = proc do |key|
193
- if default_params.has_key?(key) && params[key][0] != ?"
194
- "#{params[key]} || \"#{default_params[key]}\""
195
- else
196
- "#{params[key]}"
197
- end
198
- end
199
- params_as_string = params.keys.map { |k| "#{k.inspect} => #{get_value[k]}" }.join(', ')
200
- code << " els" unless first
201
- code << "if # #{@behavior.merged_original_conditions.inspect}\n "
202
- code << if_conditions(params_as_string).join(" &&\n ") << "\n"
203
- code << " # then\n"
204
- if @conditional_block
205
- code << " [#{@index.inspect}, block_result]\n"
206
- else
207
- code << " [#{@index.inspect}, {#{params_as_string}}]\n"
208
- end
209
- end
210
-
211
- def behavior_trace
212
- if @behavior
213
- puts @behavior.send(:ancestors).reverse.map{|a| a.inspect}.join("\n"); puts @behavior.inspect; puts
214
- else
215
- puts "No behavior to trace #{self}"
216
- end
217
- end
218
- end # Route
219
-
220
- # The Behavior class is an interim route-building class that ties
221
- # pattern-matching +conditions+ to output parameters, +params+.
222
- class Behavior
223
- attr_reader :placeholders, :conditions, :params
224
- attr_accessor :parent
225
-
226
- class << self
227
- # Count the number of open parentheses in +string+, up to and including +pos+
228
- def count_parens_up_to(string, pos)
229
- string[0..pos].gsub(/[^\(]/, '').size
230
- end
231
-
232
- # Concatenate strings and remove regexp end caps
233
- def concat_without_endcaps(string1, string2)
234
- return nil if !string1 and !string2
235
- return string1 if string2.nil?
236
- return string2 if string1.nil?
237
- s1 = string1[-1] == ?$ ? string1[0..-2] : string1
238
- s2 = string2[0] == ?^ ? string2[1..-1] : string2
239
- s1 + s2
240
- end
241
-
242
- # Join an array's elements into a string using " + " as a joiner, and
243
- # surround string elements in quotes.
244
- def array_to_code(arr)
245
- code = ''
246
- arr.each_with_index do |part, i|
247
- code << ' + ' if i > 0
248
- case part
249
- when Symbol
250
- code << part.to_s
251
- when String
252
- code << %{"#{part}"}
253
- else
254
- raise "Don't know how to compile array part: #{part.class} [#{i}]"
255
- end
256
- end
257
- code
258
- end
259
- end # class << self
260
-
261
- def initialize(conditions = {}, params = {}, parent = nil)
262
- # Must wait until after deducing placeholders to set @params !
263
- @conditions, @params, @parent = conditions, {}, parent
264
- @placeholders = {}
265
- stringify_conditions
266
- copy_original_conditions
267
- deduce_placeholders
268
- @params.merge! params
269
- end
270
-
271
- def add(path, params = {})
272
- match(path).to(params)
273
- end
274
-
275
- # Matches a +path+ and any number of optional request methods as conditions of a route.
276
- # Alternatively, +path+ can be a hash of conditions, in which case +conditions+ is ignored.
277
- # Yields a new instance so that sub-matching may occur.
278
- def match(path = '', conditions = {}, &block)
279
- if path.is_a? Hash
280
- conditions = path
281
- else
282
- conditions[:path] = path
283
- end
284
- match_without_path(conditions, &block)
285
- end
286
-
287
- def match_without_path(conditions = {})
288
- new_behavior = self.class.new(conditions, {}, self)
289
- conditions.delete :path if ['', '^$'].include?(conditions[:path])
290
- yield new_behavior if block_given?
291
- new_behavior
292
- end
293
-
294
- def to_route(params = {}, &conditional_block)
295
- @params.merge! params
296
- Route.new compiled_conditions, compiled_params, self, &conditional_block
297
- end
298
-
299
- # Creates a Route from one or more Behavior objects, unless a +block+ is passed in.
300
- # If a block is passed in, a Behavior object is yielded and further .to operations
301
- # may be called in the block. For example:
302
- #
303
- # r.match('/:controller/:id).to(:action => 'show')
304
- #
305
- # vs.
306
- #
307
- # r.to :controller => 'simple' do |s|
308
- # s.match('/test').to(:action => 'index')
309
- # s.match('/other').to(:action => 'other')
310
- # end
311
- #
312
- def to(params = {}, &block)
313
- if block_given?
314
- new_behavior = self.class.new({}, params, self)
315
- yield new_behavior if block_given?
316
- new_behavior
317
- else
318
- to_route(params).register
319
- end
320
- end
321
-
322
- # Takes a block and stores it for defered conditional routes.
323
- # The block takes the +request+ object and the +params+ hash as parameters
324
- # and should return a hash of params.
325
- #
326
- # r.defer_to do |request, params|
327
- # params.merge :controller => 'here', :action => 'there'
328
- # end
329
- #
330
- def defer_to(params = {}, &conditional_block)
331
- Router.routes << (route = to_route(params, &conditional_block))
332
- route
333
- end
334
-
335
- def default_routes(params = {}, &block)
336
- match(%r{/:controller(/:action(/:id)?)?(\.:format)?}).to(params, &block)
337
- end
338
-
339
- def namespace(name_or_path, &block)
340
- yield self.class.new(:namespace => name_or_path.to_s)
341
- end
342
-
343
- def resources(name, options = {})
344
- namespace = options[:namespace] || merged_params[:namespace] || conditions[:namespace]
345
-
346
- match_path = namespace ? "/#{namespace}/#{name}" : "/#{name}"
347
-
348
- next_level = match match_path
349
-
350
- name_prefix = options.delete :name_prefix
351
-
352
- if name_prefix.nil? && !namespace.nil?
353
- name_prefix = namespace_to_name_prefix namespace
354
- end
355
-
356
- options[:controller] ||= merged_params[:controller] || name.to_s
357
-
358
- singular = name.to_s.singularize
359
-
360
- route_plural_name = "#{name_prefix}#{name}"
361
- route_singular_name = "#{name_prefix}#{singular}"
362
-
363
- behaviors = []
364
-
365
- if member = options.delete(:member)
366
- member.each_pair do |action, methods|
367
- behaviors << Behavior.new(
368
- { :path => %r{^/:id[/;]#{action}(\.:format)?$}, :method => /^(#{[methods].flatten * '|'})$/ },
369
- { :action => action.to_s }, next_level
370
- )
371
- next_level.match("/:id/#{action}").to_route.name(:"#{action}_#{route_singular_name}")
372
- end
373
- end
374
-
375
- if collection = options.delete(:collection)
376
- collection.each_pair do |action, methods|
377
- behaviors << Behavior.new(
378
- { :path => %r{^[/;]#{action}(\.:format)?$}, :method => /^(#{[methods].flatten * '|'})$/ },
379
- { :action => action.to_s }, next_level
380
- )
381
- next_level.match("/#{action}").to_route.name(:"#{action}_#{route_plural_name}")
382
- end
383
- end
384
-
385
- routes = many_behaviors_to(behaviors + next_level.send(:resources_behaviors), options)
386
-
387
- # Add names to some routes
388
- [['', :"#{route_plural_name}"],
389
- ['/:id', :"#{route_singular_name}"],
390
- ['/new', :"new_#{route_singular_name}"],
391
- ['/:id/edit', :"edit_#{route_singular_name}"],
392
- ['/:action/:id', :"custom_#{route_singular_name}"]
393
- ].each do |path,name|
394
- next_level.match(path).to_route.name(name)
395
- end
396
-
397
- yield next_level.match("/:#{singular}_id") if block_given?
398
-
399
- routes
400
- end
401
-
402
- def resource(name, options = {})
403
- namespace = options[:namespace] || merged_params[:namespace] || conditions[:namespace]
404
- match_path = namespace ? "/#{namespace}/#{name}" : "/#{name}"
405
- next_level = match match_path
406
-
407
- options[:controller] ||= merged_params[:controller] || name.to_s
408
-
409
- # Do not pass :name_prefix option on to to_resource
410
- name_prefix = options.delete :name_prefix
411
-
412
- if name_prefix.nil? && !namespace.nil?
413
- name_prefix = namespace_to_name_prefix namespace
414
- end
415
-
416
- routes = next_level.to_resource options
417
-
418
- route_name = "#{name_prefix}#{name}"
419
-
420
- next_level.match('').to_route.name(:"#{route_name}")
421
- next_level.match('/new').to_route.name(:"new_#{route_name}")
422
- next_level.match('/edit').to_route.name(:"edit_#{route_name}")
423
-
424
- yield next_level if block_given?
425
-
426
- routes
427
- end
428
-
429
- def to_resources(params = {}, &block)
430
- many_behaviors_to resources_behaviors, params, &block
431
- end
432
-
433
- def to_resource(params = {}, &block)
434
- many_behaviors_to resource_behaviors, params, &block
435
- end
436
-
437
- def merged_original_conditions
438
- if parent.nil?
439
- @original_conditions
440
- else
441
- merged_so_far = parent.merged_original_conditions
442
- if path = Behavior.concat_without_endcaps(merged_so_far[:path], @original_conditions[:path])
443
- merged_so_far.merge(@original_conditions).merge(:path => path)
444
- else
445
- merged_so_far.merge(@original_conditions)
446
- end
447
- end
448
- end
449
-
450
- def merged_conditions
451
- if parent.nil?
452
- @conditions
453
- else
454
- merged_so_far = parent.merged_conditions
455
- if path = Behavior.concat_without_endcaps(merged_so_far[:path], @conditions[:path])
456
- merged_so_far.merge(@conditions).merge(:path => path)
457
- else
458
- merged_so_far.merge(@conditions)
459
- end
460
- end
461
- end
462
-
463
- def merged_params
464
- if parent.nil?
465
- @params
466
- else
467
- parent.merged_params.merge(@params)
468
- end
469
- end
470
-
471
- def merged_placeholders
472
- placeholders = {}
473
- (ancestors.reverse + [self]).each do |a|
474
- a.placeholders.each_pair do |k, pair|
475
- param, place = pair
476
- placeholders[k] = [param, place + (param == :path ? a.total_previous_captures : 0)]
477
- end
478
- end
479
- placeholders
480
- end
481
-
482
- def inspect
483
- "[captures: #{path_captures.inspect}, conditions: #{@original_conditions.inspect}, params: #{@params.inspect}, placeholders: #{@placeholders.inspect}]"
484
- end
485
-
486
- def regexp?
487
- @conditions_have_regexp
488
- end
489
-
490
- protected
491
- def namespace_to_name_prefix(name_or_path)
492
- name_or_path.to_s.tr('/', '_') + '_'
493
- end
494
-
495
- def resources_behaviors(parent = self)
496
- [
497
- Behavior.new({ :path => %r[^/?(\.:format)?$], :method => :get }, { :action => "index" }, parent),
498
- Behavior.new({ :path => %r[^/index(\.:format)?$], :method => :get }, { :action => "index" }, parent),
499
- Behavior.new({ :path => %r[^/new$], :method => :get }, { :action => "new" }, parent),
500
- Behavior.new({ :path => %r[^/?(\.:format)?$], :method => :post }, { :action => "create" }, parent),
501
- Behavior.new({ :path => %r[^/:id(\.:format)?$], :method => :get }, { :action => "show" }, parent),
502
- Behavior.new({ :path => %r[^/:id[;/]edit$], :method => :get }, { :action => "edit" }, parent),
503
- Behavior.new({ :path => %r[^/:id(\.:format)?$], :method => :put }, { :action => "update" }, parent),
504
- Behavior.new({ :path => %r[^/:id(\.:format)?$], :method => :delete }, { :action => "destroy" }, parent)
505
- ]
506
- end
507
-
508
- def resource_behaviors(parent = self)
509
- [
510
- Behavior.new({ :path => %r{^[;/]new$}, :method => :get }, { :action => "new" }, parent),
511
- Behavior.new({ :path => %r{^/?(\.:format)?$}, :method => :post }, { :action => "create" }, parent),
512
- Behavior.new({ :path => %r{^/?(\.:format)?$}, :method => :get }, { :action => "show" }, parent),
513
- Behavior.new({ :path => %r{^[;/]edit$}, :method => :get }, { :action => "edit" }, parent),
514
- Behavior.new({ :path => %r{^/?(\.:format)?$}, :method => :put }, { :action => "update" }, parent),
515
- Behavior.new({ :path => %r{^/?(\.:format)?$}, :method => :delete }, { :action => "destroy" }, parent)
516
- ]
517
- end
518
-
519
- # Creates a series of routes from an array of Behavior objects.
520
- # You can pass in optional +params+, and an optional block that will be
521
- # passed along to the #to method.
522
- def many_behaviors_to(behaviors, params = {}, &conditional_block)
523
- behaviors.map { |b| b.to params, &conditional_block }
524
- end
525
-
526
- # Convert conditions to regular expression string sources for consistency
527
- def stringify_conditions
528
- @conditions_have_regexp = false
529
- @conditions.each_pair do |k,v|
530
- # TODO: Other Regexp special chars
531
-
532
- @conditions[k] = case v
533
- when String,Symbol
534
- if k == :namespace
535
- v.to_s
536
- else
537
- "^#{v.to_s.escape_regexp}$"
538
- end
539
- when Regexp
540
- @conditions_have_regexp = true
541
- v.source
542
- end
543
- end
544
- end
545
-
546
- def copy_original_conditions
547
- @original_conditions = {}
548
- @conditions.each_pair do |key, value|
549
- @original_conditions[key] = value.dup
550
- end
551
- @original_conditions
552
- end
553
-
554
- def deduce_placeholders
555
- @conditions.each_pair do |match_key, source|
556
- while match = SEGMENT_REGEXP.match(source)
557
- source.sub! SEGMENT_REGEXP, PARENTHETICAL_SEGMENT_STRING
558
- unless match[2] == ':' # No need to store anonymous place holders
559
- placeholder_key = match[2].intern
560
- @params[placeholder_key] = "#{match[1]}"
561
- @placeholders[placeholder_key] = [
562
- match_key, Behavior.count_parens_up_to(source, match.offset(1)[0])
563
- ]
564
- end
565
- end
566
- end
567
- end
568
-
569
- def ancestors(list = [])
570
- if parent.nil?
571
- list
572
- else
573
- list.push parent
574
- parent.ancestors list
575
- list
576
- end
577
- end
578
-
579
- # Count the number of regexp captures in the :path condition
580
- def path_captures
581
- return 0 unless conditions[:path]
582
- Behavior.count_parens_up_to(conditions[:path], conditions[:path].size)
583
- end
584
-
585
- def total_previous_captures
586
- ancestors.map{|a| a.path_captures}.inject(0){|sum, n| sum + n}
587
- end
588
-
589
- # def merge_with_ancestors
590
- # self.class.new(merged_conditions, merged_params)
591
- # end
592
-
593
- def compiled_conditions(conditions = merged_conditions)
594
- conditions.inject({}) do |compiled,(k,v)|
595
- compiled.merge k => Regexp.new(v)
596
- end
597
- end
598
-
599
- # Compiles the params hash into 'eval'-able form.
600
- #
601
- # @params = {:controller => "admin/:controller"}
602
- #
603
- # Could become:
604
- #
605
- # { :controller => "'admin/' + matches[:path][1]" }
606
- #
607
- def compiled_params(params = merged_params, placeholders = merged_placeholders)
608
- compiled = {}
609
- params.each_pair do |key, value|
610
- unless value.is_a? String
611
- raise ArgumentError, "param value must be string (#{value.inspect})"
612
- end
613
- result = []
614
- value = value.dup
615
- match = true
616
- while match
617
- if match = SEGMENT_REGEXP_WITH_BRACKETS.match(value)
618
- result << match.pre_match unless match.pre_match.empty?
619
- ph_key = match[1][1..-1].intern
620
- if match[2] # has brackets, e.g. :path[2]
621
- result << :"#{ph_key}#{match[3]}"
622
- else # no brackets, e.g. a named placeholder such as :controller
623
- if place = placeholders[ph_key]
624
- result << :"#{place[0]}#{place[1]}"
625
- else
626
- raise "Placeholder not found while compiling routes: :#{ph_key}"
627
- end
628
- end
629
- value = match.post_match
630
- elsif match = JUST_BRACKETS.match(value)
631
- # This is a reference to :path
632
- result << match.pre_match unless match.pre_match.empty?
633
- result << :"path#{match[1]}"
634
- value = match.post_match
635
- else
636
- result << value unless value.empty?
637
- end
638
- end
639
- compiled[key] = Behavior.array_to_code(result).gsub("\\_", "_")
640
- end
641
- compiled
642
- end
643
- end # Behavior
644
-
645
- end
646
- end