Permalink
Browse files

Merge commit 'mainstream/master'

Conflicts:
	actionpack/lib/action_controller/base.rb
	railties/guides/source/caching_with_rails.textile
  • Loading branch information...
2 parents f99e9f6 + abb899c commit 20401783cf26f903d7020cb7136b1e78e60e71ea lifo committed Apr 17, 2009
Showing with 5,892 additions and 2,418 deletions.
  1. +1 −0 .gitignore
  2. +42 −23 actionmailer/lib/action_mailer/base.rb
  3. +0 −1 actionmailer/test/abstract_unit.rb
  4. +22 −4 actionmailer/test/mail_service_test.rb
  5. +7 −0 actionpack/CHANGELOG
  6. +1 −1 actionpack/Rakefile
  7. +37 −64 actionpack/lib/action_controller.rb
  8. +10 −0 actionpack/lib/action_controller/abstract.rb
  9. +41 −0 actionpack/lib/action_controller/abstract/base.rb
  10. +40 −0 actionpack/lib/action_controller/abstract/callbacks.rb
  11. +3 −0 actionpack/lib/action_controller/abstract/exceptions.rb
  12. +59 −0 actionpack/lib/action_controller/abstract/helpers.rb
  13. +82 −0 actionpack/lib/action_controller/abstract/layouts.rb
  14. +7 −0 actionpack/lib/action_controller/abstract/logger.rb
  15. +58 −0 actionpack/lib/action_controller/abstract/renderer.rb
  16. +40 −520 actionpack/lib/action_controller/{ → base}/base.rb
  17. +1 −1 actionpack/lib/action_controller/{ → base/chained}/benchmarking.rb
  18. 0 actionpack/lib/action_controller/{ → base/chained}/filters.rb
  19. 0 actionpack/lib/action_controller/{ → base/chained}/flash.rb
  20. 0 actionpack/lib/action_controller/{ → base}/cookies.rb
  21. 0 actionpack/lib/action_controller/{ → base}/helpers.rb
  22. 0 actionpack/lib/action_controller/{ → base}/http_authentication.rb
  23. +60 −94 actionpack/lib/action_controller/{ → base}/layout.rb
  24. +3 −6 actionpack/lib/action_controller/{ → base}/mime_responds.rb
  25. +91 −0 actionpack/lib/action_controller/base/redirect.rb
  26. +390 −0 actionpack/lib/action_controller/base/render.rb
  27. +2 −1 actionpack/lib/action_controller/{ → base}/request_forgery_protection.rb
  28. +42 −0 actionpack/lib/action_controller/base/responder.rb
  29. +1 −1 actionpack/lib/action_controller/{ → base}/session_management.rb
  30. 0 actionpack/lib/action_controller/{ → base}/streaming.rb
  31. 0 actionpack/lib/action_controller/{ → base}/verification.rb
  32. +0 −15 actionpack/lib/action_controller/cgi_ext.rb
  33. +0 −112 actionpack/lib/action_controller/cgi_ext/cookie.rb
  34. +0 −22 actionpack/lib/action_controller/cgi_ext/query_extension.rb
  35. +0 −24 actionpack/lib/action_controller/cgi_ext/stdinput.rb
  36. +0 −77 actionpack/lib/action_controller/cgi_process.rb
  37. +2 −0 actionpack/lib/action_controller/deprecated.rb
  38. +14 −36 actionpack/lib/action_controller/{ → dispatch}/dispatcher.rb
  39. +3 −3 actionpack/lib/action_controller/{ → dispatch}/middlewares.rb
  40. +9 −7 actionpack/lib/action_controller/{ → dispatch}/rescue.rb
  41. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/_request_and_response.erb
  42. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/_trace.erb
  43. +2 −3 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/diagnostics.erb
  44. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/layout.erb
  45. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/missing_template.erb
  46. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/routing_error.erb
  47. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/template_error.erb
  48. 0 actionpack/lib/action_controller/{ → dispatch}/templates/rescues/unknown_action.erb
  49. +7 −0 actionpack/lib/action_controller/new_base.rb
  50. +61 −0 actionpack/lib/action_controller/new_base/base.rb
  51. +31 −0 actionpack/lib/action_controller/new_base/hide_actions.rb
  52. +37 −0 actionpack/lib/action_controller/new_base/layouts.rb
  53. +62 −0 actionpack/lib/action_controller/new_base/renderer.rb
  54. +40 −0 actionpack/lib/action_controller/new_base/url_for.rb
  55. +1 −1 actionpack/lib/action_controller/record_identifier.rb
  56. 0 actionpack/lib/action_controller/{ → routing/generation}/polymorphic_routes.rb
  57. 0 actionpack/lib/action_controller/{ → routing/generation}/url_rewriter.rb
  58. 0 actionpack/lib/action_controller/{ → routing}/resources.rb
  59. +1 −1 actionpack/lib/action_controller/routing/route_set.rb
  60. +0 −88 actionpack/lib/action_controller/status_codes.rb
  61. 0 actionpack/lib/action_controller/{assertions/dom_assertions.rb → testing/assertions/dom.rb}
  62. 0 actionpack/lib/action_controller/{assertions/model_assertions.rb → testing/assertions/model.rb}
  63. +2 −2 ...onpack/lib/action_controller/{assertions/response_assertions.rb → testing/assertions/response.rb}
  64. 0 actionpack/lib/action_controller/{assertions/routing_assertions.rb → testing/assertions/routing.rb}
  65. 0 ...onpack/lib/action_controller/{assertions/selector_assertions.rb → testing/assertions/selector.rb}
  66. 0 actionpack/lib/action_controller/{assertions/tag_assertions.rb → testing/assertions/tag.rb}
  67. +3 −3 actionpack/lib/action_controller/{ → testing}/integration.rb
  68. 0 actionpack/lib/action_controller/{performance_test.rb → testing/performance.rb}
  69. +10 −4 actionpack/lib/action_controller/{test_process.rb → testing/process.rb}
  70. +1 −1 actionpack/lib/action_controller/{ → testing}/test_case.rb
  71. +0 −44 actionpack/lib/action_controller/uploaded_file.rb
  72. +64 −0 actionpack/lib/action_dispatch.rb
  73. +1 −1 actionpack/lib/{action_controller → action_dispatch/http}/headers.rb
  74. +7 −7 actionpack/lib/{action_controller → action_dispatch/http}/mime_type.rb
  75. 0 actionpack/lib/{action_controller → action_dispatch/http}/mime_types.rb
  76. +59 −17 actionpack/lib/{action_controller → action_dispatch/http}/request.rb
  77. +1 −1 actionpack/lib/{action_controller → action_dispatch/http}/response.rb
  78. +40 −0 actionpack/lib/action_dispatch/http/status_codes.rb
  79. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/failsafe.rb
  80. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/params_parser.rb
  81. +3 −3 actionpack/lib/{action_controller → action_dispatch/middleware}/reloader.rb
  82. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/rewindable_input.rb
  83. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/session/abstract_store.rb
  84. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb
  85. +1 −1 actionpack/lib/{action_controller → action_dispatch/middleware}/session/mem_cache_store.rb
  86. +1 −1 actionpack/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb}
  87. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack.rb
  88. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/adapter/camping.rb
  89. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/abstract/handler.rb
  90. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/abstract/request.rb
  91. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/basic.rb
  92. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/digest/md5.rb
  93. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/digest/nonce.rb
  94. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/digest/params.rb
  95. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/digest/request.rb
  96. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/auth/openid.rb
  97. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/builder.rb
  98. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/cascade.rb
  99. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/chunked.rb
  100. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/commonlogger.rb
  101. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/conditionalget.rb
  102. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/content_length.rb
  103. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/content_type.rb
  104. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/deflater.rb
  105. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/directory.rb
  106. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/file.rb
  107. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler.rb
  108. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/cgi.rb
  109. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/evented_mongrel.rb
  110. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/fastcgi.rb
  111. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/lsws.rb
  112. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/mongrel.rb
  113. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/scgi.rb
  114. 0 ...ack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb
  115. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/thin.rb
  116. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/handler/webrick.rb
  117. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/head.rb
  118. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/lint.rb
  119. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/lobster.rb
  120. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/lock.rb
  121. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/methodoverride.rb
  122. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/mime.rb
  123. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/mock.rb
  124. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/recursive.rb
  125. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/reloader.rb
  126. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/request.rb
  127. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/response.rb
  128. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/session/abstract/id.rb
  129. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/session/cookie.rb
  130. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/session/memcache.rb
  131. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/session/pool.rb
  132. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/showexceptions.rb
  133. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/showstatus.rb
  134. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/static.rb
  135. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/urlmap.rb
  136. 0 actionpack/lib/{action_controller → action_dispatch}/vendor/rack-1.0/rack/utils.rb
  137. +13 −9 actionpack/lib/action_view.rb
  138. +11 −83 actionpack/lib/action_view/base.rb
  139. +1 −1 actionpack/lib/action_view/helpers/active_record_helper.rb
  140. +3 −3 actionpack/lib/action_view/helpers/prototype_helper.rb
  141. +27 −16 actionpack/lib/action_view/paths.rb
  142. +0 −117 actionpack/lib/action_view/reloadable_template.rb
  143. +136 −48 actionpack/lib/action_view/{ → render}/partials.rb
  144. +114 −0 actionpack/lib/action_view/render/rendering.rb
  145. +0 −47 actionpack/lib/action_view/renderable_partial.rb
  146. +0 −246 actionpack/lib/action_view/template.rb
  147. 0 actionpack/lib/action_view/{template_error.rb → template/error.rb}
  148. 0 actionpack/lib/action_view/{template_handler.rb → template/handler.rb}
  149. +3 −3 actionpack/lib/action_view/{template_handlers.rb → template/handlers.rb}
  150. 0 actionpack/lib/action_view/{template_handlers → template/handlers}/builder.rb
  151. +2 −0 actionpack/lib/action_view/{template_handlers → template/handlers}/erb.rb
  152. +1 −1 actionpack/lib/action_view/{template_handlers → template/handlers}/rjs.rb
  153. 0 actionpack/lib/action_view/{inline_template.rb → template/inline.rb}
  154. +18 −0 actionpack/lib/action_view/template/partial.rb
  155. +87 −0 actionpack/lib/action_view/template/path.rb
  156. +26 −28 actionpack/lib/action_view/{ → template}/renderable.rb
  157. +187 −0 actionpack/lib/action_view/template/template.rb
  158. +9 −0 actionpack/lib/action_view/template/text.rb
  159. +8 −11 actionpack/lib/action_view/test_case.rb
  160. +226 −0 actionpack/test/abstract_controller/abstract_controller_test.rb
  161. +197 −0 actionpack/test/abstract_controller/callbacks_test.rb
  162. +43 −0 actionpack/test/abstract_controller/helper_test.rb
  163. +232 −0 actionpack/test/abstract_controller/layouts_test.rb
  164. +25 −0 actionpack/test/abstract_controller/test_helper.rb
  165. +1 −0 actionpack/test/abstract_controller/views/abstract_controller/testing/me3/formatted.html.erb
  166. +1 −0 actionpack/test/abstract_controller/views/abstract_controller/testing/me3/index.erb
  167. +1 −0 actionpack/test/abstract_controller/views/abstract_controller/testing/me4/index.erb
  168. +1 −0 actionpack/test/abstract_controller/views/abstract_controller/testing/me5/index.erb
  169. +1 −0 actionpack/test/abstract_controller/views/action_with_ivars.erb
  170. +1 −0 actionpack/test/abstract_controller/views/helper_test.erb
  171. +1 −0 actionpack/test/abstract_controller/views/index.erb
  172. +1 −0 actionpack/test/abstract_controller/views/layouts/abstract_controller/testing/me4.erb
  173. +1 −0 actionpack/test/abstract_controller/views/layouts/application.erb
  174. +1 −0 actionpack/test/abstract_controller/views/naked_render.erb
  175. +1 −6 actionpack/test/abstract_unit.rb
  176. +28 −17 actionpack/test/activerecord/active_record_store_test.rb
  177. +2 −0 actionpack/test/controller/action_pack_assertions_test.rb
  178. +1 −0 actionpack/test/controller/addresses_render_test.rb
  179. +2 −0 actionpack/test/controller/assert_select_test.rb
  180. +2 −0 actionpack/test/controller/base_test.rb
  181. +1 −0 actionpack/test/controller/benchmark_test.rb
  182. +4 −0 actionpack/test/controller/caching_test.rb
  183. +1 −0 actionpack/test/controller/capture_test.rb
  184. +3 −0 actionpack/test/controller/content_type_test.rb
  185. +11 −0 actionpack/test/controller/cookie_test.rb
  186. +4 −4 actionpack/test/controller/dispatcher_test.rb
  187. +0 −14 actionpack/test/controller/header_test.rb
  188. +41 −7 actionpack/test/controller/layout_test.rb
  189. +4 −1 actionpack/test/controller/logging_test.rb
  190. +6 −3 actionpack/test/controller/mime_responds_test.rb
  191. +17 −28 actionpack/test/controller/render_test.rb
  192. +35 −0 actionpack/test/controller/request/test_request_test.rb
  193. +6 −5 actionpack/test/controller/request_forgery_protection_test.rb
  194. +6 −3 actionpack/test/controller/rescue_test.rb
  195. +1 −1 actionpack/test/controller/send_file_test.rb
  196. +43 −9 actionpack/test/controller/session/cookie_store_test.rb
  197. +1 −1 actionpack/test/controller/session/mem_cache_store_test.rb
  198. +3 −5 actionpack/test/controller/test_test.rb
  199. +2 −2 actionpack/test/controller/view_paths_test.rb
  200. +16 −0 actionpack/test/dispatch/header_test.rb
  201. +1 −1 actionpack/test/{controller → dispatch}/middleware_stack_test.rb
  202. +27 −24 actionpack/test/{controller → dispatch}/mime_type_test.rb
  203. +33 −34 actionpack/test/{controller → dispatch}/rack_test.rb
  204. 0 actionpack/test/{controller → dispatch}/request/json_params_parsing_test.rb
  205. +1 −1 actionpack/test/{controller → dispatch}/request/multipart_params_parsing_test.rb
  206. 0 actionpack/test/{controller → dispatch}/request/query_string_parsing_test.rb
  207. +1 −1 actionpack/test/{controller → dispatch}/request/url_encoded_params_parsing_test.rb
  208. 0 actionpack/test/{controller → dispatch}/request/xml_params_parsing_test.rb
  209. +48 −38 actionpack/test/{controller → dispatch}/request_test.rb
  210. +1 −0 actionpack/test/fixtures/happy_path/render_action/hello_world.erb
  211. +1 −0 actionpack/test/fixtures/layout_tests/views/goodbye.rhtml
  212. +0 −1 actionpack/test/fixtures/layouts/default_html.html.erb
  213. +0 −1 actionpack/test/fixtures/test/backup_files/item.html.erb
  214. +0 −1 actionpack/test/fixtures/test/backup_files/item.html.erb.orig
  215. +1 −0 actionpack/test/fixtures/test/basic.html.erb
  216. +0 −1 actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb
  217. +35 −0 actionpack/test/lib/fixture_template.rb
  218. +90 −0 actionpack/test/new_base/base_test.rb
  219. +325 −0 actionpack/test/new_base/render_action_test.rb
  220. +16 −0 actionpack/test/new_base/render_implicit_action_test.rb
  221. +45 −0 actionpack/test/new_base/render_layout_test.rb
  222. +133 −0 actionpack/test/new_base/render_template_test.rb
  223. +144 −0 actionpack/test/new_base/render_text_test.rb
  224. +144 −0 actionpack/test/new_base/test_helper.rb
  225. +8 −0 actionpack/test/runner
  226. +6 −3 actionpack/test/template/active_record_helper_i18n_test.rb
  227. +1 −0 actionpack/test/template/active_record_helper_test.rb
  228. +2 −0 actionpack/test/template/asset_tag_helper_test.rb
  229. +1 −0 actionpack/test/template/atom_feed_helper_test.rb
  230. +40 −158 actionpack/test/template/compiled_templates_test.rb
  231. +1 −0 actionpack/test/template/form_helper_test.rb
  232. +1 −0 actionpack/test/template/form_tag_helper_test.rb
  233. +2 −1 actionpack/test/template/javascript_helper_test.rb
  234. +2 −1 actionpack/test/template/prototype_helper_test.rb
  235. +1 −0 actionpack/test/template/record_tag_helper_test.rb
  236. +39 −43 actionpack/test/template/render_test.rb
  237. +1 −0 actionpack/test/template/scriptaculous_helper_test.rb
  238. +0 −34 actionpack/test/template/template_test.rb
  239. +1 −0 actionpack/test/template/test_test.rb
  240. +1 −0 actionpack/test/template/text_helper_test.rb
  241. +4 −0 actionpack/test/template/url_helper_test.rb
  242. +7 −0 activerecord/CHANGELOG
  243. +45 −23 activerecord/lib/active_record/associations.rb
  244. +30 −1 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
  245. +2 −2 activerecord/lib/active_record/session_store.rb
  246. +39 −9 activerecord/lib/active_record/timestamp.rb
  247. +44 −0 activerecord/test/cases/schema_test_postgresql.rb
  248. +75 −0 activerecord/test/cases/timestamp_test.rb
  249. +1 −1 activerecord/test/models/pet.rb
  250. +2 −0 activerecord/test/schema/schema.rb
  251. +2 −0 activesupport/CHANGELOG
  252. +2 −0 activesupport/lib/active_support.rb
  253. +8 −8 activesupport/lib/active_support/buffered_logger.rb
  254. +1 −1 activesupport/lib/active_support/callbacks.rb
  255. +27 −0 activesupport/lib/active_support/concurrent_hash.rb
  256. +2 −2 activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
  257. +5 −5 activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
  258. +90 −11 activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
  259. +1 −2 activesupport/lib/active_support/core_ext/hash/conversions.rb
  260. +1 −0 activesupport/lib/active_support/core_ext/module.rb
  261. +2 −2 activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
  262. +26 −0 activesupport/lib/active_support/core_ext/module/setup.rb
  263. +3 −3 activesupport/lib/active_support/core_ext/proc.rb
  264. +5 −1 activesupport/lib/active_support/core_ext/string/multibyte.rb
  265. +1 −1 activesupport/lib/active_support/deprecation.rb
  266. +16 −3 activesupport/lib/active_support/memoizable.rb
  267. +9 −0 activesupport/lib/active_support/mini.rb
  268. +5 −5 activesupport/lib/active_support/multibyte/unicode_database.rb
  269. +486 −0 activesupport/lib/active_support/new_callbacks.rb
  270. +2 −0 activesupport/lib/active_support/test_case.rb
  271. +37 −12 activesupport/lib/active_support/testing/declarative.rb
  272. +43 −0 activesupport/lib/active_support/testing/pending.rb
  273. +3 −1 activesupport/lib/active_support/testing/setup_and_teardown.rb
  274. +9 −4 activesupport/lib/active_support/time_with_zone.rb
  275. +3 −3 activesupport/test/core_ext/time_ext_test.rb
  276. +4 −0 activesupport/test/core_ext/time_with_zone_test.rb
  277. +8 −3 activesupport/test/memoizable_test.rb
  278. +115 −0 activesupport/test/new_callback_inheritance_test.rb
  279. +384 −0 activesupport/test/new_callbacks_test.rb
  280. +2 −2 ci/cruise_config.rb
  281. +1 −1 railties/builtin/rails_info/rails/info_controller.rb
  282. +0 −1 railties/environments/production.rb
  283. +0 −1 railties/environments/test.rb
  284. +7 −7 railties/guides/source/caching_with_rails.textile
  285. +1 −1 railties/guides/source/rails_on_rack.textile
  286. +1 −1 railties/lib/dispatcher.rb
  287. +6 −3 railties/lib/initializer.rb
  288. +2 −2 railties/lib/test_help.rb
  289. +1 −7 railties/test/initializer_test.rb
  290. +25 −31 railties/test/rails_info_controller_test.rb
  291. +16 −1 railties/test/rails_info_test.rb
