actionpack 2.3.18 → 3.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. data/CHANGELOG +15 -64
  2. data/README +39 -48
  3. data/lib/abstract_controller.rb +22 -0
  4. data/lib/abstract_controller/base.rb +191 -0
  5. data/lib/abstract_controller/callbacks.rb +113 -0
  6. data/lib/abstract_controller/collector.rb +30 -0
  7. data/lib/abstract_controller/compatibility.rb +18 -0
  8. data/lib/abstract_controller/helpers.rb +163 -0
  9. data/lib/abstract_controller/layouts.rb +413 -0
  10. data/lib/abstract_controller/localized_cache.rb +49 -0
  11. data/lib/abstract_controller/logger.rb +13 -0
  12. data/lib/abstract_controller/rendering.rb +238 -0
  13. data/lib/{action_controller → abstract_controller}/translation.rb +1 -1
  14. data/lib/action_controller.rb +68 -102
  15. data/lib/action_controller/base.rb +77 -1409
  16. data/lib/action_controller/caching.rb +58 -45
  17. data/lib/action_controller/caching/actions.rb +100 -114
  18. data/lib/action_controller/caching/fragments.rb +17 -19
  19. data/lib/action_controller/caching/pages.rb +12 -6
  20. data/lib/action_controller/caching/sweeping.rb +42 -0
  21. data/lib/action_controller/deprecated.rb +5 -0
  22. data/lib/action_controller/deprecated/dispatcher.rb +28 -0
  23. data/lib/action_controller/deprecated/integration_test.rb +2 -0
  24. data/lib/action_controller/deprecated/performance_test.rb +1 -0
  25. data/lib/action_controller/metal.rb +125 -0
  26. data/lib/action_controller/metal/compatibility.rb +141 -0
  27. data/lib/action_controller/metal/conditional_get.rb +86 -0
  28. data/lib/action_controller/metal/configuration.rb +28 -0
  29. data/lib/action_controller/metal/cookies.rb +17 -0
  30. data/lib/action_controller/metal/exceptions.rb +46 -0
  31. data/lib/action_controller/metal/flash.rb +28 -0
  32. data/lib/action_controller/metal/head.rb +33 -0
  33. data/lib/action_controller/metal/helpers.rb +116 -0
  34. data/lib/action_controller/metal/hide_actions.rb +50 -0
  35. data/lib/action_controller/{http_authentication.rb → metal/http_authentication.rb} +18 -15
  36. data/lib/action_controller/metal/instrumentation.rb +99 -0
  37. data/lib/action_controller/metal/mime_responds.rb +300 -0
  38. data/lib/action_controller/metal/rack_delegation.rb +35 -0
  39. data/lib/action_controller/metal/redirecting.rb +90 -0
  40. data/lib/action_controller/metal/renderers.rb +95 -0
  41. data/lib/action_controller/metal/rendering.rb +69 -0
  42. data/lib/action_controller/metal/request_forgery_protection.rb +115 -0
  43. data/lib/action_controller/metal/rescue.rb +13 -0
  44. data/lib/action_controller/metal/responder.rb +220 -0
  45. data/lib/action_controller/{session_management.rb → metal/session_management.rb} +5 -14
  46. data/lib/action_controller/{streaming.rb → metal/streaming.rb} +13 -12
  47. data/lib/action_controller/metal/testing.rb +42 -0
  48. data/lib/action_controller/metal/url_for.rb +157 -0
  49. data/lib/action_controller/{verification.rb → metal/verification.rb} +41 -41
  50. data/lib/action_controller/middleware.rb +38 -0
  51. data/lib/action_controller/polymorphic_routes.rb +20 -26
  52. data/lib/action_controller/railtie.rb +30 -0
  53. data/lib/action_controller/railties/subscriber.rb +63 -0
  54. data/lib/action_controller/record_identifier.rb +3 -16
  55. data/lib/action_controller/test_case.rb +156 -18
  56. data/lib/action_controller/url_rewriter.rb +47 -200
  57. data/lib/action_controller/vendor/html-scanner.rb +16 -12
  58. data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
  59. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +12 -9
  60. data/lib/action_dispatch.rb +88 -0
  61. data/lib/action_dispatch/http/cache.rb +123 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +98 -0
  63. data/lib/{action_controller → action_dispatch/http}/headers.rb +8 -8
  64. data/lib/action_dispatch/http/mime_negotiation.rb +101 -0
  65. data/lib/{action_controller → action_dispatch/http}/mime_type.rb +30 -11
  66. data/lib/{action_controller → action_dispatch/http}/mime_types.rb +5 -3
  67. data/lib/action_dispatch/http/parameters.rb +49 -0
  68. data/lib/action_dispatch/http/request.rb +223 -0
  69. data/lib/action_dispatch/http/response.rb +209 -0
  70. data/lib/action_dispatch/http/upload.rb +48 -0
  71. data/lib/action_dispatch/http/url.rb +129 -0
  72. data/lib/action_dispatch/middleware/callbacks.rb +50 -0
  73. data/lib/action_dispatch/middleware/cascade.rb +29 -0
  74. data/lib/action_dispatch/middleware/cookies.rb +216 -0
  75. data/lib/{action_controller → action_dispatch/middleware}/flash.rb +51 -90
  76. data/lib/action_dispatch/middleware/head.rb +18 -0
  77. data/lib/action_dispatch/middleware/params_parser.rb +78 -0
  78. data/lib/action_dispatch/middleware/rescue.rb +26 -0
  79. data/lib/action_dispatch/middleware/session/abstract_store.rb +209 -0
  80. data/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb +56 -60
  81. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
  82. data/lib/action_dispatch/middleware/show_exceptions.rb +173 -0
  83. data/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb} +23 -13
  84. data/lib/action_dispatch/middleware/static.rb +44 -0
  85. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_request_and_response.erb +10 -3
  86. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_trace.erb +4 -4
  87. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
  88. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/layout.erb +2 -2
  89. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/missing_template.erb +0 -0
  90. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/routing_error.erb +0 -0
  91. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/template_error.erb +3 -3
  92. data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/unknown_action.erb +0 -0
  93. data/lib/action_dispatch/railtie.rb +15 -0
  94. data/lib/action_dispatch/routing.rb +217 -0
  95. data/lib/action_dispatch/routing/deprecated_mapper.rb +877 -0
  96. data/lib/action_dispatch/routing/mapper.rb +649 -0
  97. data/lib/action_dispatch/routing/route.rb +55 -0
  98. data/lib/action_dispatch/routing/route_set.rb +445 -0
  99. data/lib/action_dispatch/testing/assertions.rb +21 -0
  100. data/lib/action_dispatch/testing/assertions/dom.rb +37 -0
  101. data/lib/{action_controller/assertions/model_assertions.rb → action_dispatch/testing/assertions/model.rb} +2 -4
  102. data/lib/action_dispatch/testing/assertions/response.rb +154 -0
  103. data/lib/{action_controller/assertions/routing_assertions.rb → action_dispatch/testing/assertions/routing.rb} +72 -34
  104. data/lib/{action_controller/assertions/selector_assertions.rb → action_dispatch/testing/assertions/selector.rb} +14 -11
  105. data/lib/{action_controller/assertions/tag_assertions.rb → action_dispatch/testing/assertions/tag.rb} +25 -14
  106. data/lib/{action_controller → action_dispatch/testing}/integration.rb +173 -406
  107. data/lib/action_dispatch/testing/performance_test.rb +17 -0
  108. data/lib/action_dispatch/testing/test_process.rb +42 -0
  109. data/lib/action_dispatch/testing/test_request.rb +83 -0
  110. data/lib/action_dispatch/testing/test_response.rb +136 -0
  111. data/lib/action_pack/version.rb +3 -3
  112. data/lib/action_view.rb +29 -26
  113. data/lib/action_view/base.rb +101 -148
  114. data/lib/action_view/context.rb +44 -0
  115. data/lib/action_view/helpers.rb +6 -4
  116. data/lib/action_view/helpers/{active_record_helper.rb → active_model_helper.rb} +63 -63
  117. data/lib/action_view/helpers/asset_tag_helper.rb +166 -31
  118. data/lib/action_view/helpers/cache_helper.rb +1 -1
  119. data/lib/action_view/helpers/capture_helper.rb +40 -8
  120. data/lib/action_view/helpers/csrf_helper.rb +2 -4
  121. data/lib/action_view/helpers/date_helper.rb +14 -15
  122. data/lib/action_view/helpers/form_helper.rb +121 -24
  123. data/lib/action_view/helpers/form_options_helper.rb +26 -25
  124. data/lib/action_view/helpers/form_tag_helper.rb +42 -33
  125. data/lib/action_view/helpers/javascript_helper.rb +1 -109
  126. data/lib/action_view/helpers/number_helper.rb +4 -1
  127. data/lib/action_view/helpers/prototype_helper.rb +75 -499
  128. data/lib/action_view/helpers/raw_output_helper.rb +1 -1
  129. data/lib/action_view/helpers/record_tag_helper.rb +3 -3
  130. data/lib/action_view/helpers/sanitize_helper.rb +3 -2
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +89 -53
  132. data/lib/action_view/helpers/tag_helper.rb +12 -13
  133. data/lib/action_view/helpers/text_helper.rb +33 -38
  134. data/lib/action_view/helpers/translation_helper.rb +11 -35
  135. data/lib/action_view/helpers/url_helper.rb +140 -134
  136. data/lib/action_view/locale/en.yml +34 -28
  137. data/lib/action_view/paths.rb +27 -24
  138. data/lib/action_view/railtie.rb +17 -0
  139. data/lib/action_view/railties/subscriber.rb +24 -0
  140. data/lib/action_view/{partials.rb → render/partials.rb} +161 -51
  141. data/lib/action_view/render/rendering.rb +117 -0
  142. data/lib/action_view/template.rb +88 -217
  143. data/lib/action_view/template/error.rb +105 -0
  144. data/lib/action_view/template/handler.rb +41 -0
  145. data/lib/action_view/template/handlers.rb +54 -0
  146. data/lib/action_view/{template_handlers → template/handlers}/builder.rb +6 -6
  147. data/lib/action_view/template/handlers/erb.rb +58 -0
  148. data/lib/action_view/{template_handlers → template/handlers}/rjs.rb +8 -3
  149. data/lib/action_view/template/resolver.rb +164 -0
  150. data/lib/action_view/template/text.rb +40 -0
  151. data/lib/action_view/test_case.rb +18 -18
  152. metadata +165 -420
  153. data/RUNNING_UNIT_TESTS +0 -24
  154. data/Rakefile +0 -158
  155. data/install.rb +0 -30
  156. data/lib/action_controller/assertions/dom_assertions.rb +0 -55
  157. data/lib/action_controller/assertions/response_assertions.rb +0 -169
  158. data/lib/action_controller/benchmarking.rb +0 -107
  159. data/lib/action_controller/caching/sweeper.rb +0 -45
  160. data/lib/action_controller/cgi_ext.rb +0 -15
  161. data/lib/action_controller/cgi_ext/cookie.rb +0 -112
  162. data/lib/action_controller/cgi_ext/query_extension.rb +0 -22
  163. data/lib/action_controller/cgi_ext/stdinput.rb +0 -24
  164. data/lib/action_controller/cgi_process.rb +0 -77
  165. data/lib/action_controller/cookies.rb +0 -197
  166. data/lib/action_controller/dispatcher.rb +0 -133
  167. data/lib/action_controller/failsafe.rb +0 -87
  168. data/lib/action_controller/filters.rb +0 -680
  169. data/lib/action_controller/helpers.rb +0 -225
  170. data/lib/action_controller/layout.rb +0 -286
  171. data/lib/action_controller/middlewares.rb +0 -14
  172. data/lib/action_controller/mime_responds.rb +0 -193
  173. data/lib/action_controller/params_parser.rb +0 -77
  174. data/lib/action_controller/performance_test.rb +0 -15
  175. data/lib/action_controller/rack_lint_patch.rb +0 -36
  176. data/lib/action_controller/reloader.rb +0 -54
  177. data/lib/action_controller/request.rb +0 -518
  178. data/lib/action_controller/request_forgery_protection.rb +0 -116
  179. data/lib/action_controller/rescue.rb +0 -183
  180. data/lib/action_controller/resources.rb +0 -682
  181. data/lib/action_controller/response.rb +0 -237
  182. data/lib/action_controller/routing.rb +0 -388
  183. data/lib/action_controller/routing/builder.rb +0 -197
  184. data/lib/action_controller/routing/optimisations.rb +0 -130
  185. data/lib/action_controller/routing/recognition_optimisation.rb +0 -167
  186. data/lib/action_controller/routing/route.rb +0 -265
  187. data/lib/action_controller/routing/route_set.rb +0 -503
  188. data/lib/action_controller/routing/routing_ext.rb +0 -49
  189. data/lib/action_controller/routing/segments.rb +0 -343
  190. data/lib/action_controller/session/abstract_store.rb +0 -276
  191. data/lib/action_controller/session/mem_cache_store.rb +0 -60
  192. data/lib/action_controller/status_codes.rb +0 -88
  193. data/lib/action_controller/string_coercion.rb +0 -29
  194. data/lib/action_controller/templates/rescues/diagnostics.erb +0 -11
  195. data/lib/action_controller/test_process.rb +0 -580
  196. data/lib/action_controller/uploaded_file.rb +0 -44
  197. data/lib/action_view/helpers/benchmark_helper.rb +0 -54
  198. data/lib/action_view/inline_template.rb +0 -19
  199. data/lib/action_view/reloadable_template.rb +0 -117
  200. data/lib/action_view/renderable.rb +0 -109
  201. data/lib/action_view/renderable_partial.rb +0 -53
  202. data/lib/action_view/template_error.rb +0 -99
  203. data/lib/action_view/template_handler.rb +0 -34
  204. data/lib/action_view/template_handlers.rb +0 -48
  205. data/lib/action_view/template_handlers/erb.rb +0 -25
  206. data/lib/actionpack.rb +0 -2
  207. data/test/abstract_unit.rb +0 -78
  208. data/test/active_record_unit.rb +0 -104
  209. data/test/activerecord/active_record_store_test.rb +0 -221
  210. data/test/activerecord/render_partial_with_record_identification_test.rb +0 -188
  211. data/test/adv_attr_test.rb +0 -20
  212. data/test/controller/action_pack_assertions_test.rb +0 -545
  213. data/test/controller/addresses_render_test.rb +0 -37
  214. data/test/controller/assert_select_test.rb +0 -735
  215. data/test/controller/base_test.rb +0 -217
  216. data/test/controller/benchmark_test.rb +0 -32
  217. data/test/controller/caching_test.rb +0 -743
  218. data/test/controller/capture_test.rb +0 -66
  219. data/test/controller/content_type_test.rb +0 -178
  220. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  221. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  222. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  223. data/test/controller/cookie_test.rb +0 -208
  224. data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -32
  225. data/test/controller/dispatcher_test.rb +0 -144
  226. data/test/controller/dom_assertions_test.rb +0 -53
  227. data/test/controller/failsafe_test.rb +0 -60
  228. data/test/controller/fake_controllers.rb +0 -33
  229. data/test/controller/fake_models.rb +0 -19
  230. data/test/controller/filter_params_test.rb +0 -52
  231. data/test/controller/filters_test.rb +0 -885
  232. data/test/controller/flash_test.rb +0 -174
  233. data/test/controller/header_test.rb +0 -14
  234. data/test/controller/helper_test.rb +0 -224
  235. data/test/controller/html-scanner/cdata_node_test.rb +0 -15
  236. data/test/controller/html-scanner/document_test.rb +0 -148
  237. data/test/controller/html-scanner/node_test.rb +0 -89
  238. data/test/controller/html-scanner/sanitizer_test.rb +0 -300
  239. data/test/controller/html-scanner/tag_node_test.rb +0 -238
  240. data/test/controller/html-scanner/text_node_test.rb +0 -50
  241. data/test/controller/html-scanner/tokenizer_test.rb +0 -131
  242. data/test/controller/http_basic_authentication_test.rb +0 -113
  243. data/test/controller/http_digest_authentication_test.rb +0 -254
  244. data/test/controller/integration_test.rb +0 -526
  245. data/test/controller/layout_test.rb +0 -215
  246. data/test/controller/localized_templates_test.rb +0 -24
  247. data/test/controller/logging_test.rb +0 -46
  248. data/test/controller/middleware_stack_test.rb +0 -90
  249. data/test/controller/mime_responds_test.rb +0 -536
  250. data/test/controller/mime_type_test.rb +0 -93
  251. data/test/controller/output_escaping_test.rb +0 -19
  252. data/test/controller/polymorphic_routes_test.rb +0 -297
  253. data/test/controller/rack_test.rb +0 -308
  254. data/test/controller/record_identifier_test.rb +0 -139
  255. data/test/controller/redirect_test.rb +0 -285
  256. data/test/controller/reloader_test.rb +0 -125
  257. data/test/controller/render_test.rb +0 -1783
  258. data/test/controller/request/json_params_parsing_test.rb +0 -65
  259. data/test/controller/request/multipart_params_parsing_test.rb +0 -177
  260. data/test/controller/request/query_string_parsing_test.rb +0 -129
  261. data/test/controller/request/test_request_test.rb +0 -35
  262. data/test/controller/request/url_encoded_params_parsing_test.rb +0 -146
  263. data/test/controller/request/xml_params_parsing_test.rb +0 -103
  264. data/test/controller/request_forgery_protection_test.rb +0 -233
  265. data/test/controller/request_test.rb +0 -398
  266. data/test/controller/rescue_test.rb +0 -541
  267. data/test/controller/resources_test.rb +0 -1393
  268. data/test/controller/routing_test.rb +0 -2592
  269. data/test/controller/selector_test.rb +0 -628
  270. data/test/controller/send_file_test.rb +0 -171
  271. data/test/controller/session/abstract_store_test.rb +0 -64
  272. data/test/controller/session/cookie_store_test.rb +0 -354
  273. data/test/controller/session/mem_cache_store_test.rb +0 -187
  274. data/test/controller/session/test_session_test.rb +0 -58
  275. data/test/controller/test_test.rb +0 -700
  276. data/test/controller/translation_test.rb +0 -26
  277. data/test/controller/url_rewriter_test.rb +0 -395
  278. data/test/controller/verification_test.rb +0 -270
  279. data/test/controller/view_paths_test.rb +0 -141
  280. data/test/controller/webservice_test.rb +0 -273
  281. data/test/fixtures/_top_level_partial.html.erb +0 -1
  282. data/test/fixtures/_top_level_partial_only.erb +0 -1
  283. data/test/fixtures/addresses/list.erb +0 -1
  284. data/test/fixtures/alternate_helpers/foo_helper.rb +0 -3
  285. data/test/fixtures/bad_customers/_bad_customer.html.erb +0 -1
  286. data/test/fixtures/companies.yml +0 -24
  287. data/test/fixtures/company.rb +0 -10
  288. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +0 -1
  289. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +0 -1
  290. data/test/fixtures/content_type/render_default_for_rjs.rjs +0 -1
  291. data/test/fixtures/content_type/render_default_for_rxml.rxml +0 -1
  292. data/test/fixtures/customers/_customer.html.erb +0 -1
  293. data/test/fixtures/db_definitions/sqlite.sql +0 -49
  294. data/test/fixtures/developer.rb +0 -9
  295. data/test/fixtures/developers.yml +0 -21
  296. data/test/fixtures/developers/_developer.erb +0 -1
  297. data/test/fixtures/developers_projects.yml +0 -13
  298. data/test/fixtures/failsafe/500.html +0 -1
  299. data/test/fixtures/fun/games/_game.erb +0 -1
  300. data/test/fixtures/fun/games/hello_world.erb +0 -1
  301. data/test/fixtures/fun/serious/games/_game.erb +0 -1
  302. data/test/fixtures/functional_caching/_partial.erb +0 -3
  303. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +0 -3
  304. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +0 -6
  305. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +0 -5
  306. data/test/fixtures/functional_caching/fragment_cached.html.erb +0 -2
  307. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +0 -1
  308. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +0 -2
  309. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +0 -1
  310. data/test/fixtures/good_customers/_good_customer.html.erb +0 -1
  311. data/test/fixtures/helpers/abc_helper.rb +0 -5
  312. data/test/fixtures/helpers/fun/games_helper.rb +0 -3
  313. data/test/fixtures/helpers/fun/pdf_helper.rb +0 -3
  314. data/test/fixtures/layout_tests/abs_path_layout.rhtml +0 -1
  315. data/test/fixtures/layout_tests/alt/hello.rhtml +0 -1
  316. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  317. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +0 -1
  318. data/test/fixtures/layout_tests/layouts/item.rhtml +0 -1
  319. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +0 -1
  320. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +0 -1
  321. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +0 -1
  322. data/test/fixtures/layout_tests/views/hello.rhtml +0 -1
  323. data/test/fixtures/layouts/_column.html.erb +0 -2
  324. data/test/fixtures/layouts/block_with_layout.erb +0 -3
  325. data/test/fixtures/layouts/builder.builder +0 -3
  326. data/test/fixtures/layouts/default_html.html.erb +0 -1
  327. data/test/fixtures/layouts/partial_with_layout.erb +0 -3
  328. data/test/fixtures/layouts/standard.erb +0 -1
  329. data/test/fixtures/layouts/talk_from_action.erb +0 -2
  330. data/test/fixtures/layouts/xhr.html.erb +0 -2
  331. data/test/fixtures/layouts/yield.erb +0 -2
  332. data/test/fixtures/localized/hello_world.de.html +0 -1
  333. data/test/fixtures/localized/hello_world.en.html +0 -1
  334. data/test/fixtures/mascot.rb +0 -3
  335. data/test/fixtures/mascots.yml +0 -4
  336. data/test/fixtures/mascots/_mascot.html.erb +0 -1
  337. data/test/fixtures/multipart/binary_file +0 -0
  338. data/test/fixtures/multipart/boundary_problem_file +0 -10
  339. data/test/fixtures/multipart/bracketed_param +0 -5
  340. data/test/fixtures/multipart/empty +0 -10
  341. data/test/fixtures/multipart/hello.txt +0 -1
  342. data/test/fixtures/multipart/large_text_file +0 -10
  343. data/test/fixtures/multipart/mixed_files +0 -0
  344. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  345. data/test/fixtures/multipart/none +0 -9
  346. data/test/fixtures/multipart/single_parameter +0 -5
  347. data/test/fixtures/multipart/text_file +0 -10
  348. data/test/fixtures/override/test/hello_world.erb +0 -1
  349. data/test/fixtures/override2/layouts/test/sub.erb +0 -1
  350. data/test/fixtures/post_test/layouts/post.html.erb +0 -1
  351. data/test/fixtures/post_test/layouts/super_post.iphone.erb +0 -1
  352. data/test/fixtures/post_test/post/index.html.erb +0 -1
  353. data/test/fixtures/post_test/post/index.iphone.erb +0 -1
  354. data/test/fixtures/post_test/super_post/index.html.erb +0 -1
  355. data/test/fixtures/post_test/super_post/index.iphone.erb +0 -1
  356. data/test/fixtures/project.rb +0 -3
  357. data/test/fixtures/projects.yml +0 -7
  358. data/test/fixtures/projects/_project.erb +0 -1
  359. data/test/fixtures/public/404.html +0 -1
  360. data/test/fixtures/public/500.da.html +0 -1
  361. data/test/fixtures/public/500.html +0 -1
  362. data/test/fixtures/public/absolute/test.css +0 -23
  363. data/test/fixtures/public/absolute/test.js +0 -63
  364. data/test/fixtures/public/images/rails.png +0 -0
  365. data/test/fixtures/public/javascripts/application.js +0 -1
  366. data/test/fixtures/public/javascripts/bank.js +0 -1
  367. data/test/fixtures/public/javascripts/controls.js +0 -1
  368. data/test/fixtures/public/javascripts/dragdrop.js +0 -1
  369. data/test/fixtures/public/javascripts/effects.js +0 -1
  370. data/test/fixtures/public/javascripts/prototype.js +0 -1
  371. data/test/fixtures/public/javascripts/robber.js +0 -1
  372. data/test/fixtures/public/javascripts/subdir/subdir.js +0 -1
  373. data/test/fixtures/public/javascripts/version.1.0.js +0 -1
  374. data/test/fixtures/public/stylesheets/bank.css +0 -1
  375. data/test/fixtures/public/stylesheets/robber.css +0 -1
  376. data/test/fixtures/public/stylesheets/subdir/subdir.css +0 -1
  377. data/test/fixtures/public/stylesheets/version.1.0.css +0 -1
  378. data/test/fixtures/quiz/questions/_question.html.erb +0 -1
  379. data/test/fixtures/replies.yml +0 -15
  380. data/test/fixtures/replies/_reply.erb +0 -1
  381. data/test/fixtures/reply.rb +0 -7
  382. data/test/fixtures/respond_to/all_types_with_layout.html.erb +0 -1
  383. data/test/fixtures/respond_to/all_types_with_layout.js.rjs +0 -1
  384. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +0 -1
  385. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +0 -1
  386. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +0 -1
  387. data/test/fixtures/respond_to/layouts/missing.html.erb +0 -1
  388. data/test/fixtures/respond_to/layouts/standard.html.erb +0 -1
  389. data/test/fixtures/respond_to/layouts/standard.iphone.erb +0 -1
  390. data/test/fixtures/respond_to/using_defaults.html.erb +0 -1
  391. data/test/fixtures/respond_to/using_defaults.js.rjs +0 -1
  392. data/test/fixtures/respond_to/using_defaults.xml.builder +0 -1
  393. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +0 -1
  394. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +0 -1
  395. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +0 -1
  396. data/test/fixtures/scope/test/modgreet.erb +0 -1
  397. data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +0 -10
  398. data/test/fixtures/shared.html.erb +0 -1
  399. data/test/fixtures/symlink_parent/symlinked_layout.erb +0 -5
  400. data/test/fixtures/test/_counter.html.erb +0 -1
  401. data/test/fixtures/test/_customer.erb +0 -1
  402. data/test/fixtures/test/_customer_counter.erb +0 -1
  403. data/test/fixtures/test/_customer_counter_with_as.erb +0 -1
  404. data/test/fixtures/test/_customer_greeting.erb +0 -1
  405. data/test/fixtures/test/_customer_with_var.erb +0 -1
  406. data/test/fixtures/test/_form.erb +0 -1
  407. data/test/fixtures/test/_from_helper.erb +0 -1
  408. data/test/fixtures/test/_hash_greeting.erb +0 -1
  409. data/test/fixtures/test/_hash_object.erb +0 -2
  410. data/test/fixtures/test/_hello.builder +0 -1
  411. data/test/fixtures/test/_labelling_form.erb +0 -1
  412. data/test/fixtures/test/_layout_for_block_with_args.html.erb +0 -3
  413. data/test/fixtures/test/_layout_for_partial.html.erb +0 -3
  414. data/test/fixtures/test/_local_inspector.html.erb +0 -1
  415. data/test/fixtures/test/_one.html.erb +0 -1
  416. data/test/fixtures/test/_partial.erb +0 -1
  417. data/test/fixtures/test/_partial.html.erb +0 -1
  418. data/test/fixtures/test/_partial.js.erb +0 -1
  419. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +0 -1
  420. data/test/fixtures/test/_partial_only.erb +0 -1
  421. data/test/fixtures/test/_partial_with_only_html_version.html.erb +0 -1
  422. data/test/fixtures/test/_person.erb +0 -2
  423. data/test/fixtures/test/_raise.html.erb +0 -1
  424. data/test/fixtures/test/_two.html.erb +0 -1
  425. data/test/fixtures/test/_utf8_partial.html.erb +0 -1
  426. data/test/fixtures/test/_utf8_partial_magic.html.erb +0 -2
  427. data/test/fixtures/test/action_talk_to_layout.erb +0 -2
  428. data/test/fixtures/test/array_translation.erb +0 -1
  429. data/test/fixtures/test/calling_partial_with_layout.html.erb +0 -1
  430. data/test/fixtures/test/capturing.erb +0 -4
  431. data/test/fixtures/test/content_for.erb +0 -2
  432. data/test/fixtures/test/content_for_concatenated.erb +0 -3
  433. data/test/fixtures/test/content_for_with_parameter.erb +0 -2
  434. data/test/fixtures/test/delete_with_js.rjs +0 -2
  435. data/test/fixtures/test/dont_pick_me +0 -1
  436. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +0 -1
  437. data/test/fixtures/test/enum_rjs_test.rjs +0 -6
  438. data/test/fixtures/test/formatted_html_erb.html.erb +0 -1
  439. data/test/fixtures/test/formatted_xml_erb.builder +0 -1
  440. data/test/fixtures/test/formatted_xml_erb.html.erb +0 -1
  441. data/test/fixtures/test/formatted_xml_erb.xml.erb +0 -1
  442. data/test/fixtures/test/greeting.erb +0 -1
  443. data/test/fixtures/test/greeting.js.rjs +0 -1
  444. data/test/fixtures/test/hello.builder +0 -4
  445. data/test/fixtures/test/hello_world.da.html.erb +0 -1
  446. data/test/fixtures/test/hello_world.erb +0 -1
  447. data/test/fixtures/test/hello_world.erb~ +0 -1
  448. data/test/fixtures/test/hello_world.pt-BR.html.erb +0 -1
  449. data/test/fixtures/test/hello_world_container.builder +0 -3
  450. data/test/fixtures/test/hello_world_from_rxml.builder +0 -4
  451. data/test/fixtures/test/hello_world_with_layout_false.erb +0 -1
  452. data/test/fixtures/test/hello_xml_world.builder +0 -11
  453. data/test/fixtures/test/hyphen-ated.erb +0 -1
  454. data/test/fixtures/test/implicit_content_type.atom.builder +0 -2
  455. data/test/fixtures/test/list.erb +0 -1
  456. data/test/fixtures/test/malformed/malformed.en.html.erb~ +0 -1
  457. data/test/fixtures/test/malformed/malformed.erb~ +0 -1
  458. data/test/fixtures/test/malformed/malformed.html.erb~ +0 -1
  459. data/test/fixtures/test/nested_layout.erb +0 -3
  460. data/test/fixtures/test/non_erb_block_content_for.builder +0 -4
  461. data/test/fixtures/test/potential_conflicts.erb +0 -4
  462. data/test/fixtures/test/render_explicit_html_template.js.rjs +0 -1
  463. data/test/fixtures/test/render_file_from_template.html.erb +0 -1
  464. data/test/fixtures/test/render_file_with_ivar.erb +0 -1
  465. data/test/fixtures/test/render_file_with_locals.erb +0 -1
  466. data/test/fixtures/test/render_implicit_html_template.js.rjs +0 -1
  467. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +0 -1
  468. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +0 -1
  469. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +0 -1
  470. data/test/fixtures/test/render_to_string_test.erb +0 -1
  471. data/test/fixtures/test/scoped_array_translation.erb +0 -1
  472. data/test/fixtures/test/sub_template_raise.html.erb +0 -1
  473. data/test/fixtures/test/template.erb +0 -1
  474. data/test/fixtures/test/translation.erb +0 -1
  475. data/test/fixtures/test/update_element_with_capture.erb +0 -9
  476. data/test/fixtures/test/using_layout_around_block.html.erb +0 -1
  477. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +0 -1
  478. data/test/fixtures/test/utf8.html.erb +0 -4
  479. data/test/fixtures/test/utf8_magic.html.erb +0 -5
  480. data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +0 -5
  481. data/test/fixtures/topic.rb +0 -3
  482. data/test/fixtures/topics.yml +0 -22
  483. data/test/fixtures/topics/_topic.html.erb +0 -1
  484. data/test/template/active_record_helper_i18n_test.rb +0 -51
  485. data/test/template/active_record_helper_test.rb +0 -302
  486. data/test/template/asset_tag_helper_test.rb +0 -770
  487. data/test/template/atom_feed_helper_test.rb +0 -315
  488. data/test/template/benchmark_helper_test.rb +0 -86
  489. data/test/template/compiled_templates_test.rb +0 -204
  490. data/test/template/date_helper_i18n_test.rb +0 -121
  491. data/test/template/date_helper_test.rb +0 -2603
  492. data/test/template/erb_util_test.rb +0 -36
  493. data/test/template/form_helper_test.rb +0 -1447
  494. data/test/template/form_options_helper_i18n_test.rb +0 -27
  495. data/test/template/form_options_helper_test.rb +0 -811
  496. data/test/template/form_tag_helper_test.rb +0 -356
  497. data/test/template/javascript_helper_test.rb +0 -106
  498. data/test/template/number_helper_i18n_test.rb +0 -69
  499. data/test/template/number_helper_test.rb +0 -132
  500. data/test/template/prototype_helper_test.rb +0 -639
  501. data/test/template/raw_output_helper_test.rb +0 -21
  502. data/test/template/record_tag_helper_test.rb +0 -58
  503. data/test/template/render_test.rb +0 -329
  504. data/test/template/sanitize_helper_test.rb +0 -57
  505. data/test/template/scriptaculous_helper_test.rb +0 -90
  506. data/test/template/tag_helper_test.rb +0 -98
  507. data/test/template/template_test.rb +0 -32
  508. data/test/template/test_test.rb +0 -54
  509. data/test/template/text_helper_test.rb +0 -601
  510. data/test/template/translation_helper_test.rb +0 -95
  511. data/test/template/url_helper_test.rb +0 -641
  512. data/test/testing_sandbox.rb +0 -15
  513. data/test/view/test_case_test.rb +0 -176
