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.
- data/CHANGELOG +15 -64
- data/README +39 -48
- data/lib/abstract_controller.rb +22 -0
- data/lib/abstract_controller/base.rb +191 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/collector.rb +30 -0
- data/lib/abstract_controller/compatibility.rb +18 -0
- data/lib/abstract_controller/helpers.rb +163 -0
- data/lib/abstract_controller/layouts.rb +413 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +13 -0
- data/lib/abstract_controller/rendering.rb +238 -0
- data/lib/{action_controller → abstract_controller}/translation.rb +1 -1
- data/lib/action_controller.rb +68 -102
- data/lib/action_controller/base.rb +77 -1409
- data/lib/action_controller/caching.rb +58 -45
- data/lib/action_controller/caching/actions.rb +100 -114
- data/lib/action_controller/caching/fragments.rb +17 -19
- data/lib/action_controller/caching/pages.rb +12 -6
- data/lib/action_controller/caching/sweeping.rb +42 -0
- data/lib/action_controller/deprecated.rb +5 -0
- data/lib/action_controller/deprecated/dispatcher.rb +28 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/metal.rb +125 -0
- data/lib/action_controller/metal/compatibility.rb +141 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +17 -0
- data/lib/action_controller/metal/exceptions.rb +46 -0
- data/lib/action_controller/metal/flash.rb +28 -0
- data/lib/action_controller/metal/head.rb +33 -0
- data/lib/action_controller/metal/helpers.rb +116 -0
- data/lib/action_controller/metal/hide_actions.rb +50 -0
- data/lib/action_controller/{http_authentication.rb → metal/http_authentication.rb} +18 -15
- data/lib/action_controller/metal/instrumentation.rb +99 -0
- data/lib/action_controller/metal/mime_responds.rb +300 -0
- data/lib/action_controller/metal/rack_delegation.rb +35 -0
- data/lib/action_controller/metal/redirecting.rb +90 -0
- data/lib/action_controller/metal/renderers.rb +95 -0
- data/lib/action_controller/metal/rendering.rb +69 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +115 -0
- data/lib/action_controller/metal/rescue.rb +13 -0
- data/lib/action_controller/metal/responder.rb +220 -0
- data/lib/action_controller/{session_management.rb → metal/session_management.rb} +5 -14
- data/lib/action_controller/{streaming.rb → metal/streaming.rb} +13 -12
- data/lib/action_controller/metal/testing.rb +42 -0
- data/lib/action_controller/metal/url_for.rb +157 -0
- data/lib/action_controller/{verification.rb → metal/verification.rb} +41 -41
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/polymorphic_routes.rb +20 -26
- data/lib/action_controller/railtie.rb +30 -0
- data/lib/action_controller/railties/subscriber.rb +63 -0
- data/lib/action_controller/record_identifier.rb +3 -16
- data/lib/action_controller/test_case.rb +156 -18
- data/lib/action_controller/url_rewriter.rb +47 -200
- data/lib/action_controller/vendor/html-scanner.rb +16 -12
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +12 -9
- data/lib/action_dispatch.rb +88 -0
- data/lib/action_dispatch/http/cache.rb +123 -0
- data/lib/action_dispatch/http/filter_parameters.rb +98 -0
- data/lib/{action_controller → action_dispatch/http}/headers.rb +8 -8
- data/lib/action_dispatch/http/mime_negotiation.rb +101 -0
- data/lib/{action_controller → action_dispatch/http}/mime_type.rb +30 -11
- data/lib/{action_controller → action_dispatch/http}/mime_types.rb +5 -3
- data/lib/action_dispatch/http/parameters.rb +49 -0
- data/lib/action_dispatch/http/request.rb +223 -0
- data/lib/action_dispatch/http/response.rb +209 -0
- data/lib/action_dispatch/http/upload.rb +48 -0
- data/lib/action_dispatch/http/url.rb +129 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/cascade.rb +29 -0
- data/lib/action_dispatch/middleware/cookies.rb +216 -0
- data/lib/{action_controller → action_dispatch/middleware}/flash.rb +51 -90
- data/lib/action_dispatch/middleware/head.rb +18 -0
- data/lib/action_dispatch/middleware/params_parser.rb +78 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +209 -0
- data/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb +56 -60
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +173 -0
- data/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb} +23 -13
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_request_and_response.erb +10 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_trace.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/layout.erb +2 -2
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/missing_template.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/routing_error.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/template_error.erb +3 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/unknown_action.erb +0 -0
- data/lib/action_dispatch/railtie.rb +15 -0
- data/lib/action_dispatch/routing.rb +217 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +877 -0
- data/lib/action_dispatch/routing/mapper.rb +649 -0
- data/lib/action_dispatch/routing/route.rb +55 -0
- data/lib/action_dispatch/routing/route_set.rb +445 -0
- data/lib/action_dispatch/testing/assertions.rb +21 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +37 -0
- data/lib/{action_controller/assertions/model_assertions.rb → action_dispatch/testing/assertions/model.rb} +2 -4
- data/lib/action_dispatch/testing/assertions/response.rb +154 -0
- data/lib/{action_controller/assertions/routing_assertions.rb → action_dispatch/testing/assertions/routing.rb} +72 -34
- data/lib/{action_controller/assertions/selector_assertions.rb → action_dispatch/testing/assertions/selector.rb} +14 -11
- data/lib/{action_controller/assertions/tag_assertions.rb → action_dispatch/testing/assertions/tag.rb} +25 -14
- data/lib/{action_controller → action_dispatch/testing}/integration.rb +173 -406
- data/lib/action_dispatch/testing/performance_test.rb +17 -0
- data/lib/action_dispatch/testing/test_process.rb +42 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +136 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +29 -26
- data/lib/action_view/base.rb +101 -148
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/helpers.rb +6 -4
- data/lib/action_view/helpers/{active_record_helper.rb → active_model_helper.rb} +63 -63
- data/lib/action_view/helpers/asset_tag_helper.rb +166 -31
- data/lib/action_view/helpers/cache_helper.rb +1 -1
- data/lib/action_view/helpers/capture_helper.rb +40 -8
- data/lib/action_view/helpers/csrf_helper.rb +2 -4
- data/lib/action_view/helpers/date_helper.rb +14 -15
- data/lib/action_view/helpers/form_helper.rb +121 -24
- data/lib/action_view/helpers/form_options_helper.rb +26 -25
- data/lib/action_view/helpers/form_tag_helper.rb +42 -33
- data/lib/action_view/helpers/javascript_helper.rb +1 -109
- data/lib/action_view/helpers/number_helper.rb +4 -1
- data/lib/action_view/helpers/prototype_helper.rb +75 -499
- data/lib/action_view/helpers/raw_output_helper.rb +1 -1
- data/lib/action_view/helpers/record_tag_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +3 -2
- data/lib/action_view/helpers/scriptaculous_helper.rb +89 -53
- data/lib/action_view/helpers/tag_helper.rb +12 -13
- data/lib/action_view/helpers/text_helper.rb +33 -38
- data/lib/action_view/helpers/translation_helper.rb +11 -35
- data/lib/action_view/helpers/url_helper.rb +140 -134
- data/lib/action_view/locale/en.yml +34 -28
- data/lib/action_view/paths.rb +27 -24
- data/lib/action_view/railtie.rb +17 -0
- data/lib/action_view/railties/subscriber.rb +24 -0
- data/lib/action_view/{partials.rb → render/partials.rb} +161 -51
- data/lib/action_view/render/rendering.rb +117 -0
- data/lib/action_view/template.rb +88 -217
- data/lib/action_view/template/error.rb +105 -0
- data/lib/action_view/template/handler.rb +41 -0
- data/lib/action_view/template/handlers.rb +54 -0
- data/lib/action_view/{template_handlers → template/handlers}/builder.rb +6 -6
- data/lib/action_view/template/handlers/erb.rb +58 -0
- data/lib/action_view/{template_handlers → template/handlers}/rjs.rb +8 -3
- data/lib/action_view/template/resolver.rb +164 -0
- data/lib/action_view/template/text.rb +40 -0
- data/lib/action_view/test_case.rb +18 -18
- metadata +165 -420
- data/RUNNING_UNIT_TESTS +0 -24
- data/Rakefile +0 -158
- data/install.rb +0 -30
- data/lib/action_controller/assertions/dom_assertions.rb +0 -55
- data/lib/action_controller/assertions/response_assertions.rb +0 -169
- data/lib/action_controller/benchmarking.rb +0 -107
- data/lib/action_controller/caching/sweeper.rb +0 -45
- data/lib/action_controller/cgi_ext.rb +0 -15
- data/lib/action_controller/cgi_ext/cookie.rb +0 -112
- data/lib/action_controller/cgi_ext/query_extension.rb +0 -22
- data/lib/action_controller/cgi_ext/stdinput.rb +0 -24
- data/lib/action_controller/cgi_process.rb +0 -77
- data/lib/action_controller/cookies.rb +0 -197
- data/lib/action_controller/dispatcher.rb +0 -133
- data/lib/action_controller/failsafe.rb +0 -87
- data/lib/action_controller/filters.rb +0 -680
- data/lib/action_controller/helpers.rb +0 -225
- data/lib/action_controller/layout.rb +0 -286
- data/lib/action_controller/middlewares.rb +0 -14
- data/lib/action_controller/mime_responds.rb +0 -193
- data/lib/action_controller/params_parser.rb +0 -77
- data/lib/action_controller/performance_test.rb +0 -15
- data/lib/action_controller/rack_lint_patch.rb +0 -36
- data/lib/action_controller/reloader.rb +0 -54
- data/lib/action_controller/request.rb +0 -518
- data/lib/action_controller/request_forgery_protection.rb +0 -116
- data/lib/action_controller/rescue.rb +0 -183
- data/lib/action_controller/resources.rb +0 -682
- data/lib/action_controller/response.rb +0 -237
- data/lib/action_controller/routing.rb +0 -388
- data/lib/action_controller/routing/builder.rb +0 -197
- data/lib/action_controller/routing/optimisations.rb +0 -130
- data/lib/action_controller/routing/recognition_optimisation.rb +0 -167
- data/lib/action_controller/routing/route.rb +0 -265
- data/lib/action_controller/routing/route_set.rb +0 -503
- data/lib/action_controller/routing/routing_ext.rb +0 -49
- data/lib/action_controller/routing/segments.rb +0 -343
- data/lib/action_controller/session/abstract_store.rb +0 -276
- data/lib/action_controller/session/mem_cache_store.rb +0 -60
- data/lib/action_controller/status_codes.rb +0 -88
- data/lib/action_controller/string_coercion.rb +0 -29
- data/lib/action_controller/templates/rescues/diagnostics.erb +0 -11
- data/lib/action_controller/test_process.rb +0 -580
- data/lib/action_controller/uploaded_file.rb +0 -44
- data/lib/action_view/helpers/benchmark_helper.rb +0 -54
- data/lib/action_view/inline_template.rb +0 -19
- data/lib/action_view/reloadable_template.rb +0 -117
- data/lib/action_view/renderable.rb +0 -109
- data/lib/action_view/renderable_partial.rb +0 -53
- data/lib/action_view/template_error.rb +0 -99
- data/lib/action_view/template_handler.rb +0 -34
- data/lib/action_view/template_handlers.rb +0 -48
- data/lib/action_view/template_handlers/erb.rb +0 -25
- data/lib/actionpack.rb +0 -2
- data/test/abstract_unit.rb +0 -78
- data/test/active_record_unit.rb +0 -104
- data/test/activerecord/active_record_store_test.rb +0 -221
- data/test/activerecord/render_partial_with_record_identification_test.rb +0 -188
- data/test/adv_attr_test.rb +0 -20
- data/test/controller/action_pack_assertions_test.rb +0 -545
- data/test/controller/addresses_render_test.rb +0 -37
- data/test/controller/assert_select_test.rb +0 -735
- data/test/controller/base_test.rb +0 -217
- data/test/controller/benchmark_test.rb +0 -32
- data/test/controller/caching_test.rb +0 -743
- data/test/controller/capture_test.rb +0 -66
- data/test/controller/content_type_test.rb +0 -178
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +0 -208
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -32
- data/test/controller/dispatcher_test.rb +0 -144
- data/test/controller/dom_assertions_test.rb +0 -53
- data/test/controller/failsafe_test.rb +0 -60
- data/test/controller/fake_controllers.rb +0 -33
- data/test/controller/fake_models.rb +0 -19
- data/test/controller/filter_params_test.rb +0 -52
- data/test/controller/filters_test.rb +0 -885
- data/test/controller/flash_test.rb +0 -174
- data/test/controller/header_test.rb +0 -14
- data/test/controller/helper_test.rb +0 -224
- data/test/controller/html-scanner/cdata_node_test.rb +0 -15
- data/test/controller/html-scanner/document_test.rb +0 -148
- data/test/controller/html-scanner/node_test.rb +0 -89
- data/test/controller/html-scanner/sanitizer_test.rb +0 -300
- data/test/controller/html-scanner/tag_node_test.rb +0 -238
- data/test/controller/html-scanner/text_node_test.rb +0 -50
- data/test/controller/html-scanner/tokenizer_test.rb +0 -131
- data/test/controller/http_basic_authentication_test.rb +0 -113
- data/test/controller/http_digest_authentication_test.rb +0 -254
- data/test/controller/integration_test.rb +0 -526
- data/test/controller/layout_test.rb +0 -215
- data/test/controller/localized_templates_test.rb +0 -24
- data/test/controller/logging_test.rb +0 -46
- data/test/controller/middleware_stack_test.rb +0 -90
- data/test/controller/mime_responds_test.rb +0 -536
- data/test/controller/mime_type_test.rb +0 -93
- data/test/controller/output_escaping_test.rb +0 -19
- data/test/controller/polymorphic_routes_test.rb +0 -297
- data/test/controller/rack_test.rb +0 -308
- data/test/controller/record_identifier_test.rb +0 -139
- data/test/controller/redirect_test.rb +0 -285
- data/test/controller/reloader_test.rb +0 -125
- data/test/controller/render_test.rb +0 -1783
- data/test/controller/request/json_params_parsing_test.rb +0 -65
- data/test/controller/request/multipart_params_parsing_test.rb +0 -177
- data/test/controller/request/query_string_parsing_test.rb +0 -129
- data/test/controller/request/test_request_test.rb +0 -35
- data/test/controller/request/url_encoded_params_parsing_test.rb +0 -146
- data/test/controller/request/xml_params_parsing_test.rb +0 -103
- data/test/controller/request_forgery_protection_test.rb +0 -233
- data/test/controller/request_test.rb +0 -398
- data/test/controller/rescue_test.rb +0 -541
- data/test/controller/resources_test.rb +0 -1393
- data/test/controller/routing_test.rb +0 -2592
- data/test/controller/selector_test.rb +0 -628
- data/test/controller/send_file_test.rb +0 -171
- data/test/controller/session/abstract_store_test.rb +0 -64
- data/test/controller/session/cookie_store_test.rb +0 -354
- data/test/controller/session/mem_cache_store_test.rb +0 -187
- data/test/controller/session/test_session_test.rb +0 -58
- data/test/controller/test_test.rb +0 -700
- data/test/controller/translation_test.rb +0 -26
- data/test/controller/url_rewriter_test.rb +0 -395
- data/test/controller/verification_test.rb +0 -270
- data/test/controller/view_paths_test.rb +0 -141
- data/test/controller/webservice_test.rb +0 -273
- data/test/fixtures/_top_level_partial.html.erb +0 -1
- data/test/fixtures/_top_level_partial_only.erb +0 -1
- data/test/fixtures/addresses/list.erb +0 -1
- data/test/fixtures/alternate_helpers/foo_helper.rb +0 -3
- data/test/fixtures/bad_customers/_bad_customer.html.erb +0 -1
- data/test/fixtures/companies.yml +0 -24
- data/test/fixtures/company.rb +0 -10
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rjs.rjs +0 -1
- data/test/fixtures/content_type/render_default_for_rxml.rxml +0 -1
- data/test/fixtures/customers/_customer.html.erb +0 -1
- data/test/fixtures/db_definitions/sqlite.sql +0 -49
- data/test/fixtures/developer.rb +0 -9
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers/_developer.erb +0 -1
- data/test/fixtures/developers_projects.yml +0 -13
- data/test/fixtures/failsafe/500.html +0 -1
- data/test/fixtures/fun/games/_game.erb +0 -1
- data/test/fixtures/fun/games/hello_world.erb +0 -1
- data/test/fixtures/fun/serious/games/_game.erb +0 -1
- data/test/fixtures/functional_caching/_partial.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +0 -6
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +0 -5
- data/test/fixtures/functional_caching/fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +0 -1
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +0 -1
- data/test/fixtures/good_customers/_good_customer.html.erb +0 -1
- data/test/fixtures/helpers/abc_helper.rb +0 -5
- data/test/fixtures/helpers/fun/games_helper.rb +0 -3
- data/test/fixtures/helpers/fun/pdf_helper.rb +0 -3
- data/test/fixtures/layout_tests/abs_path_layout.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/item.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +0 -1
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +0 -1
- data/test/fixtures/layout_tests/views/hello.rhtml +0 -1
- data/test/fixtures/layouts/_column.html.erb +0 -2
- data/test/fixtures/layouts/block_with_layout.erb +0 -3
- data/test/fixtures/layouts/builder.builder +0 -3
- data/test/fixtures/layouts/default_html.html.erb +0 -1
- data/test/fixtures/layouts/partial_with_layout.erb +0 -3
- data/test/fixtures/layouts/standard.erb +0 -1
- data/test/fixtures/layouts/talk_from_action.erb +0 -2
- data/test/fixtures/layouts/xhr.html.erb +0 -2
- data/test/fixtures/layouts/yield.erb +0 -2
- data/test/fixtures/localized/hello_world.de.html +0 -1
- data/test/fixtures/localized/hello_world.en.html +0 -1
- data/test/fixtures/mascot.rb +0 -3
- data/test/fixtures/mascots.yml +0 -4
- data/test/fixtures/mascots/_mascot.html.erb +0 -1
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +0 -10
- data/test/fixtures/multipart/bracketed_param +0 -5
- data/test/fixtures/multipart/empty +0 -10
- data/test/fixtures/multipart/hello.txt +0 -1
- data/test/fixtures/multipart/large_text_file +0 -10
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/none +0 -9
- data/test/fixtures/multipart/single_parameter +0 -5
- data/test/fixtures/multipart/text_file +0 -10
- data/test/fixtures/override/test/hello_world.erb +0 -1
- data/test/fixtures/override2/layouts/test/sub.erb +0 -1
- data/test/fixtures/post_test/layouts/post.html.erb +0 -1
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +0 -1
- data/test/fixtures/post_test/post/index.html.erb +0 -1
- data/test/fixtures/post_test/post/index.iphone.erb +0 -1
- data/test/fixtures/post_test/super_post/index.html.erb +0 -1
- data/test/fixtures/post_test/super_post/index.iphone.erb +0 -1
- data/test/fixtures/project.rb +0 -3
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/projects/_project.erb +0 -1
- data/test/fixtures/public/404.html +0 -1
- data/test/fixtures/public/500.da.html +0 -1
- data/test/fixtures/public/500.html +0 -1
- data/test/fixtures/public/absolute/test.css +0 -23
- data/test/fixtures/public/absolute/test.js +0 -63
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +0 -1
- data/test/fixtures/public/javascripts/controls.js +0 -1
- data/test/fixtures/public/javascripts/dragdrop.js +0 -1
- data/test/fixtures/public/javascripts/effects.js +0 -1
- data/test/fixtures/public/javascripts/prototype.js +0 -1
- data/test/fixtures/public/javascripts/robber.js +0 -1
- data/test/fixtures/public/javascripts/subdir/subdir.js +0 -1
- data/test/fixtures/public/javascripts/version.1.0.js +0 -1
- data/test/fixtures/public/stylesheets/bank.css +0 -1
- data/test/fixtures/public/stylesheets/robber.css +0 -1
- data/test/fixtures/public/stylesheets/subdir/subdir.css +0 -1
- data/test/fixtures/public/stylesheets/version.1.0.css +0 -1
- data/test/fixtures/quiz/questions/_question.html.erb +0 -1
- data/test/fixtures/replies.yml +0 -15
- data/test/fixtures/replies/_reply.erb +0 -1
- data/test/fixtures/reply.rb +0 -7
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +0 -1
- data/test/fixtures/respond_to/all_types_with_layout.js.rjs +0 -1
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +0 -1
- data/test/fixtures/respond_to/layouts/missing.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults.xml.builder +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +0 -1
- data/test/fixtures/scope/test/modgreet.erb +0 -1
- data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +0 -10
- data/test/fixtures/shared.html.erb +0 -1
- data/test/fixtures/symlink_parent/symlinked_layout.erb +0 -5
- data/test/fixtures/test/_counter.html.erb +0 -1
- data/test/fixtures/test/_customer.erb +0 -1
- data/test/fixtures/test/_customer_counter.erb +0 -1
- data/test/fixtures/test/_customer_counter_with_as.erb +0 -1
- data/test/fixtures/test/_customer_greeting.erb +0 -1
- data/test/fixtures/test/_customer_with_var.erb +0 -1
- data/test/fixtures/test/_form.erb +0 -1
- data/test/fixtures/test/_from_helper.erb +0 -1
- data/test/fixtures/test/_hash_greeting.erb +0 -1
- data/test/fixtures/test/_hash_object.erb +0 -2
- data/test/fixtures/test/_hello.builder +0 -1
- data/test/fixtures/test/_labelling_form.erb +0 -1
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +0 -3
- data/test/fixtures/test/_layout_for_partial.html.erb +0 -3
- data/test/fixtures/test/_local_inspector.html.erb +0 -1
- data/test/fixtures/test/_one.html.erb +0 -1
- data/test/fixtures/test/_partial.erb +0 -1
- data/test/fixtures/test/_partial.html.erb +0 -1
- data/test/fixtures/test/_partial.js.erb +0 -1
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +0 -1
- data/test/fixtures/test/_partial_only.erb +0 -1
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +0 -1
- data/test/fixtures/test/_person.erb +0 -2
- data/test/fixtures/test/_raise.html.erb +0 -1
- data/test/fixtures/test/_two.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial_magic.html.erb +0 -2
- data/test/fixtures/test/action_talk_to_layout.erb +0 -2
- data/test/fixtures/test/array_translation.erb +0 -1
- data/test/fixtures/test/calling_partial_with_layout.html.erb +0 -1
- data/test/fixtures/test/capturing.erb +0 -4
- data/test/fixtures/test/content_for.erb +0 -2
- data/test/fixtures/test/content_for_concatenated.erb +0 -3
- data/test/fixtures/test/content_for_with_parameter.erb +0 -2
- data/test/fixtures/test/delete_with_js.rjs +0 -2
- data/test/fixtures/test/dont_pick_me +0 -1
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/enum_rjs_test.rjs +0 -6
- data/test/fixtures/test/formatted_html_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.builder +0 -1
- data/test/fixtures/test/formatted_xml_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.xml.erb +0 -1
- data/test/fixtures/test/greeting.erb +0 -1
- data/test/fixtures/test/greeting.js.rjs +0 -1
- data/test/fixtures/test/hello.builder +0 -4
- data/test/fixtures/test/hello_world.da.html.erb +0 -1
- data/test/fixtures/test/hello_world.erb +0 -1
- data/test/fixtures/test/hello_world.erb~ +0 -1
- data/test/fixtures/test/hello_world.pt-BR.html.erb +0 -1
- data/test/fixtures/test/hello_world_container.builder +0 -3
- data/test/fixtures/test/hello_world_from_rxml.builder +0 -4
- data/test/fixtures/test/hello_world_with_layout_false.erb +0 -1
- data/test/fixtures/test/hello_xml_world.builder +0 -11
- data/test/fixtures/test/hyphen-ated.erb +0 -1
- data/test/fixtures/test/implicit_content_type.atom.builder +0 -2
- data/test/fixtures/test/list.erb +0 -1
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.html.erb~ +0 -1
- data/test/fixtures/test/nested_layout.erb +0 -3
- data/test/fixtures/test/non_erb_block_content_for.builder +0 -4
- data/test/fixtures/test/potential_conflicts.erb +0 -4
- data/test/fixtures/test/render_explicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_file_from_template.html.erb +0 -1
- data/test/fixtures/test/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/render_file_with_locals.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +0 -1
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +0 -1
- data/test/fixtures/test/render_to_string_test.erb +0 -1
- data/test/fixtures/test/scoped_array_translation.erb +0 -1
- data/test/fixtures/test/sub_template_raise.html.erb +0 -1
- data/test/fixtures/test/template.erb +0 -1
- data/test/fixtures/test/translation.erb +0 -1
- data/test/fixtures/test/update_element_with_capture.erb +0 -9
- data/test/fixtures/test/using_layout_around_block.html.erb +0 -1
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +0 -1
- data/test/fixtures/test/utf8.html.erb +0 -4
- data/test/fixtures/test/utf8_magic.html.erb +0 -5
- data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +0 -5
- data/test/fixtures/topic.rb +0 -3
- data/test/fixtures/topics.yml +0 -22
- data/test/fixtures/topics/_topic.html.erb +0 -1
- data/test/template/active_record_helper_i18n_test.rb +0 -51
- data/test/template/active_record_helper_test.rb +0 -302
- data/test/template/asset_tag_helper_test.rb +0 -770
- data/test/template/atom_feed_helper_test.rb +0 -315
- data/test/template/benchmark_helper_test.rb +0 -86
- data/test/template/compiled_templates_test.rb +0 -204
- data/test/template/date_helper_i18n_test.rb +0 -121
- data/test/template/date_helper_test.rb +0 -2603
- data/test/template/erb_util_test.rb +0 -36
- data/test/template/form_helper_test.rb +0 -1447
- data/test/template/form_options_helper_i18n_test.rb +0 -27
- data/test/template/form_options_helper_test.rb +0 -811
- data/test/template/form_tag_helper_test.rb +0 -356
- data/test/template/javascript_helper_test.rb +0 -106
- data/test/template/number_helper_i18n_test.rb +0 -69
- data/test/template/number_helper_test.rb +0 -132
- data/test/template/prototype_helper_test.rb +0 -639
- data/test/template/raw_output_helper_test.rb +0 -21
- data/test/template/record_tag_helper_test.rb +0 -58
- data/test/template/render_test.rb +0 -329
- data/test/template/sanitize_helper_test.rb +0 -57
- data/test/template/scriptaculous_helper_test.rb +0 -90
- data/test/template/tag_helper_test.rb +0 -98
- data/test/template/template_test.rb +0 -32
- data/test/template/test_test.rb +0 -54
- data/test/template/text_helper_test.rb +0 -601
- data/test/template/translation_helper_test.rb +0 -95
- data/test/template/url_helper_test.rb +0 -641
- data/test/testing_sandbox.rb +0 -15
- 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
|