View
1 .gitignore
@@ -14,6 +14,7 @@ railties/pkg
railties/test/500.html
railties/doc/guides/html/images
railties/doc/guides/html/stylesheets
+benches
railties/guides/output
*.rbc
*.swp
View
65 actionmailer/lib/action_mailer/base.rb
@@ -373,6 +373,14 @@ def mailer_name=(value)
attr_reader :mail
attr_reader :template_name, :default_template_name, :action_name
+ def controller_path
+ self.class.controller_path
+ end
+
+ def formats
+ @template.formats
+ end
+
class << self
attr_writer :mailer_name
@@ -466,7 +474,7 @@ def create!(method_name, *parameters) #:nodoc:
# have not already been specified manually.
if @parts.empty?
Dir.glob("#{template_path}/#{@template}.*").each do |path|
- template = template_root["#{mailer_name}/#{File.basename(path)}"]
+ template = template_root.find_by_parts("#{mailer_name}/#{File.basename(path)}")
# Skip unless template has a multipart format
next unless template && template.multipart?
@@ -475,7 +483,7 @@ def create!(method_name, *parameters) #:nodoc:
:content_type => template.content_type,
:disposition => "inline",
:charset => charset,
- :body => render_message(template, @body)
+ :body => render_template(template, @body)
)
end
unless @parts.empty?
@@ -489,7 +497,7 @@ def create!(method_name, *parameters) #:nodoc:
# normal template exists (or if there were no implicit parts) we render
# it.
template_exists = @parts.empty?
- template_exists ||= template_root["#{mailer_name}/#{@template}"]
+ template_exists ||= template_root.find_by_parts("#{mailer_name}/#{@template}")
@body = render_message(@template, @body) if template_exists
# Finally, if there are other message parts and a textual body exists,
@@ -514,6 +522,7 @@ def create!(method_name, *parameters) #:nodoc:
# no alternate has been given as the parameter, this will fail.
def deliver!(mail = @mail)
raise "no mail object available for delivery!" unless mail
+
unless logger.nil?
logger.info "Sent mail to #{Array(recipients).join(', ')}"
logger.debug "\n#{mail.encoded}"
@@ -545,27 +554,43 @@ def initialize_defaults(method_name)
@mime_version = @@default_mime_version.dup if @@default_mime_version
end
- def render_message(method_name, body)
- if method_name.respond_to?(:content_type)
- @current_template_content_type = method_name.content_type
+ def render_template(template, body)
+ if template.respond_to?(:content_type)
+ @current_template_content_type = template.content_type
end
+
+ @template = initialize_template_class(body)
+ layout = _pick_layout(layout, true) unless template.exempt_from_layout?
+ @template._render_template_with_layout(template, layout, {})
+ ensure
+ @current_template_content_type = nil
+ end
+
+ def render_message(method_name, body)
render :file => method_name, :body => body
ensure
@current_template_content_type = nil
end
def render(opts)
- body = opts.delete(:body)
- if opts[:file] && (opts[:file] !~ /\// && !opts[:file].respond_to?(:render))
- opts[:file] = "#{mailer_name}/#{opts[:file]}"
- end
-
+ layout, file = opts.delete(:layout), opts[:file]
+
begin
- old_template, @template = @template, initialize_template_class(body)
- layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
- @template.render(opts.merge(:layout => layout))
- ensure
- @template = old_template
+ @template = initialize_template_class(opts.delete(:body))
+
+ if file
+ prefix = mailer_name unless file =~ /\//
+ template = view_paths.find_by_parts(file, formats, prefix)
+ end
+
+ layout = _pick_layout(layout,
+ !template || !template.exempt_from_layout?)
+
+ if template
+ @template._render_template_with_layout(template, layout, opts)
+ elsif inline = opts[:inline]
+ @template._render_inline(inline, layout, opts)
+ end
end
end
@@ -577,12 +602,6 @@ def default_template_format
end
end
- def candidate_for_layout?(options)
- !self.view_paths.find_template(default_template_name, default_template_format).exempt_from_layout?
- rescue ActionView::MissingTemplate
- return true
- end
-
def template_root
self.class.template_root
end
@@ -597,7 +616,7 @@ def template_path
def initialize_template_class(assigns)
template = ActionView::Base.new(self.class.view_paths, assigns, self)
- template.template_format = default_template_format
+ template.formats = [default_template_format]
template
end
View
1 actionmailer/test/abstract_unit.rb
@@ -19,7 +19,6 @@
$:.unshift "#{File.dirname(__FILE__)}/fixtures/helpers"
-ActionView::Base.cache_template_loading = true
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
ActionMailer::Base.template_root = FIXTURE_LOAD_PATH
View
26 actionmailer/test/mail_service_test.rb
@@ -565,13 +565,31 @@ def test_performs_delivery_via_sendmail
TestMailer.deliver_signed_up(@recipient)
end
+ class FakeLogger
+ attr_reader :info_contents, :debug_contents
+
+ def initialize
+ @info_contents, @debug_contents = "", ""
+ end
+
+ def info(str)
+ @info_contents << str
+ end
+
+ def debug(str)
+ @debug_contents << str
+ end
+ end
+
def test_delivery_logs_sent_mail
mail = TestMailer.create_signed_up(@recipient)
- logger = mock()
- logger.expects(:info).with("Sent mail to #{@recipient}")
- logger.expects(:debug).with("\n#{mail.encoded}")
- TestMailer.logger = logger
+ # logger = mock()
+ # logger.expects(:info).with("Sent mail to #{@recipient}")
+ # logger.expects(:debug).with("\n#{mail.encoded}")
+ TestMailer.logger = FakeLogger.new
TestMailer.deliver_signed_up(@recipient)
+ assert(TestMailer.logger.info_contents =~ /Sent mail to #{@recipient}/)
+ assert_equal(TestMailer.logger.debug_contents, "\n#{mail.encoded}")
end
def test_unquote_quoted_printable_subject
View
7 actionpack/CHANGELOG
@@ -1,7 +1,14 @@
+*Edge*
+
+* Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes]
+
+
*2.3.2 [Final] (March 15, 2009)*
* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]
+* Don't check authenticity tokens for any AJAX requests [Ross Kaffenberger/Bryan Helmkamp]
+
* Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack]
* Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger]
View
2 actionpack/Rakefile
@@ -30,7 +30,7 @@ Rake::TestTask.new(:test_action_pack) do |t|
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
- t.test_files = Dir.glob( "test/[cft]*/**/*_test.rb" ).sort
+ t.test_files = Dir.glob( "test/[cdft]*/**/*_test.rb" ).sort
t.verbose = true
#t.warning = true
View
101 actionpack/lib/action_controller.rb
@@ -31,86 +31,59 @@
end
end
-begin
- gem 'rack', '~> 1.0.0'
- require 'rack'
-rescue Gem::LoadError
- require 'action_controller/vendor/rack-1.0/rack'
-end
+require File.join(File.dirname(__FILE__), "action_pack")
module ActionController
# TODO: Review explicit to see if they will automatically be handled by
# the initilizer if they are really needed.
def self.load_all!
- [Base, CGIHandler, CgiRequest, Request, Response, Http::Headers, UrlRewriter, UrlWriter]
+ [Base, Request, Response, UrlRewriter, UrlWriter]
+ [ActionDispatch::Http::Headers]
end
- autoload :AbstractRequest, 'action_controller/request'
- autoload :Base, 'action_controller/base'
- autoload :Benchmarking, 'action_controller/benchmarking'
+ autoload :Base, 'action_controller/base/base'
+ autoload :Benchmarking, 'action_controller/base/chained/benchmarking'
autoload :Caching, 'action_controller/caching'
- autoload :Cookies, 'action_controller/cookies'
- autoload :Dispatcher, 'action_controller/dispatcher'
- autoload :Failsafe, 'action_controller/failsafe'
- autoload :Filters, 'action_controller/filters'
- autoload :Flash, 'action_controller/flash'
- autoload :Helpers, 'action_controller/helpers'
- autoload :HttpAuthentication, 'action_controller/http_authentication'
- autoload :Integration, 'action_controller/integration'
- autoload :IntegrationTest, 'action_controller/integration'
- autoload :Layout, 'action_controller/layout'
- autoload :MiddlewareStack, 'action_controller/middleware_stack'
- autoload :MimeResponds, 'action_controller/mime_responds'
- autoload :ParamsParser, 'action_controller/params_parser'
- autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes'
+ autoload :Cookies, 'action_controller/base/cookies'
+ autoload :Dispatcher, 'action_controller/dispatch/dispatcher'
+ autoload :Filters, 'action_controller/base/chained/filters'
+ autoload :Flash, 'action_controller/base/chained/flash'
+ autoload :Helpers, 'action_controller/base/helpers'
+ autoload :HttpAuthentication, 'action_controller/base/http_authentication'
+ autoload :Integration, 'action_controller/testing/integration'
+ autoload :IntegrationTest, 'action_controller/testing/integration'
+ autoload :Layout, 'action_controller/base/layout'
+ autoload :MimeResponds, 'action_controller/base/mime_responds'
+ autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes'
autoload :RecordIdentifier, 'action_controller/record_identifier'
- autoload :Reloader, 'action_controller/reloader'
- autoload :Request, 'action_controller/request'
- autoload :RequestForgeryProtection, 'action_controller/request_forgery_protection'
- autoload :Rescue, 'action_controller/rescue'
- autoload :Resources, 'action_controller/resources'
- autoload :Response, 'action_controller/response'
- autoload :RewindableInput, 'action_controller/rewindable_input'
+ autoload :Redirector, 'action_controller/base/redirect'
+ autoload :Renderer, 'action_controller/base/render'
+ autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection'
+ autoload :Rescue, 'action_controller/dispatch/rescue'
+ autoload :Resources, 'action_controller/routing/resources'
+ autoload :Responder, 'action_controller/base/responder'
autoload :Routing, 'action_controller/routing'
- autoload :SessionManagement, 'action_controller/session_management'
- autoload :StatusCodes, 'action_controller/status_codes'
- autoload :Streaming, 'action_controller/streaming'
- autoload :TestCase, 'action_controller/test_case'
- autoload :TestProcess, 'action_controller/test_process'
+ autoload :SessionManagement, 'action_controller/base/session_management'
+ autoload :Streaming, 'action_controller/base/streaming'
+ autoload :TestCase, 'action_controller/testing/test_case'
+ autoload :TestProcess, 'action_controller/testing/process'
autoload :Translation, 'action_controller/translation'
- autoload :UploadedFile, 'action_controller/uploaded_file'
- autoload :UploadedStringIO, 'action_controller/uploaded_file'
- autoload :UploadedTempfile, 'action_controller/uploaded_file'
- autoload :UrlRewriter, 'action_controller/url_rewriter'
- autoload :UrlWriter, 'action_controller/url_rewriter'
- autoload :Verification, 'action_controller/verification'
+ autoload :UrlEncodedPairParser, 'action_controller/dispatch/url_encoded_pair_parser'
+ autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter'
+ autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter'
+ autoload :Verification, 'action_controller/base/verification'
module Assertions
- autoload :DomAssertions, 'action_controller/assertions/dom_assertions'
- autoload :ModelAssertions, 'action_controller/assertions/model_assertions'
- autoload :ResponseAssertions, 'action_controller/assertions/response_assertions'
- autoload :RoutingAssertions, 'action_controller/assertions/routing_assertions'
- autoload :SelectorAssertions, 'action_controller/assertions/selector_assertions'
- autoload :TagAssertions, 'action_controller/assertions/tag_assertions'
- end
-
- module Http
- autoload :Headers, 'action_controller/headers'
+ autoload :DomAssertions, 'action_controller/testing/assertions/dom'
+ autoload :ModelAssertions, 'action_controller/testing/assertions/model'
+ autoload :ResponseAssertions, 'action_controller/testing/assertions/response'
+ autoload :RoutingAssertions, 'action_controller/testing/assertions/routing'
+ autoload :SelectorAssertions, 'action_controller/testing/assertions/selector'
+ autoload :TagAssertions, 'action_controller/testing/assertions/tag'
end
-
- module Session
- autoload :AbstractStore, 'action_controller/session/abstract_store'
- autoload :CookieStore, 'action_controller/session/cookie_store'
- autoload :MemCacheStore, 'action_controller/session/mem_cache_store'
- end
-
- # DEPRECATE: Remove CGI support
- autoload :CgiRequest, 'action_controller/cgi_process'
- autoload :CGIHandler, 'action_controller/cgi_process'
end
-autoload :Mime, 'action_controller/mime_type'
-
autoload :HTML, 'action_controller/vendor/html-scanner'
+require 'action_dispatch'
require 'action_view'
View
10 actionpack/lib/action_controller/abstract.rb
@@ -0,0 +1,10 @@
+module AbstractController
+ autoload :Base, "action_controller/abstract/base"
+ autoload :Callbacks, "action_controller/abstract/callbacks"
+ autoload :Helpers, "action_controller/abstract/helpers"
+ autoload :Layouts, "action_controller/abstract/layouts"
+ autoload :Logger, "action_controller/abstract/logger"
+ autoload :Renderer, "action_controller/abstract/renderer"
+ # === Exceptions
+ autoload :ActionNotFound, "action_controller/abstract/exceptions"
+end
View
41 actionpack/lib/action_controller/abstract/base.rb
@@ -0,0 +1,41 @@
+module AbstractController
+ class Base
+
+ attr_internal :response_body
+ attr_internal :response_obj
+ attr_internal :action_name
+
+ def self.process(action)
+ new.process(action)
+ end
+
+ def self.inherited(klass)
+ end
+
+ def initialize
+ self.response_obj = {}
+ end
+
+ def process(action_name)
+ unless respond_to_action?(action_name)
+ raise ActionNotFound, "The action '#{action_name}' could not be found"
+ end
+
+ @_action_name = action_name
+ process_action
+ self.response_obj[:body] = self.response_body
+ self
+ end
+
+ private
+
+ def process_action
+ respond_to?(action_name) ? send(action_name) : send(:action_missing, action_name)
+ end
+
+ def respond_to_action?(action_name)
+ respond_to?(action_name) || respond_to?(:action_missing, true)
+ end
+
+ end
+end
View
40 actionpack/lib/action_controller/abstract/callbacks.rb
@@ -0,0 +1,40 @@
+module AbstractController
+ module Callbacks
+ setup do
+ include ActiveSupport::NewCallbacks
+ define_callbacks :process_action
+ end
+
+ def process_action
+ _run_process_action_callbacks(action_name) do
+ super
+ end
+ end
+
+ module ClassMethods
+ def _normalize_callback_options(options)
+ if only = options[:only]
+ only = Array(only).map {|o| "action_name == :#{o}"}.join(" || ")
+ options[:per_key] = {:if => only}
+ end
+ if except = options[:except]
+ except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ")
+ options[:per_key] = {:unless => except}
+ end
+ end
+
+ [:before, :after, :around].each do |filter|
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+ def #{filter}_filter(*names, &blk)
+ options = names.last.is_a?(Hash) ? names.pop : {}
+ _normalize_callback_options(options)
+ names.push(blk) if block_given?
+ names.each do |name|
+ process_action_callback(:#{filter}, name, options)
+ end
+ end
+ RUBY_EVAL
+ end
+ end
+ end
+end
View
3 actionpack/lib/action_controller/abstract/exceptions.rb
@@ -0,0 +1,3 @@
+module AbstractController
+ class ActionNotFound < StandardError ; end
+end
View
59 actionpack/lib/action_controller/abstract/helpers.rb
@@ -0,0 +1,59 @@
+module AbstractController
+ module Helpers
+ depends_on Renderer
+
+ setup do
+ extlib_inheritable_accessor :master_helper_module
+ self.master_helper_module = Module.new
+ end
+
+ # def self.included(klass)
+ # klass.class_eval do
+ # extlib_inheritable_accessor :master_helper_module
+ # self.master_helper_module = Module.new
+ # end
+ # end
+
+ def _action_view
+ @_action_view ||= begin
+ av = super
+ av.helpers.send(:include, master_helper_module)
+ av
+ end
+ end
+
+ module ClassMethods
+ def inherited(klass)
+ klass.master_helper_module = Module.new
+ klass.master_helper_module.__send__ :include, master_helper_module
+
+ super
+ end
+
+ def add_template_helper(mod)
+ master_helper_module.module_eval { include mod }
+ end
+
+ def helper_method(*meths)
+ meths.flatten.each do |meth|
+ master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
+ def #{meth}(*args, &blk)
+ controller.send(%(#{meth}), *args, &blk)
+ end
+ ruby_eval
+ end
+ end
+
+ def helper(*args, &blk)
+ args.flatten.each do |arg|
+ case arg
+ when Module
+ add_template_helper(arg)
+ end
+ end
+ master_helper_module.module_eval(&blk) if block_given?
+ end
+ end
+
+ end
+end
View
82 actionpack/lib/action_controller/abstract/layouts.rb
@@ -0,0 +1,82 @@
+module AbstractController
+ module Layouts
+
+ depends_on Renderer
+
+ module ClassMethods
+ def layout(layout)
+ unless [String, Symbol, FalseClass, NilClass].include?(layout.class)
+ raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
+ end
+
+ @_layout = layout || false # Converts nil to false
+ _write_layout_method
+ end
+
+ def _implied_layout_name
+ name.underscore
+ end
+
+ # Takes the specified layout and creates a _layout method to be called
+ # by _default_layout
+ #
+ # If the specified layout is a:
+ # String:: return the string
+ # Symbol:: call the method specified by the symbol
+ # false:: return nil
+ # none:: If a layout is found in the view paths with the controller's
+ # name, return that string. Otherwise, use the superclass'
+ # layout (which might also be implied)
+ def _write_layout_method
+ case @_layout
+ when String
+ self.class_eval %{def _layout() #{@_layout.inspect} end}
+ when Symbol
+ self.class_eval %{def _layout() #{@_layout} end}
+ when false
+ self.class_eval %{def _layout() end}
+ else
+ self.class_eval %{
+ def _layout
+ if view_paths.find_by_parts?("#{_implied_layout_name}", formats, "layouts")
+ "#{_implied_layout_name}"
+ else
+ super
+ end
+ end
+ }
+ end
+ end
+ end
+
+ def _render_template(template, options)
+ _action_view._render_template_with_layout(template, options[:_layout])
+ end
+
+ private
+
+ def _layout() end # This will be overwritten
+
+ def _layout_for_name(name)
+ unless [String, FalseClass, NilClass].include?(name.class)
+ raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}"
+ end
+
+ name && view_paths.find_by_parts(name, formats, "layouts")
+ end
+
+ def _default_layout(require_layout = false)
+ if require_layout && !_layout
+ raise ArgumentError,
+ "There was no default layout for #{self.class} in #{view_paths.inspect}"
+ end
+
+ begin
+ layout = _layout_for_name(_layout)
+ rescue NameError => e
+ raise NoMethodError,
+ "You specified #{@_layout.inspect} as the layout, but no such method was found"
+ end
+ end
+ end
+end
View
7 actionpack/lib/action_controller/abstract/logger.rb
@@ -0,0 +1,7 @@
+module AbstractController
+ module Logger
+ setup do
+ cattr_accessor :logger
+ end
+ end
+end
View
58 actionpack/lib/action_controller/abstract/renderer.rb
@@ -0,0 +1,58 @@
+require "action_controller/abstract/logger"
+
+module AbstractController
+ module Renderer
+ depends_on AbstractController::Logger
+
+ setup do
+ attr_internal :formats
+
+ extlib_inheritable_accessor :_view_paths
+
+ self._view_paths ||= ActionView::PathSet.new
+ end
+
+ def _action_view
+ @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
+ end
+
+ def render(options = {})
+ self.response_body = render_to_string(options)
+ end
+
+ # Raw rendering of a template.
+ # ====
+ # @option _prefix<String> The template's path prefix
+ # @option _layout<String> The relative path to the layout template to use
+ #
+ # :api: plugin
+ def render_to_string(options = {})
+ name = options[:_template_name] || action_name
+
+ template = options[:_template] || view_paths.find_by_parts(name.to_s, formats, options[:_prefix])
+ _render_template(template, options)
+ end
+
+ def _render_template(template, options)
+ _action_view._render_template_with_layout(template)
+ end
+
+ def view_paths() _view_paths end
+
+ module ClassMethods
+
+ def append_view_path(path)
+ self.view_paths << path
+ end
+
+ def view_paths
+ self._view_paths
+ end
+
+ def view_paths=(paths)
+ self._view_paths = paths.is_a?(ActionView::PathSet) ?
+ paths : ActionView::Base.process_view_paths(paths)
+ end
+ end
+ end
+end
View
560 actionpack/lib/action_controller/base.rb → ...onpack/lib/action_controller/base/base.rb
@@ -1,3 +1,4 @@
+require 'action_controller/deprecated'
require 'set'
module ActionController #:nodoc:
@@ -58,22 +59,6 @@ def initialize(message = nil)
end
end
- class DoubleRenderError < ActionControllerError #:nodoc:
- DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
-
- def initialize(message = nil)
- super(message || DEFAULT_MESSAGE)
- end
- end
-
- class RedirectBackError < ActionControllerError #:nodoc:
- DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].'
-
- def initialize(message = nil)
- super(message || DEFAULT_MESSAGE)
- end
- end
-
class UnknownHttpMethod < ActionControllerError #:nodoc:
end
@@ -247,9 +232,8 @@ class UnknownHttpMethod < ActionControllerError #:nodoc:
# end
#
class Base
- DEFAULT_RENDER_STATUS_CODE = "200 OK"
- include StatusCodes
+ include ActionDispatch::StatusCodes
cattr_reader :protected_instance_variables
# Controller specific instance variables which will not be accessible inside views.
@@ -301,7 +285,10 @@ class Base
# A YAML parser is also available and can be turned on with:
#
# ActionController::Base.param_parsers[Mime::YAML] = :yaml
- @@param_parsers = {}
+ @@param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
+ Mime::URL_ENCODED_FORM => :url_encoded_form,
+ Mime::XML => :xml_simple,
+ Mime::JSON => :json }
cattr_accessor :param_parsers
# Controls the default charset for all renders.
@@ -381,8 +368,8 @@ class Base
class << self
def call(env)
# HACK: For global rescue to have access to the original request and response
- request = env["action_controller.rescue.request"] ||= Request.new(env)
- response = env["action_controller.rescue.response"] ||= Response.new
+ request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
+ response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
process(request, response)
end
@@ -514,8 +501,8 @@ def filter_parameter_logging(*filter_words, &block)
def process(request, response, method = :perform_action, *arguments) #:nodoc:
response.request = request
- initialize_template_class(response)
assign_shortcuts(request, response)
+ initialize_template_class(response)
initialize_current_url
assign_names
@@ -678,371 +665,6 @@ def append_view_path(path)
@template.view_paths.push(*path)
end
- protected
- # Renders the content that will be returned to the browser as the response body.
- #
- # === Rendering an action
- #
- # Action rendering is the most common form and the type used automatically by Action Controller when nothing else is
- # specified. By default, actions are rendered within the current layout (if one exists).
- #
- # # Renders the template for the action "goal" within the current controller
- # render :action => "goal"
- #
- # # Renders the template for the action "short_goal" within the current controller,
- # # but without the current active layout
- # render :action => "short_goal", :layout => false
- #
- # # Renders the template for the action "long_goal" within the current controller,
- # # but with a custom layout
- # render :action => "long_goal", :layout => "spectacular"
- #
- # === Rendering partials
- #
- # Partial rendering in a controller is most commonly used together with Ajax calls that only update one or a few elements on a page
- # without reloading. Rendering of partials from the controller makes it possible to use the same partial template in
- # both the full-page rendering (by calling it from within the template) and when sub-page updates happen (from the
- # controller action responding to Ajax calls). By default, the current layout is not used.
- #
- # # Renders the same partial with a local variable.
- # render :partial => "person", :locals => { :name => "david" }
- #
- # # Renders the partial, making @new_person available through
- # # the local variable 'person'
- # render :partial => "person", :object => @new_person
- #
- # # Renders a collection of the same partial by making each element
- # # of @winners available through the local variable "person" as it
- # # builds the complete response.
- # render :partial => "person", :collection => @winners
- #
- # # Renders a collection of partials but with a custom local variable name
- # render :partial => "admin_person", :collection => @winners, :as => :person
- #
- # # Renders the same collection of partials, but also renders the
- # # person_divider partial between each person partial.
- # render :partial => "person", :collection => @winners, :spacer_template => "person_divider"
- #
- # # Renders a collection of partials located in a view subfolder
- # # outside of our current controller. In this example we will be
- # # rendering app/views/shared/_note.r(html|xml) Inside the partial
- # # each element of @new_notes is available as the local var "note".
- # render :partial => "shared/note", :collection => @new_notes
- #
- # # Renders the partial with a status code of 500 (internal error).
- # render :partial => "broken", :status => 500
- #
- # Note that the partial filename must also be a valid Ruby variable name,
- # so e.g. 2005 and register-user are invalid.
- #
- #
- # == Automatic etagging
- #
- # Rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the
- # response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified
- # and the response body will be set to an empty string. No etag header will be inserted if it's already set.
- #
- # === Rendering a template
- #
- # Template rendering works just like action rendering except that it takes a path relative to the template root.
- # The current layout is automatically applied.
- #
- # # Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
- # render :template => "weblog/show"
- #
- # # Renders the template with a local variable
- # render :template => "weblog/show", :locals => {:customer => Customer.new}
- #
- # === Rendering a file
- #
- # File rendering works just like action rendering except that it takes a filesystem path. By default, the path
- # is assumed to be absolute, and the current layout is not applied.
- #
- # # Renders the template located at the absolute filesystem path
- # render :file => "/path/to/some/template.erb"
- # render :file => "c:/path/to/some/template.erb"
- #
- # # Renders a template within the current layout, and with a 404 status code
- # render :file => "/path/to/some/template.erb", :layout => true, :status => 404
- # render :file => "c:/path/to/some/template.erb", :layout => true, :status => 404
- #
- # === Rendering text
- #
- # Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text
- # rendering is not done within the active layout.
- #
- # # Renders the clear text "hello world" with status code 200
- # render :text => "hello world!"
- #
- # # Renders the clear text "Explosion!" with status code 500
- # render :text => "Explosion!", :status => 500
- #
- # # Renders the clear text "Hi there!" within the current active layout (if one exists)
- # render :text => "Hi there!", :layout => true
- #
- # # Renders the clear text "Hi there!" within the layout
- # # placed in "app/views/layouts/special.r(html|xml)"
- # render :text => "Hi there!", :layout => "special"
- #
- # === Streaming data and/or controlling the page generation
- #
- # The <tt>:text</tt> option can also accept a Proc object, which can be used to:
- #
- # 1. stream on-the-fly generated data to the browser. Note that you should
- # use the methods provided by ActionController::Steaming instead if you
- # want to stream a buffer or a file.
- # 2. manually control the page generation. This should generally be avoided,
- # as it violates the separation between code and content, and because almost
- # everything that can be done with this method can also be done more cleanly
- # using one of the other rendering methods, most notably templates.
- #
- # Two arguments are passed to the proc, a <tt>response</tt> object and an
- # <tt>output</tt> object. The response object is equivalent to the return
- # value of the ActionController::Base#response method, and can be used to
- # control various things in the HTTP response, such as setting the
- # Content-Type header. The output object is an writable <tt>IO</tt>-like
- # object, so one can call <tt>write</tt> and <tt>flush</tt> on it.
- #
- # The following example demonstrates how one can stream a large amount of
- # on-the-fly generated data to the browser:
- #
- # # Streams about 180 MB of generated data to the browser.
- # render :text => proc { |response, output|
- # 10_000_000.times do |i|
- # output.write("This is line #{i}\n")
- # output.flush
- # end
- # }
- #
- # Another example:
- #
- # # Renders "Hello from code!"
- # render :text => proc { |response, output| output.write("Hello from code!") }
- #
- # === Rendering XML
- #
- # Rendering XML sets the content type to application/xml.
- #
- # # Renders '<name>David</name>'
- # render :xml => {:name => "David"}.to_xml
- #
- # It's not necessary to call <tt>to_xml</tt> on the object you want to render, since <tt>render</tt> will
- # automatically do that for you:
- #
- # # Also renders '<name>David</name>'
- # render :xml => {:name => "David"}
- #
- # === Rendering JSON
- #
- # Rendering JSON sets the content type to application/json and optionally wraps the JSON in a callback. It is expected
- # that the response will be parsed (or eval'd) for use as a data structure.
- #
- # # Renders '{"name": "David"}'
- # render :json => {:name => "David"}.to_json
- #
- # It's not necessary to call <tt>to_json</tt> on the object you want to render, since <tt>render</tt> will
- # automatically do that for you:
- #
- # # Also renders '{"name": "David"}'
- # render :json => {:name => "David"}
- #
- # Sometimes the result isn't handled directly by a script (such as when the request comes from a SCRIPT tag),
- # so the <tt>:callback</tt> option is provided for these cases.
- #
- # # Renders 'show({"name": "David"})'
- # render :json => {:name => "David"}.to_json, :callback => 'show'
- #
- # === Rendering an inline template
- #
- # Rendering of an inline template works as a cross between text and action rendering where the source for the template
- # is supplied inline, like text, but its interpreted with ERb or Builder, like action. By default, ERb is used for rendering
- # and the current layout is not used.
- #
- # # Renders "hello, hello, hello, again"
- # render :inline => "<%= 'hello, ' * 3 + 'again' %>"
- #
- # # Renders "<p>Good seeing you!</p>" using Builder
- # render :inline => "xml.p { 'Good seeing you!' }", :type => :builder
- #
- # # Renders "hello david"
- # render :inline => "<%= 'hello ' + name %>", :locals => { :name => "david" }
- #
- # === Rendering inline JavaScriptGenerator page updates
- #
- # In addition to rendering JavaScriptGenerator page updates with Ajax in RJS templates (see ActionView::Base for details),
- # you can also pass the <tt>:update</tt> parameter to +render+, along with a block, to render page updates inline.
- #
- # render :update do |page|
- # page.replace_html 'user_list', :partial => 'user', :collection => @users
- # page.visual_effect :highlight, 'user_list'
- # end
- #
- # === Rendering vanilla JavaScript
- #
- # In addition to using RJS with render :update, you can also just render vanilla JavaScript with :js.
- #
- # # Renders "alert('hello')" and sets the mime type to text/javascript
- # render :js => "alert('hello')"
- #
- # === Rendering with status and location headers
- # All renders take the <tt>:status</tt> and <tt>:location</tt> options and turn them into headers. They can even be used together:
- #
- # render :xml => post.to_xml, :status => :created, :location => post_url(post)
- def render(options = nil, extra_options = {}, &block) #:doc:
- raise DoubleRenderError, "Can only render or redirect once per action" if performed?
-
- validate_render_arguments(options, extra_options, block_given?)
-
- if options.nil?
- options = { :template => default_template, :layout => true }
- elsif options == :update
- options = extra_options.merge({ :update => true })
- elsif options.is_a?(String) || options.is_a?(Symbol)
- case options.to_s.index('/')
- when 0
- extra_options[:file] = options
- when nil
- extra_options[:action] = options
- else
- extra_options[:template] = options
- end
-
- options = extra_options
- elsif !options.is_a?(Hash)
- extra_options[:partial] = options
- options = extra_options
- end
-
- layout = pick_layout(options)
- response.layout = layout.path_without_format_and_extension if layout
- logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
-
- if content_type = options[:content_type]
- response.content_type = content_type.to_s
- end
-
- if location = options[:location]
- response.headers["Location"] = url_for(location)
- end
-
- if options.has_key?(:text)
- text = layout ? @template.render(options.merge(:text => options[:text], :layout => layout)) : options[:text]
- render_for_text(text, options[:status])
-
- else
- if file = options[:file]
- render_for_file(file, options[:status], layout, options[:locals] || {})
-
- elsif template = options[:template]
- render_for_file(template, options[:status], layout, options[:locals] || {})
-
- elsif inline = options[:inline]
- render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
-
- elsif action_name = options[:action]
- render_for_file(default_template(action_name.to_s), options[:status], layout)
-
- elsif xml = options[:xml]
- response.content_type ||= Mime::XML
- render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options[:status])
-
- elsif js = options[:js]
- response.content_type ||= Mime::JS
- render_for_text(js, options[:status])
-
- elsif json = options[:json]
- json = json.to_json unless json.is_a?(String)
- json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
- response.content_type ||= Mime::JSON
- render_for_text(json, options[:status])
-
- elsif options[:partial]
- options[:partial] = default_template_name if options[:partial] == true
- if layout
- render_for_text(@template.render(:text => @template.render(options), :layout => layout), options[:status])
- else
- render_for_text(@template.render(options), options[:status])
- end
-
- elsif options[:update]
- @template.send(:_evaluate_assigns_and_ivars)
-
- generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
- response.content_type = Mime::JS
- render_for_text(generator.to_s, options[:status])
-
- elsif options[:nothing]
- render_for_text(nil, options[:status])
-
- else
- render_for_file(default_template, options[:status], layout)
- end
- end
- end
-
- # Renders according to the same rules as <tt>render</tt>, but returns the result in a string instead
- # of sending it as the response body to the browser.
- def render_to_string(options = nil, &block) #:doc:
- render(options, &block)
- response.body
- ensure
- response.content_type = nil
- erase_render_results
- reset_variables_added_to_assigns
- end
-
- # Return a response that has no content (merely headers). The options
- # argument is interpreted to be a hash of header names and values.
- # This allows you to easily return a response that consists only of
- # significant headers:
- #
- # head :created, :location => person_path(@person)
- #
- # It can also be used to return exceptional conditions:
- #
- # return head(:method_not_allowed) unless request.post?
- # return head(:bad_request) unless valid_request?
- # render
- def head(*args)
- if args.length > 2
- raise ArgumentError, "too many arguments to head"
- elsif args.empty?
- raise ArgumentError, "too few arguments to head"
- end
- options = args.extract_options!
- status = interpret_status(args.shift || options.delete(:status) || :ok)
-
- options.each do |key, value|
- headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s
- end
-
- render :nothing => true, :status => status
- end
-
- # Clears the rendered results, allowing for another render to be performed.
- def erase_render_results #:nodoc:
- response.body = []
- @performed_render = false
- end
-
- # Clears the redirected results from the headers, resets the status to 200 and returns
- # the URL that was used to redirect or nil if there was no redirected URL
- # Note that +redirect_to+ will change the body of the response to indicate a redirection.
- # The response body is not reset here, see +erase_render_results+
- def erase_redirect_results #:nodoc:
- @performed_redirect = false
- response.redirected_to = nil
- response.redirected_to_method_params = nil
- response.status = DEFAULT_RENDER_STATUS_CODE
- response.headers.delete('Location')
- end
-
- # Erase both render and redirect results
- def erase_results #:nodoc:
- erase_render_results
- erase_redirect_results
- end
-
def rewrite_options(options) #:nodoc:
if defaults = default_url_options(options)
defaults.merge(options)
@@ -1064,73 +686,6 @@ def rewrite_options(options) #:nodoc:
def default_url_options(options = nil)
end
- # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
- #
- # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
- # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
- # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
- # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
- # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
- # Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
- #
- # Examples:
- # redirect_to :action => "show", :id => 5
- # redirect_to post
- # redirect_to "http://www.rubyonrails.org"
- # redirect_to "/images/screenshot.jpg"
- # redirect_to articles_url
- # redirect_to :back
- #
- # The redirection happens as a "302 Moved" header unless otherwise specified.
- #
- # Examples:
- # redirect_to post_url(@post), :status=>:found
- # redirect_to :action=>'atom', :status=>:moved_permanently
- # redirect_to post_url(@post), :status=>301
- # redirect_to :action=>'atom', :status=>302
- #
- # When using <tt>redirect_to :back</tt>, if there is no referrer,
- # RedirectBackError will be raised. You may specify some fallback
- # behavior for this case by rescuing RedirectBackError.
- def redirect_to(options = {}, response_status = {}) #:doc:
- raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
-
- if options.is_a?(Hash) && options[:status]
- status = options.delete(:status)
- elsif response_status[:status]
- status = response_status[:status]
- else
- status = 302
- end
-
- response.redirected_to = options
-
- case options
- # The scheme name consist of a letter followed by any combination of
- # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
- # characters; and is terminated by a colon (":").
- when %r{^\w[\w\d+.-]*:.*}
- redirect_to_full_url(options, status)
- when String
- redirect_to_full_url(request.protocol + request.host_with_port + options, status)
- when :back
- if referer = request.headers["Referer"]
- redirect_to(referer, :status=>status)
- else
- raise RedirectBackError
- end
- else
- redirect_to_full_url(url_for(options), status)
- end
- end
-
- def redirect_to_full_url(url, status)
- raise DoubleRenderError if performed?
- logger.info("Redirected to #{url}") if logger && logger.info?
- response.redirect(url, interpret_status(status))
- @performed_redirect = true
- end
-
# Sets the etag and/or last_modified on the response and checks it against
# the client request. If the request doesn't match the options provided, the
# request is considered stale and should be generated from scratch. Otherwise,
@@ -1236,40 +791,20 @@ def reset_session #:doc:
end
private
- def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
- path = template_path.respond_to?(:path_without_format_and_extension) ? template_path.path_without_format_and_extension : template_path
- logger.info("Rendering #{path}" + (status ? " (#{status})" : '')) if logger
- render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
- end
-
- def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
- @performed_render = true
-
- response.status = interpret_status(status || DEFAULT_RENDER_STATUS_CODE)
-
- if append_response
- response.body_parts << text.to_s
- else
- response.body = case text
- when Proc then text
- when nil then [" "] # Safari doesn't pass the headers of the return if the response is zero length
- else [text.to_s]
- end
+ def _process_options(options)
+ if content_type = options[:content_type]
+ response.content_type = content_type.to_s
end
- end
- def validate_render_arguments(options, extra_options, has_block)
- if options && (has_block && options != :update) && !options.is_a?(String) && !options.is_a?(Hash) && !options.is_a?(Symbol)
- raise RenderError, "You called render with invalid options : #{options.inspect}"
+ if location = options[:location]
+ response.headers["Location"] = url_for(location)
end
- if !extra_options.is_a?(Hash)
- raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
- end
+ response.status = interpret_status(options[:status] || DEFAULT_RENDER_STATUS_CODE)
end
def initialize_template_class(response)
- response.template = ActionView::Base.new(self.class.view_paths, {}, self)
+ @template = response.template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
response.template.helpers.send :include, self.class.master_helper_module
response.redirected_to = nil
@performed_render = @performed_redirect = false
@@ -1282,7 +817,6 @@ def assign_shortcuts(request, response)
@_response.session = request.session
@_session = @_response.session
- @template = @_response.template
@_headers = @_response.headers
end
@@ -1318,23 +852,21 @@ def default_render #:nodoc:
end
def perform_action
- if action_methods.include?(action_name)
- send(action_name)
- default_render unless performed?
- elsif respond_to? :method_missing
- method_missing action_name
- default_render unless performed?
- else
- begin
- default_render
- rescue ActionView::MissingTemplate => e
- # Was the implicit template missing, or was it another template?
- if e.path == default_template_name
- raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence(:locale => :en)}", caller
- else
- raise e
- end
- end
+ if called = action_methods.include?(action_name)
+ ret = send(action_name)
+ elsif called = respond_to?(:method_missing)
+ ret = method_missing(action_name)
+ end
+
+ return (performed? ? ret : default_render) if called
+
+ begin
+ default_render
+ rescue ActionView::MissingTemplate => e
+ raise e unless e.action_name == action_name
+ # If the path is the same as the action_name, the action is completely missing
+ raise UnknownAction, "No action responded to #{action_name}. Actions: " +
+ "#{action_methods.sort.to_sentence}", caller
end
end
@@ -1347,23 +879,6 @@ def assign_names
@action_name = (params['action'] || 'index')
end
- # Returns a set of the methods defined as actions in your controller
- def action_methods
- self.class.action_methods
- end
-
- def self.action_methods
- @action_methods ||=
- # All public instance methods of this class, including ancestors
- public_instance_methods(true).map { |m| m.to_s }.to_set -
- # Except for public instance methods of Base and its ancestors
- Base.public_instance_methods(true).map { |m| m.to_s } +
- # Be sure to include shadowed public instance methods of this class
- public_instance_methods(false).map { |m| m.to_s } -
- # And always exclude explicitly hidden actions
- hidden_actions
- end
-
def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
@@ -1379,6 +894,10 @@ def complete_request_uri
"#{request.protocol}#{request.host}#{request.request_uri}"
end
+ def close_session
+ # @_session.close if @_session && @_session.respond_to?(:close)
+ end
+
def default_template(action_name = self.action_name)
self.view_paths.find_template(default_template_name(action_name), default_template_format)
end
@@ -1390,7 +909,7 @@ def default_template_name(action_name = self.action_name)
action_name = strip_out_controller(action_name)
end
end
- "#{self.controller_path}/#{action_name}"
+ "#{controller_path}/#{action_name}"
end
def strip_out_controller(path)
@@ -1402,14 +921,15 @@ def template_path_includes_controller?(path)
end
def process_cleanup
+ close_session
end
end
Base.class_eval do
- [ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
+ [ Filters, Layout, Renderer, Redirector, Responder, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
Cookies, Caching, Verification, Streaming, SessionManagement,
- HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
- RecordIdentifier, RequestForgeryProtection, Translation
+ HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods, RecordIdentifier,
+ RequestForgeryProtection, Translation
].each do |mod|
include mod
end
View
2 ...ack/lib/action_controller/benchmarking.rb → ...n_controller/base/chained/benchmarking.rb
@@ -64,7 +64,7 @@ def render_with_benchmark(options = nil, extra_options = {}, &block)
private
def perform_action_with_benchmark
- if logger
+ if logger && logger.info?
ms = [Benchmark.ms { perform_action_without_benchmark }, 0.01].max
logging_view = defined?(@view_runtime)
logging_active_record = Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
View
0 actionpack/lib/action_controller/filters.rb → ...action_controller/base/chained/filters.rb
File renamed without changes.
View
0 actionpack/lib/action_controller/flash.rb → ...b/action_controller/base/chained/flash.rb
File renamed without changes.
View
0 actionpack/lib/action_controller/cookies.rb → ...ack/lib/action_controller/base/cookies.rb
File renamed without changes.
View
0 actionpack/lib/action_controller/helpers.rb → ...ack/lib/action_controller/base/helpers.rb
File renamed without changes.
View
0 .../action_controller/http_authentication.rb → ...on_controller/base/http_authentication.rb
File renamed without changes.
View
154 actionpack/lib/action_controller/layout.rb → ...pack/lib/action_controller/base/layout.rb
@@ -2,11 +2,7 @@ module ActionController #:nodoc:
module Layout #:nodoc:
def self.included(base)
base.extend(ClassMethods)
- base.class_eval do
- class << self
- alias_method_chain :inherited, :layout
- end
- end
+ base.class_inheritable_accessor :layout_name, :layout_conditions
end
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
@@ -159,123 +155,93 @@ class << self
#
# This will render the help action with the "help" layout instead of the controller-wide "weblog_standard" layout.
module ClassMethods
+ extend ActiveSupport::Memoizable
+
# If a layout is specified, all rendered actions will have their result rendered
# when the layout <tt>yield</tt>s. This layout can itself depend on instance variables assigned during action
# performance and have access to them as any normal template would.
def layout(template_name, conditions = {}, auto = false)
add_layout_conditions(conditions)
- write_inheritable_attribute(:layout, template_name)
- write_inheritable_attribute(:auto_layout, auto)
+ self.layout_name = template_name
+ end
+
+ def memoized_default_layout(formats) #:nodoc:
+ self.layout_name || begin
+ layout = default_layout_name
+ layout.is_a?(String) ? find_layout(layout, formats) : layout
+ rescue ActionView::MissingTemplate
+ end
+ end
+
+ def default_layout(*args)
+ memoized_default_layout(*args)
+ @_memoized_default_layout ||= ::ActiveSupport::ConcurrentHash.new
+ @_memoized_default_layout[args] ||= memoized_default_layout(*args)
+ end
+
+ def memoized_find_layout(layout, formats) #:nodoc:
+ return layout if layout.nil? || layout.respond_to?(:render)
+ prefix = layout.to_s =~ /layouts\// ? nil : "layouts"
+ view_paths.find_by_parts(layout.to_s, formats, prefix)
end
- def layout_conditions #:nodoc:
- @layout_conditions ||= read_inheritable_attribute(:layout_conditions)
+ def find_layout(*args)
+ @_memoized_find_layout ||= ::ActiveSupport::ConcurrentHash.new
+ @_memoized_find_layout[args] ||= memoized_find_layout(*args)
end
def layout_list #:nodoc:
Array(view_paths).sum([]) { |path| Dir["#{path.to_str}/layouts/**/*"] }
end
+ memoize :layout_list
- private
- def inherited_with_layout(child)
- inherited_without_layout(child)
- unless child.name.blank?
- layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
- child.layout(layout_match, {}, true) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
- end
+ def default_layout_name
+ layout_match = name.underscore.sub(/_controller$/, '')
+ if layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
+ superclass.default_layout_name if superclass.respond_to?(:default_layout_name)
+ else
+ layout_match
end
+ end
+ memoize :default_layout_name
+ private
def add_layout_conditions(conditions)
- write_inheritable_hash(:layout_conditions, normalize_conditions(conditions))
- end
-
- def normalize_conditions(conditions)
- conditions.inject({}) {|hash, (key, value)| hash.merge(key => [value].flatten.map {|action| action.to_s})}
+ # :except => :foo == :except => [:foo] == :except => "foo" == :except => ["foo"]
+ conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
+ write_inheritable_hash(:layout_conditions, conditions)
end
end
-
- # Returns the name of the active layout. If the layout was specified as a method reference (through a symbol), this method
- # is called and the return value is used. Likewise if the layout was specified as an inline method (through a proc or method
- # object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
- # weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
- def active_layout(passed_layout = nil, options = {})
- layout = passed_layout || default_layout
- return layout if layout.respond_to?(:render)
-
- active_layout = case layout
- when Symbol then __send__(layout)
- when Proc then layout.call(self)
- else layout
+
+ def active_layout(name)
+ name = self.class.default_layout(formats) if name == true
+
+ layout_name = case name
+ when Symbol then __send__(name)
+ when Proc then name.call(self)
+ else name
end
- find_layout(active_layout, default_template_format, options[:html_fallback]) if active_layout
+ self.class.find_layout(layout_name, formats)
end
- private
- def default_layout #:nodoc:
- layout = self.class.read_inheritable_attribute(:layout)
- return layout unless self.class.read_inheritable_attribute(:auto_layout)
- find_layout(layout, default_template_format)
- rescue ActionView::MissingTemplate
- nil
- end
-
- def find_layout(layout, format, html_fallback=false) #:nodoc:
- view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", format, html_fallback)
- rescue ActionView::MissingTemplate
- raise if Mime::Type.lookup_by_extension(format.to_s).html?
- end
-
- def pick_layout(options)
- if options.has_key?(:layout)
- case layout = options.delete(:layout)
- when FalseClass
- nil
- when NilClass, TrueClass
- active_layout if action_has_layout? && candidate_for_layout?(:template => default_template_name)
- else
- active_layout(layout, :html_fallback => true)
- end
- else
- active_layout if action_has_layout? && candidate_for_layout?(options)
- end
- end
+ def _pick_layout(layout_name = nil, implicit = false)
+ return unless layout_name || implicit
+ layout_name = true if layout_name.nil?
+ active_layout(layout_name) if action_has_layout? && layout_name
+ end
+ private
def action_has_layout?
if conditions = self.class.layout_conditions
- case
- when only = conditions[:only]
- only.include?(action_name)
- when except = conditions[:except]
- !except.include?(action_name)
- else
- true
+ if only = conditions[:only]
+ return only.include?(action_name)
+ elsif except = conditions[:except]
+ return !except.include?(action_name)
end
- else
- true
end
+ true
end
- def candidate_for_layout?(options)
- template = options[:template] || default_template(options[:action])
- if options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty?
- begin
- template_object = self.view_paths.find_template(template, default_template_format)
- # this restores the behavior from 2.2.2, where response.template.template_format was reset
- # to :html for :js requests with a matching html template.
- # see v2.2.2, ActionView::Base, lines 328-330
- @real_format = :html if response.template.template_format == :js && template_object.format == "html"
- !template_object.exempt_from_layout?
- rescue ActionView::MissingTemplate
- true
- end
- end
- rescue ActionView::MissingTemplate
- false
- end
-
- def default_template_format
- @real_format || response.template.template_format
- end
end
end
View
9 ...ck/lib/action_controller/mime_responds.rb → ...b/action_controller/base/mime_responds.rb
@@ -109,16 +109,13 @@ def respond_to(*types, &block)
end
class Responder #:nodoc:
+
def initialize(controller)
@controller = controller
@request = controller.request
@response = controller.response
- if ActionController::Base.use_accept_header
- @mime_type_priority = Array(Mime::Type.lookup_by_extension(@request.parameters[:format]) || @request.accepts)
- else
- @mime_type_priority = [@request.format]
- end
+ @mime_type_priority = @request.formats
@order = []
@responses = {}
@@ -130,7 +127,7 @@ def custom(mime_type, &block)
@order << mime_type
@responses[mime_type] ||= Proc.new do
- @response.template.template_format = mime_type.to_sym
+ @response.template.formats = [mime_type.to_sym]
@response.content_type = mime_type.to_s
block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
end