@@ -0,0 +1,113 @@
1
+ module AbstractController
2
+ module Callbacks
3
+ extend ActiveSupport::Concern
4
+
5
+ # Uses ActiveSupport::Callbacks as the base functionality. For
6
+ # more details on the whole callback system, read the documentation
7
+ # for ActiveSupport::Callbacks.
8
+ include ActiveSupport::Callbacks
9
+
10
+ included do
11
+ define_callbacks :process_action, :terminator => "response_body"
12
+ end
13
+
14
+ # Override AbstractController::Base's process_action to run the
15
+ # process_action callbacks around the normal behavior.
16
+ def process_action(method_name)
17
+ run_callbacks(:process_action, method_name) do
18
+ super
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ # If :only or :accept are used, convert the options into the
24
+ # primitive form (:per_key) used by ActiveSupport::Callbacks.
25
+ # The basic idea is that :only => :index gets converted to
26
+ # :if => proc {|c| c.action_name == "index" }, but that the
27
+ # proc is only evaluated once per action for the lifetime of
28
+ # a Rails process.
29
+ #
30
+ # ==== Options
31
+ # :only<#to_s>:: The callback should be run only for this action
32
+ # :except<#to_s>:: The callback should be run for all actions
33
+ # except this action
34
+ def _normalize_callback_options(options)
35
+ if only = options[:only]
36
+ only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ")
37
+ options[:per_key] = {:if => only}
38
+ end
39
+ if except = options[:except]
40
+ except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
41
+ options[:per_key] = {:unless => except}
42
+ end
43
+ end
44
+
45
+ # Skip before, after, and around filters matching any of the names
46
+ #
47
+ # ==== Parameters
48
+ # *names<Object>:: A list of valid names that could be used for
49
+ # callbacks. Note that skipping uses Ruby equality, so it's
50
+ # impossible to skip a callback defined using an anonymous proc
51
+ # using #skip_filter
52
+ def skip_filter(*names, &blk)
53
+ skip_before_filter(*names)
54
+ skip_after_filter(*names)
55
+ skip_around_filter(*names)
56
+ end
57
+
58
+ # Take callback names and an optional callback proc, normalize them,
59
+ # then call the block with each callback. This allows us to abstract
60
+ # the normalization across several methods that use it.
61
+ #
62
+ # ==== Parameters
63
+ # callbacks<Array[*Object, Hash]>:: A list of callbacks, with an optional
64
+ # options hash as the last parameter.
65
+ # block<Proc>:: A proc that should be added to the callbacks.
66
+ #
67
+ # ==== Block Parameters
68
+ # name<Symbol>:: The callback to be added
69
+ # options<Hash>:: A list of options to be used when adding the callback
70
+ def _insert_callbacks(callbacks, block)
71
+ options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
72
+ _normalize_callback_options(options)
73
+ callbacks.push(block) if block
74
+ callbacks.each do |callback|
75
+ yield callback, options
76
+ end
77
+ end
78
+
79
+ # set up before_filter, prepend_before_filter, skip_before_filter, etc.
80
+ # for each of before, after, and around.
81
+ [:before, :after, :around].each do |filter|
82
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
83
+ # Append a before, after or around filter. See _insert_callbacks
84
+ # for details on the allowed parameters.
85
+ def #{filter}_filter(*names, &blk)
86
+ _insert_callbacks(names, blk) do |name, options|
87
+ set_callback(:process_action, :#{filter}, name, options)
88
+ end
89
+ end
90
+
91
+ # Prepend a before, after or around filter. See _insert_callbacks
92
+ # for details on the allowed parameters.
93
+ def prepend_#{filter}_filter(*names, &blk)
94
+ _insert_callbacks(names, blk) do |name, options|
95
+ set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
96
+ end
97
+ end
98
+
99
+ # Skip a before, after or around filter. See _insert_callbacks
100
+ # for details on the allowed parameters.
101
+ def skip_#{filter}_filter(*names, &blk)
102
+ _insert_callbacks(names, blk) do |name, options|
103
+ skip_callback(:process_action, :#{filter}, name, options)
104
+ end
105
+ end
106
+
107
+ # *_filter is the same as append_*_filter
108
+ alias_method :append_#{filter}_filter, :#{filter}_filter
109
+ RUBY_EVAL
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,30 @@
1
+ module AbstractController
2
+ module Collector
3
+ def self.generate_method_for_mime(mime)
4
+ sym = mime.is_a?(Symbol) ? mime : mime.to_sym
5
+ const = sym.to_s.upcase
6
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
7
+ def #{sym}(*args, &block) # def html(*args, &block)
8
+ custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block)
9
+ end # end
10
+ RUBY
11
+ end
12
+
13
+ Mime::SET.each do |mime|
14
+ generate_method_for_mime(mime)
15
+ end
16
+
17
+ protected
18
+
19
+ def method_missing(symbol, &block)
20
+ mime_constant = Mime.const_get(symbol.to_s.upcase)
21
+
22
+ if Mime::SET.include?(mime_constant)
23
+ AbstractController::Collector.generate_method_for_mime(mime_constant)
24
+ send(symbol, &block)
25
+ else
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ module AbstractController
2
+ module Compatibility
3
+ extend ActiveSupport::Concern
4
+
5
+ def _find_layout(name, details)
6
+ details[:prefix] = nil if name =~ /\blayouts/
7
+ super
8
+ end
9
+
10
+ # Move this into a "don't run in production" module
11
+ def _default_layout(details, require_layout = false)
12
+ super
13
+ rescue ActionView::MissingTemplate
14
+ _find_layout(_layout({}), {})
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,163 @@
1
+ require 'active_support/dependencies'
2
+ require 'active_support/core_ext/class/attribute'
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ module AbstractController
6
+ module Helpers
7
+ extend ActiveSupport::Concern
8
+
9
+ include Rendering
10
+
11
+ def self.next_serial
12
+ @helper_serial ||= 0
13
+ @helper_serial += 1
14
+ end
15
+
16
+ included do
17
+ class_attribute :_helpers, :_helper_serial
18
+ delegate :_helpers, :to => :'self.class'
19
+ self._helpers = Module.new
20
+ self._helper_serial = ::AbstractController::Helpers.next_serial
21
+ end
22
+
23
+ module ClassMethods
24
+ # When a class is inherited, wrap its helper module in a new module.
25
+ # This ensures that the parent class's module can be changed
26
+ # independently of the child class's.
27
+ def inherited(klass)
28
+ helpers = _helpers
29
+ klass._helpers = Module.new { include helpers }
30
+ klass.class_eval { default_helper_module! unless name.blank? }
31
+ super
32
+ end
33
+
34
+ # Declare a controller method as a helper. For example, the following
35
+ # makes the +current_user+ controller method available to the view:
36
+ # class ApplicationController < ActionController::Base
37
+ # helper_method :current_user, :logged_in?
38
+ #
39
+ # def current_user
40
+ # @current_user ||= User.find_by_id(session[:user])
41
+ # end
42
+ #
43
+ # def logged_in?
44
+ # current_user != nil
45
+ # end
46
+ # end
47
+ #
48
+ # In a view:
49
+ # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
50
+ #
51
+ # ==== Parameters
52
+ # meths<Array[#to_s]>:: The name of a method on the controller
53
+ # to be made available on the view.
54
+ def helper_method(*meths)
55
+ meths.flatten.each do |meth|
56
+ _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
57
+ def #{meth}(*args, &blk)
58
+ controller.send(%(#{meth}), *args, &blk)
59
+ end
60
+ ruby_eval
61
+ end
62
+ end
63
+
64
+ # The +helper+ class method can take a series of helper module names, a block, or both.
65
+ #
66
+ # ==== Parameters
67
+ # *args<Array[Module, Symbol, String, :all]>
68
+ # block<Block>:: A block defining helper methods
69
+ #
70
+ # ==== Examples
71
+ # When the argument is a module it will be included directly in the template class.
72
+ # helper FooHelper # => includes FooHelper
73
+ #
74
+ # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
75
+ # and include the module in the template class. The second form illustrates how to include custom helpers
76
+ # when working with namespaced controllers, or other cases where the file containing the helper definition is not
77
+ # in one of Rails' standard load paths:
78
+ # helper :foo # => requires 'foo_helper' and includes FooHelper
79
+ # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
80
+ #
81
+ # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
82
+ # to the template.
83
+ #
84
+ # # One line
85
+ # helper { def hello() "Hello, world!" end }
86
+ #
87
+ # # Multi-line
88
+ # helper do
89
+ # def foo(bar)
90
+ # "#{bar} is the very best"
91
+ # end
92
+ # end
93
+ #
94
+ # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
95
+ # +symbols+, +strings+, +modules+ and blocks.
96
+ #
97
+ # helper(:three, BlindHelper) { def mice() 'mice' end }
98
+ #
99
+ def helper(*args, &block)
100
+ self._helper_serial = AbstractController::Helpers.next_serial + 1
101
+
102
+ _modules_for_helpers(args).each do |mod|
103
+ add_template_helper(mod)
104
+ end
105
+
106
+ _helpers.module_eval(&block) if block_given?
107
+ end
108
+
109
+ private
110
+ # Makes all the (instance) methods in the helper module available to templates
111
+ # rendered through this controller.
112
+ #
113
+ # ==== Parameters
114
+ # mod<Module>:: The module to include into the current helper module
115
+ # for the class
116
+ def add_template_helper(mod)
117
+ _helpers.module_eval { include mod }
118
+ end
119
+
120
+ # Returns a list of modules, normalized from the acceptable kinds of
121
+ # helpers with the following behavior:
122
+ #
123
+ # String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper",
124
+ # and "foo_bar_helper.rb" is loaded using require_dependency.
125
+ #
126
+ # Module:: No further processing
127
+ #
128
+ # After loading the appropriate files, the corresponding modules
129
+ # are returned.
130
+ #
131
+ # ==== Parameters
132
+ # args<Array[String, Symbol, Module]>:: A list of helpers
133
+ #
134
+ # ==== Returns
135
+ # Array[Module]:: A normalized list of modules for the list of
136
+ # helpers provided.
137
+ def _modules_for_helpers(args)
138
+ args.flatten.map! do |arg|
139
+ case arg
140
+ when String, Symbol
141
+ file_name = "#{arg.to_s.underscore}_helper"
142
+ require_dependency(file_name, "Missing helper file helpers/%s.rb")
143
+ file_name.camelize.constantize
144
+ when Module
145
+ arg
146
+ else
147
+ raise ArgumentError, "helper must be a String, Symbol, or Module"
148
+ end
149
+ end
150
+ end
151
+
152
+ def default_helper_module!
153
+ module_name = name.sub(/Controller$/, '')
154
+ module_path = module_name.underscore
155
+ helper module_path
156
+ rescue MissingSourceFile => e
157
+ raise e unless e.is_missing? "helpers/#{module_path}_helper"
158
+ rescue NameError => e
159
+ raise e unless e.missing_name? "#{module_name}Helper"
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,413 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ module AbstractController
5
+ # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
6
+ # repeated setups. The inclusion pattern has pages that look like this:
7
+ #
8
+ # <%= render "shared/header" %>
9
+ # Hello World
10
+ # <%= render "shared/footer" %>
11
+ #
12
+ # This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose
13
+ # and if you ever want to change the structure of these two includes, you'll have to change all the templates.
14
+ #
15
+ # With layouts, you can flip it around and have the common structure know where to insert changing content. This means
16
+ # that the header and footer are only mentioned in one place, like this:
17
+ #
18
+ # // The header part of this layout
19
+ # <%= yield %>
20
+ # // The footer part of this layout
21
+ #
22
+ # And then you have content pages that look like this:
23
+ #
24
+ # hello world
25
+ #
26
+ # At rendering time, the content page is computed and then inserted in the layout, like this:
27
+ #
28
+ # // The header part of this layout
29
+ # hello world
30
+ # // The footer part of this layout
31
+ #
32
+ # == Accessing shared variables
33
+ #
34
+ # Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
35
+ # references that won't materialize before rendering time:
36
+ #
37
+ # <h1><%= @page_title %></h1>
38
+ # <%= yield %>
39
+ #
40
+ # ...and content pages that fulfill these references _at_ rendering time:
41
+ #
42
+ # <% @page_title = "Welcome" %>
43
+ # Off-world colonies offers you a chance to start a new life
44
+ #
45
+ # The result after rendering is:
46
+ #
47
+ # <h1>Welcome</h1>
48
+ # Off-world colonies offers you a chance to start a new life
49
+ #
50
+ # == Layout assignment
51
+ #
52
+ # You can either specify a layout declaratively (using the #layout class method) or give
53
+ # it the same name as your controller, and place it in <tt>app/views/layouts</tt>.
54
+ # If a subclass does not have a layout specified, it inherits its layout using normal Ruby inheritance.
55
+ #
56
+ # For instance, if you have PostsController and a template named <tt>app/views/layouts/posts.html.erb</tt>,
57
+ # that template will be used for all actions in PostsController and controllers inheriting
58
+ # from PostsController.
59
+ #
60
+ # If you use a module, for instance Weblog::PostsController, you will need a template named
61
+ # <tt>app/views/layouts/weblog/posts.html.erb</tt>.
62
+ #
63
+ # Since all your controllers inherit from ApplicationController, they will use
64
+ # <tt>app/views/layouts/application.html.erb</tt> if no other layout is specified
65
+ # or provided.
66
+ #
67
+ # == Inheritance Examples
68
+ #
69
+ # class BankController < ActionController::Base
70
+ # layout "bank_standard"
71
+ #
72
+ # class InformationController < BankController
73
+ #
74
+ # class TellerController < BankController
75
+ # # teller.html.erb exists
76
+ #
77
+ # class TillController < TellerController
78
+ #
79
+ # class VaultController < BankController
80
+ # layout :access_level_layout
81
+ #
82
+ # class EmployeeController < BankController
83
+ # layout nil
84
+ #
85
+ # The InformationController uses "bank_standard" inherited from the BankController, the VaultController overwrites
86
+ # and picks the layout dynamically, and the EmployeeController doesn't want to use a layout at all.
87
+ #
88
+ # The TellerController uses +teller.html.erb+, and TillController inherits that layout and
89
+ # uses it as well.
90
+ #
91
+ # == Types of layouts
92
+ #
93
+ # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes
94
+ # you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can
95
+ # be done either by specifying a method reference as a symbol or using an inline method (as a proc).
96
+ #
97
+ # The method reference is the preferred approach to variable layouts and is used like this:
98
+ #
99
+ # class WeblogController < ActionController::Base
100
+ # layout :writers_and_readers
101
+ #
102
+ # def index
103
+ # # fetching posts
104
+ # end
105
+ #
106
+ # private
107
+ # def writers_and_readers
108
+ # logged_in? ? "writer_layout" : "reader_layout"
109
+ # end
110
+ #
111
+ # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing
112
+ # is logged in or not.
113
+ #
114
+ # If you want to use an inline method, such as a proc, do something like this:
115
+ #
116
+ # class WeblogController < ActionController::Base
117
+ # layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
118
+ #
119
+ # Of course, the most common way of specifying a layout is still just as a plain template name:
120
+ #
121
+ # class WeblogController < ActionController::Base
122
+ # layout "weblog_standard"
123
+ #
124
+ # If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
125
+ # Otherwise, it will be looked up relative to the template root.
126
+ #
127
+ # == Conditional layouts
128
+ #
129
+ # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering
130
+ # a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The
131
+ # <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
132
+ #
133
+ # class WeblogController < ActionController::Base
134
+ # layout "weblog_standard", :except => :rss
135
+ #
136
+ # # ...
137
+ #
138
+ # end
139
+ #
140
+ # This will assign "weblog_standard" as the WeblogController's layout except for the +rss+ action, which will not wrap a layout
141
+ # around the rendered view.
142
+ #
143
+ # Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
144
+ # #<tt>:except => [ :rss, :text_only ]</tt> is valid, as is <tt>:except => :rss</tt>.
145
+ #
146
+ # == Using a different layout in the action render call
147
+ #
148
+ # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above.
149
+ # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller.
150
+ # You can do this by passing a <tt>:layout</tt> option to the <tt>render</tt> call. For example:
151
+ #
152
+ # class WeblogController < ActionController::Base
153
+ # layout "weblog_standard"
154
+ #
155
+ # def help
156
+ # render :action => "help", :layout => "help"
157
+ # end
158
+ # end
159
+ #
160
+ # This will render the help action with the "help" layout instead of the controller-wide "weblog_standard" layout.
161
+ module Layouts
162
+ extend ActiveSupport::Concern
163
+
164
+ include Rendering
165
+
166
+ included do
167
+ class_attribute :_layout_conditions
168
+ delegate :_layout_conditions, :to => :'self.class'
169
+ self._layout_conditions = {}
170
+ _write_layout_method
171
+ end
172
+
173
+ module ClassMethods
174
+ def inherited(klass)
175
+ super
176
+ klass.class_eval do
177
+ _write_layout_method
178
+ @found_layouts = {}
179
+ end
180
+ end
181
+
182
+ def clear_template_caches!
183
+ @found_layouts.clear if defined? @found_layouts
184
+ super
185
+ end
186
+
187
+ def cache_layout(details)
188
+ layout = @found_layouts
189
+ key = Thread.current[:format_locale_key]
190
+
191
+ # Cache nil
192
+ if layout.key?(key)
193
+ return layout[key]
194
+ else
195
+ layout[key] = yield
196
+ end
197
+ end
198
+
199
+ # This module is mixed in if layout conditions are provided. This means
200
+ # that if no layout conditions are used, this method is not used
201
+ module LayoutConditions
202
+ # Determines whether the current action has a layout by checking the
203
+ # action name against the :only and :except conditions set on the
204
+ # layout.
205
+ #
206
+ # ==== Returns
207
+ # Boolean:: True if the action has a layout, false otherwise.
208
+ def _action_has_layout?
209
+ conditions = _layout_conditions
210
+
211
+ if only = conditions[:only]
212
+ only.include?(action_name)
213
+ elsif except = conditions[:except]
214
+ !except.include?(action_name)
215
+ else
216
+ true
217
+ end
218
+ end
219
+ end
220
+
221
+ # Specify the layout to use for this class.
222
+ #
223
+ # If the specified layout is a:
224
+ # String:: the String is the template name
225
+ # Symbol:: call the method specified by the symbol, which will return
226
+ # the template name
227
+ # false:: There is no layout
228
+ # true:: raise an ArgumentError
229
+ #
230
+ # ==== Parameters
231
+ # layout<String, Symbol, false)>:: The layout to use.
232
+ #
233
+ # ==== Options (conditions)
234
+ # :only<#to_s, Array[#to_s]>:: A list of actions to apply this layout to.
235
+ # :except<#to_s, Array[#to_s]>:: Apply this layout to all actions but this one
236
+ def layout(layout, conditions = {})
237
+ include LayoutConditions unless conditions.empty?
238
+
239
+ conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
240
+ self._layout_conditions = conditions
241
+
242
+ @_layout = layout || false # Converts nil to false
243
+ _write_layout_method
244
+ end
245
+
246
+ # If no layout is supplied, look for a template named the return
247
+ # value of this method.
248
+ #
249
+ # ==== Returns
250
+ # String:: A template name
251
+ def _implied_layout_name
252
+ controller_path
253
+ end
254
+
255
+ # Takes the specified layout and creates a _layout method to be called
256
+ # by _default_layout
257
+ #
258
+ # If there is no explicit layout specified:
259
+ # If a layout is found in the view paths with the controller's
260
+ # name, return that string. Otherwise, use the superclass'
261
+ # layout (which might also be implied)
262
+ def _write_layout_method
263
+ case defined?(@_layout) ? @_layout : nil
264
+ when String
265
+ self.class_eval %{def _layout(details) #{@_layout.inspect} end}
266
+ when Symbol
267
+ self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
268
+ def _layout(details)
269
+ #{@_layout}.tap do |layout|
270
+ unless layout.is_a?(String) || !layout
271
+ raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \
272
+ "should have returned a String, false, or nil"
273
+ end
274
+ end
275
+ end
276
+ ruby_eval
277
+ when Proc
278
+ define_method :_layout_from_proc, &@_layout
279
+ self.class_eval %{def _layout(details) _layout_from_proc(self) end}
280
+ when false
281
+ self.class_eval %{def _layout(details) end}
282
+ when true
283
+ raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
284
+ when nil
285
+ if name
286
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
287
+ def _layout(details)
288
+ self.class.cache_layout(details) do
289
+ if template_exists?("#{_implied_layout_name}", details, :_prefix => "layouts")
290
+ "#{_implied_layout_name}"
291
+ else
292
+ super
293
+ end
294
+ end
295
+ end
296
+ RUBY
297
+ end
298
+ end
299
+ self.class_eval { private :_layout }
300
+ end
301
+ end
302
+
303
+ def render_to_body(options = {})
304
+ # In the case of a partial with a layout, handle the layout
305
+ # here, and make sure the view does not try to handle it
306
+ layout = options.delete(:layout) if options.key?(:partial)
307
+
308
+ response = super
309
+
310
+ # This is a little bit messy. We need to explicitly handle partial
311
+ # layouts here since the core lookup logic is in the view, but
312
+ # we need to determine the layout based on the controller
313
+ #
314
+ # TODO: An easier way to handle this would probably be to override
315
+ # render_template
316
+ if layout
317
+ layout = _layout_for_option(layout, options[:_template].details)
318
+ response = layout.render(view_context, options[:locals] || {}) { response }
319
+ end
320
+
321
+ response
322
+ end
323
+
324
+ private
325
+
326
+ # This will be overwritten by _write_layout_method
327
+ def _layout(details) end
328
+
329
+ # Determine the layout for a given name and details.
330
+ #
331
+ # ==== Parameters
332
+ # name<String>:: The name of the template
333
+ # details<Hash{Symbol => Object}>:: A list of details to restrict
334
+ # the lookup to. By default, layout lookup is limited to the
335
+ # formats specified for the current request.
336
+ def _layout_for_name(name, details)
337
+ name && _find_layout(name, details)
338
+ end
339
+
340
+ # Determine the layout for a given name and details, taking into account
341
+ # the name type.
342
+ #
343
+ # ==== Parameters
344
+ # name<String|TrueClass|FalseClass|Symbol>:: The name of the template
345
+ # details<Hash{Symbol => Object}>:: A list of details to restrict
346
+ # the lookup to. By default, layout lookup is limited to the
347
+ # formats specified for the current request.
348
+ def _layout_for_option(name, details)
349
+ case name
350
+ when String then _layout_for_name(name, details)
351
+ when true then _default_layout(details, true)
352
+ when :default then _default_layout(details, false)
353
+ when false, nil then nil
354
+ else
355
+ raise ArgumentError,
356
+ "String, true, or false, expected for `layout'; you passed #{name.inspect}"
357
+ end
358
+ end
359
+
360
+ def _determine_template(options)
361
+ super
362
+
363
+ return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
364
+ layout = options.key?(:layout) ? options[:layout] : :default
365
+ options[:_layout] = _layout_for_option(layout, options[:_template].details)
366
+ end
367
+
368
+ # Take in the name and details and find a Template.
369
+ #
370
+ # ==== Parameters
371
+ # name<String>:: The name of the template to retrieve
372
+ # details<Hash>:: A list of details to restrict the search by. This
373
+ # might include details like the format or locale of the template.
374
+ #
375
+ # ==== Returns
376
+ # Template:: A template object matching the name and details
377
+ def _find_layout(name, details)
378
+ # TODO: Make prefix actually part of details in ViewPath#find_by_parts
379
+ prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts"
380
+ find_template(name, details, :_prefix => prefix)
381
+ end
382
+
383
+ # Returns the default layout for this controller and a given set of details.
384
+ # Optionally raises an exception if the layout could not be found.
385
+ #
386
+ # ==== Parameters
387
+ # details<Hash>:: A list of details to restrict the search by. This
388
+ # might include details like the format or locale of the template.
389
+ # require_layout<Boolean>:: If this is true, raise an ArgumentError
390
+ # with details about the fact that the exception could not be
391
+ # found (defaults to false)
392
+ #
393
+ # ==== Returns
394
+ # Template:: The template object for the default layout (or nil)
395
+ def _default_layout(details, require_layout = false)
396
+ if require_layout && _action_has_layout? && !_layout(details)
397
+ raise ArgumentError,
398
+ "There was no default layout for #{self.class} in #{view_paths.inspect}"
399
+ end
400
+
401
+ begin
402
+ _layout_for_name(_layout(details), details) if _action_has_layout?
403
+ rescue NameError => e
404
+ raise NoMethodError,
405
+ "You specified #{@_layout.inspect} as the layout, but no such method was found"
406
+ end
407
+ end
408
+
409
+ def _action_has_layout?
410
+ true
411
+ end
412
+ end
413
+ end