merb 0.5.3 → 0.9.2
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/LICENSE +0 -20
- data/README +0 -277
- data/Rakefile +80 -199
- data/TODO +0 -3
- metadata +19 -438
- data/SVN_REVISION +0 -1
- data/app_generators/merb/USAGE +0 -5
- data/app_generators/merb/merb_generator.rb +0 -108
- data/app_generators/merb/templates/Rakefile +0 -124
- data/app_generators/merb/templates/app/controllers/application.rb +0 -3
- data/app_generators/merb/templates/app/controllers/exceptions.rb +0 -13
- data/app_generators/merb/templates/app/helpers/global_helper.rb +0 -5
- data/app_generators/merb/templates/app/mailers/views/layout/application.html.erb +0 -1
- data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +0 -1
- data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +0 -1
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +0 -216
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +0 -38
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +0 -40
- data/app_generators/merb/templates/app/views/layout/application.html.erb +0 -11
- data/app_generators/merb/templates/config/boot.rb +0 -11
- data/app_generators/merb/templates/config/dependencies.rb +0 -41
- data/app_generators/merb/templates/config/environments/development.rb +0 -1
- data/app_generators/merb/templates/config/environments/production.rb +0 -1
- data/app_generators/merb/templates/config/environments/test.rb +0 -1
- data/app_generators/merb/templates/config/merb.yml +0 -82
- data/app_generators/merb/templates/config/merb_init.rb +0 -17
- data/app_generators/merb/templates/config/plugins.yml +0 -1
- data/app_generators/merb/templates/config/router.rb +0 -35
- data/app_generators/merb/templates/config/upload.conf +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +0 -6
- data/app_generators/merb/templates/public/stylesheets/master.css +0 -119
- data/app_generators/merb/templates/script/destroy +0 -32
- data/app_generators/merb/templates/script/generate +0 -32
- data/app_generators/merb/templates/script/stop_merb +0 -13
- data/app_generators/merb/templates/script/win_script.cmd +0 -1
- data/app_generators/merb/templates/spec/spec.opts +0 -6
- data/app_generators/merb/templates/spec/spec_helper.rb +0 -15
- data/app_generators/merb/templates/test/test_helper.rb +0 -14
- data/app_generators/merb_plugin/USAGE +0 -5
- data/app_generators/merb_plugin/merb_plugin_generator.rb +0 -68
- data/app_generators/merb_plugin/templates/LICENSE +0 -20
- data/app_generators/merb_plugin/templates/README +0 -4
- data/app_generators/merb_plugin/templates/Rakefile +0 -35
- data/app_generators/merb_plugin/templates/TODO +0 -5
- data/app_generators/merb_plugin/templates/merbtasks.rb +0 -6
- data/app_generators/merb_plugin/templates/sampleplugin.rb +0 -10
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +0 -7
- data/app_generators/merb_plugin/templates/spec_helper.rb +0 -2
- data/bin/merb +0 -4
- data/lib/autotest/discover.rb +0 -3
- data/lib/autotest/merb_rspec.rb +0 -80
- data/lib/merb.rb +0 -188
- data/lib/merb/abstract_controller.rb +0 -399
- data/lib/merb/assets.rb +0 -160
- data/lib/merb/assets.rb.orig +0 -119
- data/lib/merb/boot_loader.rb +0 -286
- data/lib/merb/boot_loader.rb.orig +0 -235
- data/lib/merb/caching.rb +0 -5
- data/lib/merb/caching/action_cache.rb +0 -92
- data/lib/merb/caching/fragment_cache.rb +0 -39
- data/lib/merb/caching/store/file_cache.rb +0 -90
- data/lib/merb/caching/store/memory_cache.rb +0 -85
- data/lib/merb/config.rb +0 -290
- data/lib/merb/constants.rb +0 -50
- data/lib/merb/controller.rb +0 -220
- data/lib/merb/cookies.rb +0 -95
- data/lib/merb/core_ext.rb +0 -15
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/class.rb +0 -180
- data/lib/merb/core_ext/enumerable.rb +0 -49
- data/lib/merb/core_ext/get_args.rb +0 -76
- data/lib/merb/core_ext/hash.rb +0 -306
- data/lib/merb/core_ext/inflections.rb +0 -112
- data/lib/merb/core_ext/inflector.rb +0 -275
- data/lib/merb/core_ext/kernel.rb +0 -242
- data/lib/merb/core_ext/mash.rb +0 -88
- data/lib/merb/core_ext/module.rb +0 -67
- data/lib/merb/core_ext/numeric.rb +0 -72
- data/lib/merb/core_ext/object.rb +0 -183
- data/lib/merb/core_ext/string.rb +0 -53
- data/lib/merb/core_ext/symbol.rb +0 -6
- data/lib/merb/dispatcher.rb +0 -109
- data/lib/merb/drb_server.rb +0 -19
- data/lib/merb/erubis_ext.rb +0 -10
- data/lib/merb/exceptions.rb +0 -192
- data/lib/merb/generators/merb_app/merb_app.rb +0 -22
- data/lib/merb/generators/merb_generator_helpers.rb +0 -318
- data/lib/merb/generators/merb_plugin.rb +0 -22
- data/lib/merb/logger.rb +0 -78
- data/lib/merb/mail_controller.rb +0 -268
- data/lib/merb/mailer.rb +0 -87
- data/lib/merb/mixins/basic_authentication.rb +0 -35
- data/lib/merb/mixins/controller.rb +0 -160
- data/lib/merb/mixins/erubis_capture.rb +0 -68
- data/lib/merb/mixins/general_controller.rb +0 -253
- data/lib/merb/mixins/inline_partial.rb +0 -32
- data/lib/merb/mixins/render.rb +0 -465
- data/lib/merb/mixins/responder.rb +0 -449
- data/lib/merb/mixins/view_context.rb +0 -558
- data/lib/merb/mixins/web_controller.rb +0 -36
- data/lib/merb/mongrel_handler.rb +0 -168
- data/lib/merb/part_controller.rb +0 -29
- data/lib/merb/plugins.rb +0 -16
- data/lib/merb/rack_adapter.rb +0 -37
- data/lib/merb/request.rb +0 -465
- data/lib/merb/router.rb +0 -646
- data/lib/merb/server.rb +0 -169
- data/lib/merb/session.rb +0 -23
- data/lib/merb/session/cookie_store.rb +0 -118
- data/lib/merb/session/mem_cache_session.rb +0 -131
- data/lib/merb/session/memory_session.rb +0 -176
- data/lib/merb/template.rb +0 -37
- data/lib/merb/template/erubis.rb +0 -68
- data/lib/merb/template/haml.rb +0 -87
- data/lib/merb/template/markaby.rb +0 -59
- data/lib/merb/template/xml_builder.rb +0 -50
- data/lib/merb/test/fake_request.rb +0 -74
- data/lib/merb/test/helper.rb +0 -260
- data/lib/merb/test/hpricot.rb +0 -136
- data/lib/merb/test/multipart.rb +0 -66
- data/lib/merb/test/rspec.rb +0 -18
- data/lib/merb/test/rspec_matchers/controller_matchers.rb +0 -117
- data/lib/merb/test/rspec_matchers/markup_matchers.rb +0 -98
- data/lib/merb/upload_handler.rb +0 -80
- data/lib/merb/upload_progress.rb +0 -48
- data/lib/merb/version.rb +0 -49
- data/lib/merb/view_context.rb +0 -79
- data/lib/tasks.rb +0 -7
- data/lib/tasks/merb.rake +0 -54
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +0 -16
- data/merb_default_generators/model/templates/new_model_template.erb +0 -5
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +0 -26
- data/merb_default_generators/resource_controller/templates/controller.rb +0 -30
- data/merb_default_generators/resource_controller/templates/edit.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/helper.rb +0 -5
- data/merb_default_generators/resource_controller/templates/index.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/new.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/show.html.erb +0 -1
- data/merb_generators/controller/USAGE +0 -5
- data/merb_generators/controller/controller_generator.rb +0 -16
- data/merb_generators/controller/templates/controller.rb +0 -8
- data/merb_generators/controller/templates/helper.rb +0 -5
- data/merb_generators/controller/templates/index.html.erb +0 -3
- data/merb_generators/part_controller/USAGE +0 -5
- data/merb_generators/part_controller/part_controller_generator.rb +0 -27
- data/merb_generators/part_controller/templates/controller.rb +0 -8
- data/merb_generators/part_controller/templates/helper.rb +0 -5
- data/merb_generators/part_controller/templates/index.html.erb +0 -3
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +0 -67
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +0 -67
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +0 -8
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +0 -5
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +0 -5
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +0 -26
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +0 -7
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/spec/fixtures/config/environments/environment_config_test.yml +0 -1
- data/spec/fixtures/config/merb.yml +0 -18
- data/spec/fixtures/controllers/dispatch_spec_controllers.rb +0 -235
- data/spec/fixtures/controllers/render_spec_controllers.rb +0 -184
- data/spec/fixtures/foo.rb +0 -3
- data/spec/fixtures/mailers/views/layout/application.html.erb +0 -3
- data/spec/fixtures/mailers/views/layout/application.text.erb +0 -3
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +0 -1
- data/spec/fixtures/models/router_spec_models.rb +0 -30
- data/spec/fixtures/parts/views/layout/todo_part.html.erb +0 -3
- data/spec/fixtures/parts/views/layout/todo_part.xml.erb +0 -3
- data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/list.html.erb +0 -3
- data/spec/fixtures/sample.txt +0 -1
- data/spec/fixtures/views/erubis.html.erb +0 -1
- data/spec/fixtures/views/examples/_erubis.html.erb +0 -1
- data/spec/fixtures/views/examples/_haml.html.haml +0 -1
- data/spec/fixtures/views/examples/_markaby.html.mab +0 -1
- data/spec/fixtures/views/examples/_throw_content.html.erb +0 -6
- data/spec/fixtures/views/examples/hello.xml.builder +0 -1
- data/spec/fixtures/views/examples/js.js.erb +0 -1
- data/spec/fixtures/views/examples/template_catch_content.html.erb +0 -15
- data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +0 -6
- data/spec/fixtures/views/examples/template_throw_content.html.erb +0 -10
- data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +0 -3
- data/spec/fixtures/views/exceptions/admin_access_required.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
- data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +0 -4
- data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +0 -1
- data/spec/fixtures/views/haml.html.haml +0 -1
- data/spec/fixtures/views/haml.xml.haml +0 -2
- data/spec/fixtures/views/layout/application.html.erb +0 -1
- data/spec/fixtures/views/layout/application.xml.erb +0 -1
- data/spec/fixtures/views/layout/nested/example.html.erb +0 -1
- data/spec/fixtures/views/markaby.html.mab +0 -1
- data/spec/fixtures/views/nested/example/test.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_collection.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_new.html.erb +0 -1
- data/spec/fixtures/views/partials/_haml.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_collection.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_new.html.haml +0 -1
- data/spec/fixtures/views/partials/_markaby.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_collection.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_new.html.mab +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +0 -1
- data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +0 -4
- data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +0 -7
- data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +0 -7
- data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +0 -15
- data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +0 -15
- data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +0 -4
- data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +0 -12
- data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +0 -11
- data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +0 -14
- data/spec/fixtures/views/test.dir/the_template.html.erb +0 -1
- data/spec/merb/abstract_controller_spec.rb +0 -38
- data/spec/merb/assets_spec.rb +0 -207
- data/spec/merb/caching_spec.rb +0 -102
- data/spec/merb/config_spec.rb +0 -29
- data/spec/merb/controller_filters_spec.rb +0 -253
- data/spec/merb/controller_spec.rb +0 -126
- data/spec/merb/cookie_store_spec.rb +0 -72
- data/spec/merb/cookies_spec.rb +0 -96
- data/spec/merb/core_ext/class_spec.rb +0 -97
- data/spec/merb/core_ext/enumerable_spec.rb +0 -27
- data/spec/merb/core_ext/hash_spec.rb +0 -251
- data/spec/merb/core_ext/inflector_spec.rb +0 -34
- data/spec/merb/core_ext/kernel_spec.rb +0 -25
- data/spec/merb/core_ext/numeric_spec.rb +0 -26
- data/spec/merb/core_ext/object_spec.rb +0 -47
- data/spec/merb/core_ext/string_spec.rb +0 -22
- data/spec/merb/core_ext/symbol_spec.rb +0 -7
- data/spec/merb/dependency_spec.rb +0 -22
- data/spec/merb/dispatch_spec.rb +0 -528
- data/spec/merb/fake_request_spec.rb +0 -80
- data/spec/merb/generator_spec.rb +0 -248
- data/spec/merb/handler_spec.rb +0 -169
- data/spec/merb/mail_controller_spec.rb +0 -177
- data/spec/merb/mailer_spec.rb +0 -87
- data/spec/merb/multipart_spec.rb +0 -50
- data/spec/merb/part_controller_spec.rb +0 -124
- data/spec/merb/plugins_spec.rb +0 -80
- data/spec/merb/render_spec.rb +0 -469
- data/spec/merb/request_spec.rb +0 -287
- data/spec/merb/responder_spec.rb +0 -562
- data/spec/merb/router_spec.rb +0 -900
- data/spec/merb/server_spec.rb +0 -19
- data/spec/merb/template_spec.rb +0 -41
- data/spec/merb/upload_handler_spec.rb +0 -108
- data/spec/merb/version_spec.rb +0 -33
- data/spec/merb/view_context_spec.rb +0 -366
- data/spec/spec_generator_helper.rb +0 -34
- data/spec/spec_helper.rb +0 -101
- data/spec/spec_helpers/url_shared_behaviour.rb +0 -112
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +0 -53
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +0 -17
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +0 -9
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +0 -29
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +0 -9
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
require 'enumerator'
|
|
2
|
-
|
|
3
|
-
module Merb
|
|
4
|
-
class << self
|
|
5
|
-
# Provides the currently implemented mime types as a hash
|
|
6
|
-
def available_mime_types
|
|
7
|
-
ResponderMixin::Rest::TYPES
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# Any specific outgoing headers should be included here. These are not
|
|
11
|
-
# the content-type header but anything in addition to it.
|
|
12
|
-
# +tranform_method+ should be set to a symbol of the method used to
|
|
13
|
-
# transform a resource into this mime type.
|
|
14
|
-
# For example for the :xml mime type an object might be transformed by
|
|
15
|
-
# calling :to_xml, or for the :js mime type, :to_json.
|
|
16
|
-
# If there is no transform method, use nil.
|
|
17
|
-
def add_mime_type(key,transform_method, values,new_response_headers = {})
|
|
18
|
-
raise ArgumentError unless key.is_a?(Symbol) && values.is_a?(Array)
|
|
19
|
-
ResponderMixin::Rest::TYPES.update(key => values)
|
|
20
|
-
add_response_headers!(key, new_response_headers)
|
|
21
|
-
ResponderMixin::Rest::TRANSFORM_METHODS.merge!(key => transform_method)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def remove_mime_type(key)
|
|
25
|
-
key == :all ? false : ResponderMixin::Rest::TYPES.delete(key)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Return the method name (if any) for the mimetype
|
|
29
|
-
def mime_transform_method(key)
|
|
30
|
-
ResponderMixin::Rest::TRANSFORM_METHODS[key]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Return default arguments for transform method (if any)
|
|
34
|
-
def mime_transform_method_defaults(key)
|
|
35
|
-
ResponderMixin::Rest::TRANSFORM_METHOD_DEFAULTS[key]
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Set default arguments/proc for a format transform method
|
|
39
|
-
def set_mime_transform_method_defaults(key, *args, &block)
|
|
40
|
-
raise "Unknown mimetype #{key}" unless ResponderMixin::Rest::TRANSFORM_METHODS[key]
|
|
41
|
-
args = block if block_given?
|
|
42
|
-
ResponderMixin::Rest::TRANSFORM_METHOD_DEFAULTS[key] = args unless args.empty?
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Adds outgoing headers to a mime type. This can be done with the Merb.add_mime_type method
|
|
46
|
-
# or directly here.
|
|
47
|
-
# ===Example
|
|
48
|
-
# {{[
|
|
49
|
-
# Merb.outgoing_headers!(:xml => { :Encoding => "UTF-8" })
|
|
50
|
-
# ]}}
|
|
51
|
-
#
|
|
52
|
-
# This method is destructive on any already defined outgoing headers
|
|
53
|
-
def add_response_headers!(key, values = {})
|
|
54
|
-
raise ArgumentError unless key.is_a?(Symbol) && values.is_a?(Hash)
|
|
55
|
-
response_headers[key] = values
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def response_headers
|
|
59
|
-
ResponderMixin::Rest::RESPONSE_HEADERS
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Completely removes any headers set that are additional to the content-type header.
|
|
63
|
-
def remove_response_headers!(key)
|
|
64
|
-
raise ArgumentError unless key.is_a?(Symbol)
|
|
65
|
-
response_headers[key] = {}
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Sets the mime types and outgoing headers to their original states
|
|
69
|
-
def reset_default_mime_types!
|
|
70
|
-
available_mime_types.clear
|
|
71
|
-
response_headers.clear
|
|
72
|
-
Merb.add_mime_type(:all,nil,%w[*/*])
|
|
73
|
-
Merb.add_mime_type(:yaml,:to_yaml,%w[application/x-yaml text/yaml])
|
|
74
|
-
Merb.add_mime_type(:text,:to_text,%w[text/plain])
|
|
75
|
-
Merb.add_mime_type(:html,nil,%w[text/html application/xhtml+xml application/html])
|
|
76
|
-
Merb.add_mime_type(:xml,:to_xml,%w[application/xml text/xml application/x-xml], :Encoding => "UTF-8")
|
|
77
|
-
Merb.add_mime_type(:js,:to_json,%w[ text/javascript application/javascript application/x-javascript])
|
|
78
|
-
Merb.add_mime_type(:json,:to_json,%w[application/json text/x-json ])
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# The ResponderMixin adds methods that help you manage what
|
|
84
|
-
# formats your controllers have available, determine what format(s)
|
|
85
|
-
# the client requested and is capable of handling, and perform
|
|
86
|
-
# content negotiation to pick the proper content format to
|
|
87
|
-
# deliver.
|
|
88
|
-
#
|
|
89
|
-
# If you hear someone say "Use provides" they're talking about the
|
|
90
|
-
# Responder. If you hear someone ask "What happened to respond_to?"
|
|
91
|
-
# it was replaced by provides and the other Responder methods.
|
|
92
|
-
#
|
|
93
|
-
# == A simple example
|
|
94
|
-
#
|
|
95
|
-
# The best way to understand how all of these pieces fit together is
|
|
96
|
-
# with an example. Here's a simple web-service ready resource that
|
|
97
|
-
# provides a list of all the widgets we know about. The widget list is
|
|
98
|
-
# available in 3 formats: :html (the default), plus :xml and :text.
|
|
99
|
-
#
|
|
100
|
-
# class Widgets < Application
|
|
101
|
-
# provides :html # This is the default, but you can
|
|
102
|
-
# # be explicit if you like.
|
|
103
|
-
# provides :xml, :text
|
|
104
|
-
#
|
|
105
|
-
# def index
|
|
106
|
-
# @widgets = Widget.fetch
|
|
107
|
-
# render @widgets
|
|
108
|
-
# end
|
|
109
|
-
# end
|
|
110
|
-
#
|
|
111
|
-
# Let's look at some example requests for this list of widgets. We'll
|
|
112
|
-
# assume they're all GET requests, but that's only to make the examples
|
|
113
|
-
# easier; this works for the full set of RESTful methods.
|
|
114
|
-
#
|
|
115
|
-
# 1. The simplest case, /widgets.html
|
|
116
|
-
# Since the request includes a specific format (.html) we know
|
|
117
|
-
# what format to return. Since :html is in our list of provided
|
|
118
|
-
# formats, that's what we'll return. +render+ will look
|
|
119
|
-
# for an index.html.erb (or another template format
|
|
120
|
-
# like index.html.mab; see the documentation on Template engines)
|
|
121
|
-
#
|
|
122
|
-
# 2. Almost as simple, /widgets.xml
|
|
123
|
-
# This is very similar. They want :xml, we have :xml, so
|
|
124
|
-
# that's what they get. If +render+ doesn't find an
|
|
125
|
-
# index.xml.builder or similar template, it will call +to_xml+
|
|
126
|
-
# on @widgets. This may or may not do something useful, but you can
|
|
127
|
-
# see how it works.
|
|
128
|
-
#
|
|
129
|
-
# 3. A browser request for /widgets
|
|
130
|
-
# This time the URL doesn't say what format is being requested, so
|
|
131
|
-
# we'll look to the HTTP Accept: header. If it's '*/*' (anything),
|
|
132
|
-
# we'll use the first format on our list, :html by default.
|
|
133
|
-
#
|
|
134
|
-
# If it parses to a list of accepted formats, we'll look through
|
|
135
|
-
# them, in order, until we find one we have available. If we find
|
|
136
|
-
# one, we'll use that. Otherwise, we can't fulfill the request:
|
|
137
|
-
# they asked for a format we don't have. So we raise
|
|
138
|
-
# 406: Not Acceptable.
|
|
139
|
-
#
|
|
140
|
-
# == A more complex example
|
|
141
|
-
#
|
|
142
|
-
# Sometimes you don't have the same code to handle each available
|
|
143
|
-
# format. Sometimes you need to load different data to serve
|
|
144
|
-
# /widgets.xml versus /widgets.txt. In that case, you can use
|
|
145
|
-
# +content_type+ to determine what format will be delivered.
|
|
146
|
-
#
|
|
147
|
-
# class Widgets < Application
|
|
148
|
-
# def action1
|
|
149
|
-
# if content_type == :text
|
|
150
|
-
# Widget.load_text_formatted(params[:id])
|
|
151
|
-
# else
|
|
152
|
-
# render
|
|
153
|
-
# end
|
|
154
|
-
# end
|
|
155
|
-
#
|
|
156
|
-
# def action2
|
|
157
|
-
# case content_type
|
|
158
|
-
# when :html
|
|
159
|
-
# handle_html()
|
|
160
|
-
# when :xml
|
|
161
|
-
# handle_xml()
|
|
162
|
-
# when :text
|
|
163
|
-
# handle_text()
|
|
164
|
-
# else
|
|
165
|
-
# render
|
|
166
|
-
# end
|
|
167
|
-
# end
|
|
168
|
-
# end
|
|
169
|
-
#
|
|
170
|
-
# You can do any standard Ruby flow control using +content_type+. If
|
|
171
|
-
# you don't call it yourself, it will be called (triggering content
|
|
172
|
-
# negotiation) by +render+.
|
|
173
|
-
#
|
|
174
|
-
# Once +content_type+ has been called, the output format is frozen,
|
|
175
|
-
# and none of the provides methods can be used.
|
|
176
|
-
module ResponderMixin
|
|
177
|
-
|
|
178
|
-
def self.included(base) # :nodoc:
|
|
179
|
-
base.extend(ClassMethods)
|
|
180
|
-
base.class_eval do
|
|
181
|
-
class_inheritable_accessor :class_provided_formats
|
|
182
|
-
class_inheritable_accessor :class_provided_format_arguments
|
|
183
|
-
end
|
|
184
|
-
base.reset_provides
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
module ClassMethods
|
|
188
|
-
|
|
189
|
-
# Adds symbols representing formats to the controller's
|
|
190
|
-
# default list of provided_formats. These will apply to
|
|
191
|
-
# every action in the controller, unless modified in the action.
|
|
192
|
-
# If the last argument is a Hash or an Array, these are regarded
|
|
193
|
-
# as arguments to pass to the to_<mime_type> method as needed.
|
|
194
|
-
def provides(*formats, &block)
|
|
195
|
-
options = extract_provides_options(formats, &block)
|
|
196
|
-
formats.each do |fmt|
|
|
197
|
-
self.class_provided_formats << fmt unless class_provided_formats.include?(fmt)
|
|
198
|
-
self.class_provided_format_arguments[fmt] = options unless options.nil?
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Overwrites the controller's list of provided_formats. These
|
|
203
|
-
# will apply to every action in the controller, unless modified
|
|
204
|
-
# in the action.
|
|
205
|
-
def only_provides(*formats)
|
|
206
|
-
clear_provides
|
|
207
|
-
provides(*formats)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
# Removes formats from the controller's
|
|
211
|
-
# default list of provided_formats. These will apply to
|
|
212
|
-
# every action in the controller, unless modified in the action.
|
|
213
|
-
def does_not_provide(*formats)
|
|
214
|
-
self.class_provided_formats -= formats
|
|
215
|
-
formats.each { |fmt| self.class_provided_format_arguments.delete(fmt) }
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Clear any formats and their options
|
|
219
|
-
def clear_provides
|
|
220
|
-
self.class_provided_formats = []
|
|
221
|
-
self.class_provided_format_arguments = {}
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# Reset to the default list of formats
|
|
225
|
-
def reset_provides
|
|
226
|
-
only_provides(:html)
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
# Extract arguments for provided format methods
|
|
230
|
-
def extract_provides_options(args, &block)
|
|
231
|
-
return block if block_given?
|
|
232
|
-
case args.last
|
|
233
|
-
when Hash then [args.pop]
|
|
234
|
-
when Array then args.pop
|
|
235
|
-
when Proc then args.pop
|
|
236
|
-
else nil
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
# Returns the current list of formats provided for this instance
|
|
243
|
-
# of the controller. It starts with what has been set in the controller
|
|
244
|
-
# (or :html by default) but can be modifed on a per-action basis.
|
|
245
|
-
def provided_formats
|
|
246
|
-
@_provided_formats ||= class_provided_formats.dup
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# Sets the provided formats for this action. Usually, you would
|
|
250
|
-
# use a combination of +provides+, +only_provides+ and +does_not_provide+
|
|
251
|
-
# to manage this, but you can set it directly.
|
|
252
|
-
# If the last argument is a Hash or an Array, these are regarded
|
|
253
|
-
# as arguments to pass to the to_<mime_type> method as needed.
|
|
254
|
-
def set_provided_formats(*formats, &block)
|
|
255
|
-
raise_if_content_type_already_set!
|
|
256
|
-
@_provided_formats = []
|
|
257
|
-
@_provided_format_arguments = {}
|
|
258
|
-
provides(*formats.flatten, &block)
|
|
259
|
-
end
|
|
260
|
-
alias :provided_formats= :set_provided_formats
|
|
261
|
-
|
|
262
|
-
# Returns a Hash of arguments for format methods
|
|
263
|
-
def provided_format_arguments
|
|
264
|
-
@_provided_format_arguments ||= Hash.new.replace(class_provided_format_arguments)
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
# Returns the arguments (if any) for the mime_transform_method call
|
|
268
|
-
def provided_format_arguments_for(fmt)
|
|
269
|
-
self.provided_format_arguments[fmt] || Merb.mime_transform_method_defaults(fmt)
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
# Adds formats to the list of provided formats for this particular
|
|
273
|
-
# request. Usually used to add formats to a single action. See also
|
|
274
|
-
# the controller-level provides that affects all actions in a controller.
|
|
275
|
-
def provides(*formats, &block)
|
|
276
|
-
raise_if_content_type_already_set!
|
|
277
|
-
options = self.class.extract_provides_options(formats, &block)
|
|
278
|
-
formats.each do |fmt|
|
|
279
|
-
self.provided_formats << fmt unless provided_formats.include?(fmt)
|
|
280
|
-
self.provided_format_arguments[fmt] = options unless options.nil?
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
# Sets list of provided formats for this particular
|
|
285
|
-
# request. Usually used to limit formats to a single action. See also
|
|
286
|
-
# the controller-level provides that affects all actions in a controller.
|
|
287
|
-
def only_provides(*formats)
|
|
288
|
-
self.set_provided_formats(*formats)
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# Removes formats from the list of provided formats for this particular
|
|
292
|
-
# request. Usually used to remove formats from a single action. See
|
|
293
|
-
# also the controller-level provides that affects all actions in a
|
|
294
|
-
# controller.
|
|
295
|
-
def does_not_provide(*formats)
|
|
296
|
-
formats.flatten!
|
|
297
|
-
self.provided_formats -= formats
|
|
298
|
-
formats.each { |fmt| self.provided_format_arguments.delete(fmt) }
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
# Do the content negotiation:
|
|
302
|
-
# 1. if params[:format] is there, and provided, use it
|
|
303
|
-
# 2. Parse the Accept header
|
|
304
|
-
# 3. If it's */*, use the first provided format
|
|
305
|
-
# 4. Look for one that is provided, in order of request
|
|
306
|
-
# 5. Raise 406 if none found
|
|
307
|
-
def perform_content_negotiation # :nodoc:
|
|
308
|
-
raise Merb::ControllerExceptions::NotAcceptable if provided_formats.empty?
|
|
309
|
-
if fmt = params[:format]
|
|
310
|
-
if provided_formats.include?(fmt.to_sym)
|
|
311
|
-
fmt.to_sym
|
|
312
|
-
else
|
|
313
|
-
raise Merb::ControllerExceptions::NotAcceptable
|
|
314
|
-
end
|
|
315
|
-
else
|
|
316
|
-
accepts = Rest::Responder.parse(request.accept).
|
|
317
|
-
collect {|t| t.to_sym}
|
|
318
|
-
if accepts.include?(:all)
|
|
319
|
-
provided_formats.first
|
|
320
|
-
else
|
|
321
|
-
accepts.each do |type|
|
|
322
|
-
return type if provided_formats.include?(type)
|
|
323
|
-
end
|
|
324
|
-
raise Merb::ControllerExceptions::NotAcceptable
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
# Checks to see if content negotiation has already been performed.
|
|
330
|
-
# If it has, you can no longer modify the list of provided formats.
|
|
331
|
-
def content_type_set?
|
|
332
|
-
!@_content_type.nil?
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
# Returns the output format for this request, based on the
|
|
336
|
-
# provided formats, <tt>params[:format]</tt> and the client's HTTP
|
|
337
|
-
# Accept header.
|
|
338
|
-
#
|
|
339
|
-
# The first time this is called, it triggers content negotiation
|
|
340
|
-
# and caches the value. Once you call +content_type+ you can
|
|
341
|
-
# not set or change the list of provided formats.
|
|
342
|
-
#
|
|
343
|
-
# Called automatically by +render+, so you should only call it if
|
|
344
|
-
# you need the value, not to trigger content negotiation.
|
|
345
|
-
def content_type
|
|
346
|
-
unless content_type_set?
|
|
347
|
-
@_content_type = perform_content_negotiation
|
|
348
|
-
raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{@_content_type}") unless
|
|
349
|
-
Merb.available_mime_types.has_key?(@_content_type)
|
|
350
|
-
headers['Content-Type'] = Merb.available_mime_types[@_content_type].first
|
|
351
|
-
end
|
|
352
|
-
@_content_type
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
# Sets the output content_type for this request. Normally you
|
|
356
|
-
# should use +provides+, +does_not_provide+ and +only_provides+
|
|
357
|
-
# and then let the content negotiation process determine the proper
|
|
358
|
-
# content_type. However, in some circumstances you may want to
|
|
359
|
-
# set it directly, or override what content negotiation picks.
|
|
360
|
-
def content_type=(new_type)
|
|
361
|
-
@_content_type = new_type
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
private
|
|
365
|
-
|
|
366
|
-
def raise_if_content_type_already_set!
|
|
367
|
-
raise "Cannot modify provided_formats because content_type has already been set" if content_type_set?
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
module Rest
|
|
371
|
-
|
|
372
|
-
TYPES = {}
|
|
373
|
-
RESPONSE_HEADERS = Hash.new([])
|
|
374
|
-
TRANSFORM_METHODS = {}
|
|
375
|
-
TRANSFORM_METHOD_DEFAULTS = {}
|
|
376
|
-
|
|
377
|
-
class Responder
|
|
378
|
-
|
|
379
|
-
protected
|
|
380
|
-
|
|
381
|
-
def self.parse(accept_header)
|
|
382
|
-
# parse the raw accept header into a unique, sorted array of AcceptType objects
|
|
383
|
-
list = accept_header.to_s.split(/,/).enum_for(:each_with_index).map do |entry,index|
|
|
384
|
-
AcceptType.new(entry,index += 1)
|
|
385
|
-
end.sort.uniq
|
|
386
|
-
# firefox (and possibly other browsers) send broken default accept headers.
|
|
387
|
-
# fix them up by sorting alternate xml forms (namely application/xhtml+xml)
|
|
388
|
-
# ahead of pure xml types (application/xml,text/xml).
|
|
389
|
-
if app_xml = list.detect{|e| e.super_range == 'application/xml'}
|
|
390
|
-
list.select{|e| e.to_s =~ /\+xml/}.each { |acc_type|
|
|
391
|
-
list[list.index(acc_type)],list[list.index(app_xml)] =
|
|
392
|
-
list[list.index(app_xml)],list[list.index(acc_type)] }
|
|
393
|
-
end
|
|
394
|
-
list
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
class AcceptType
|
|
400
|
-
|
|
401
|
-
attr_reader :media_range, :quality, :index, :type, :sub_type
|
|
402
|
-
|
|
403
|
-
def initialize(entry,index)
|
|
404
|
-
@index = index
|
|
405
|
-
@media_range, quality = entry.split(/;\s*q=/).map{|a| a.strip }
|
|
406
|
-
@type, @sub_type = @media_range.split(/\//)
|
|
407
|
-
quality ||= 0.0 if @media_range == '*/*'
|
|
408
|
-
@quality = ((quality || 1.0).to_f * 100).to_i
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
def <=>(entry)
|
|
412
|
-
c = entry.quality <=> quality
|
|
413
|
-
c = index <=> entry.index if c == 0
|
|
414
|
-
c
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
def eql?(entry)
|
|
418
|
-
synonyms.include?(entry.media_range)
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
def ==(entry); eql?(entry); end
|
|
422
|
-
|
|
423
|
-
def hash; super_range.hash; end
|
|
424
|
-
|
|
425
|
-
def synonyms
|
|
426
|
-
@syns ||= TYPES.values.select{|e| e.include?(@media_range)}.flatten
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
def super_range
|
|
430
|
-
synonyms.first || @media_range
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
def to_sym
|
|
434
|
-
TYPES.select{|k,v|
|
|
435
|
-
v == synonyms || v[0] == synonyms[0]}.flatten.first
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
def to_s
|
|
439
|
-
@media_range
|
|
440
|
-
end
|
|
441
|
-
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
end
|
|
447
|
-
reset_default_mime_types!
|
|
448
|
-
|
|
449
|
-
end
|
|
@@ -1,558 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
# The ViewContextMixin module provides a number of helper methods to views for
|
|
3
|
-
# linking to assets and other pages, dealing with JavaScript, and caching.
|
|
4
|
-
module ViewContextMixin
|
|
5
|
-
|
|
6
|
-
include Merb::Assets::AssetHelpers
|
|
7
|
-
|
|
8
|
-
# :section: Accessing Assets
|
|
9
|
-
# Merb provides views with convenience methods for links images and other assets.
|
|
10
|
-
|
|
11
|
-
# Creates a link for the URL given in +url+ with the text in +name+; HTML options are given in the +opts+
|
|
12
|
-
# hash.
|
|
13
|
-
#
|
|
14
|
-
# ==== Options
|
|
15
|
-
# The +opts+ hash is used to set HTML attributes on the tag.
|
|
16
|
-
#
|
|
17
|
-
# ==== Examples
|
|
18
|
-
# link_to("The Merb home page", "http://www.merbivore.com/")
|
|
19
|
-
# # => <a href="http://www.merbivore.com/">The Merb home page</a>
|
|
20
|
-
#
|
|
21
|
-
# link_to("The Ruby home page", "http://www.ruby-lang.org", {'class' => 'special', 'target' => 'blank'})
|
|
22
|
-
# # => <a href="http://www.ruby-lang.org" class="special" target="blank">The Ruby home page</a>
|
|
23
|
-
#
|
|
24
|
-
# link_to p.title, "/blog/show/#{p.id}"
|
|
25
|
-
# # => <a href="blog/show/13">The Entry Title</a>
|
|
26
|
-
#
|
|
27
|
-
def link_to(name, url='', opts={})
|
|
28
|
-
opts[:href] ||= url
|
|
29
|
-
%{<a #{ opts.to_xml_attributes }>#{name}</a>}
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Creates an image tag with the +src+ attribute set to the +img+ argument. The path
|
|
33
|
-
# prefix defaults to <tt>/images/</tt>. The path prefix can be overriden by setting a +:path+
|
|
34
|
-
# parameter in the +opts+ hash. The rest of the +opts+ hash sets HTML attributes.
|
|
35
|
-
#
|
|
36
|
-
# ==== Options
|
|
37
|
-
# path:: Sets the path prefix for the image (defaults to +/images/+)
|
|
38
|
-
#
|
|
39
|
-
# All other options in +opts+ set HTML attributes on the tag.
|
|
40
|
-
#
|
|
41
|
-
# ==== Examples
|
|
42
|
-
# image_tag('foo.gif')
|
|
43
|
-
# # => <img src='/images/foo.gif' />
|
|
44
|
-
#
|
|
45
|
-
# image_tag('foo.gif', :class => 'bar')
|
|
46
|
-
# # => <img src='/images/foo.gif' class='bar' />
|
|
47
|
-
#
|
|
48
|
-
# image_tag('foo.gif', :path => '/files/')
|
|
49
|
-
# # => <img src='/files/foo.gif' />
|
|
50
|
-
#
|
|
51
|
-
# image_tag('http://test.com/foo.gif')
|
|
52
|
-
# # => <img src="http://test.com/foo.gif">
|
|
53
|
-
def image_tag(img, opts={})
|
|
54
|
-
opts[:path] ||=
|
|
55
|
-
if img =~ %r{^https?://}
|
|
56
|
-
''
|
|
57
|
-
else
|
|
58
|
-
if Merb::Config[:path_prefix]
|
|
59
|
-
Merb::Config[:path_prefix] + '/images/'
|
|
60
|
-
else
|
|
61
|
-
'/images/'
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
opts[:src] ||= opts.delete(:path) + img
|
|
65
|
-
%{<img #{ opts.to_xml_attributes } />}
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# :section: JavaScript related functions
|
|
69
|
-
#
|
|
70
|
-
|
|
71
|
-
# Escapes text for use in JavaScript, replacing unsafe strings with their
|
|
72
|
-
# escaped equivalent.
|
|
73
|
-
#
|
|
74
|
-
# ==== Examples
|
|
75
|
-
# escape_js("'Lorem ipsum!' -- Some guy")
|
|
76
|
-
# # => "\\'Lorem ipsum!\\' -- Some guy"
|
|
77
|
-
#
|
|
78
|
-
# escape_js("Please keep text\nlines as skinny\nas possible.")
|
|
79
|
-
# # => "Please keep text\\nlines as skinny\\nas possible."
|
|
80
|
-
def escape_js(javascript)
|
|
81
|
-
(javascript || '').gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Creates a link tag with the text in +name+ and the <tt>onClick</tt> handler set to a JavaScript
|
|
85
|
-
# string in +function+.
|
|
86
|
-
#
|
|
87
|
-
# ==== Examples
|
|
88
|
-
# link_to_function('Click me', "alert('hi!')")
|
|
89
|
-
# # => <a href="#" onclick="alert('hi!'); return false;">Click me</a>
|
|
90
|
-
#
|
|
91
|
-
# link_to_function('Add to cart', "item_total += 1; alert('Item added!');")
|
|
92
|
-
# # => <a href="#" onclick="item_total += 1; alert('Item added!'); return false;">Add to cart</a>
|
|
93
|
-
#
|
|
94
|
-
def link_to_function(name, function)
|
|
95
|
-
%{<a href="#" onclick="#{function}; return false;">#{name}</a>}
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# The js method simply calls +to_json+ on an object in +data+; if the object
|
|
99
|
-
# does not implement a +to_json+ method, then it calls +to_json+ on
|
|
100
|
-
# +data.inspect+.
|
|
101
|
-
#
|
|
102
|
-
# ==== Examples
|
|
103
|
-
# js({'user' => 'Lewis', 'page' => 'home'})
|
|
104
|
-
# # => "{\"user\":\"Lewis\",\"page\":\"home\"}"
|
|
105
|
-
#
|
|
106
|
-
# my_array = [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
|
107
|
-
# js(my_array)
|
|
108
|
-
# # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
|
|
109
|
-
#
|
|
110
|
-
def js(data)
|
|
111
|
-
if data.respond_to? :to_json
|
|
112
|
-
data.to_json
|
|
113
|
-
else
|
|
114
|
-
data.inspect.to_json
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# :section: External JavaScript and Stylesheets
|
|
119
|
-
#
|
|
120
|
-
# You can use require_js(:prototype) or require_css(:shinystyles)
|
|
121
|
-
# from any view or layout, and the scripts will only be included once
|
|
122
|
-
# in the head of the final page. To get this effect, the head of your layout you will
|
|
123
|
-
# need to include a call to include_required_js and include_required_css.
|
|
124
|
-
#
|
|
125
|
-
# ==== Examples
|
|
126
|
-
# # File: app/views/layouts/application.html.erb
|
|
127
|
-
#
|
|
128
|
-
# <html>
|
|
129
|
-
# <head>
|
|
130
|
-
# <%= include_required_js %>
|
|
131
|
-
# <%= include_required_css %>
|
|
132
|
-
# </head>
|
|
133
|
-
# <body>
|
|
134
|
-
# <%= catch_content :layout %>
|
|
135
|
-
# </body>
|
|
136
|
-
# </html>
|
|
137
|
-
#
|
|
138
|
-
# # File: app/views/whatever/_part1.herb
|
|
139
|
-
#
|
|
140
|
-
# <% require_js 'this' -%>
|
|
141
|
-
# <% require_css 'that', 'another_one' -%>
|
|
142
|
-
#
|
|
143
|
-
# # File: app/views/whatever/_part2.herb
|
|
144
|
-
#
|
|
145
|
-
# <% require_js 'this', 'something_else' -%>
|
|
146
|
-
# <% require_css 'that' -%>
|
|
147
|
-
#
|
|
148
|
-
# # File: app/views/whatever/index.herb
|
|
149
|
-
#
|
|
150
|
-
# <%= partial(:part1) %>
|
|
151
|
-
# <%= partial(:part2) %>
|
|
152
|
-
#
|
|
153
|
-
# # Will generate the following in the final page...
|
|
154
|
-
# <html>
|
|
155
|
-
# <head>
|
|
156
|
-
# <script src="/javascripts/this.js" type="text/javascript"></script>
|
|
157
|
-
# <script src="/javascripts/something_else.js" type="text/javascript"></script>
|
|
158
|
-
# <link href="/stylesheets/that.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
159
|
-
# <link href="/stylesheets/another_one.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
160
|
-
# </head>
|
|
161
|
-
# .
|
|
162
|
-
# .
|
|
163
|
-
# .
|
|
164
|
-
# </html>
|
|
165
|
-
#
|
|
166
|
-
# See each method's documentation for more information.
|
|
167
|
-
|
|
168
|
-
# :section: Bundling Asset Files
|
|
169
|
-
#
|
|
170
|
-
# The key to making a fast web application is to reduce both the amount of
|
|
171
|
-
# data transfered and the number of client-server interactions. While having
|
|
172
|
-
# many small, module Javascript or stylesheet files aids in the development
|
|
173
|
-
# process, your web application will benefit from bundling those assets in
|
|
174
|
-
# the production environment.
|
|
175
|
-
#
|
|
176
|
-
# An asset bundle is a set of asset files which are combined into a single
|
|
177
|
-
# file. This reduces the number of requests required to render a page, and
|
|
178
|
-
# can reduce the amount of data transfer required if you're using gzip
|
|
179
|
-
# encoding.
|
|
180
|
-
#
|
|
181
|
-
# Asset bundling is always enabled in production mode, and can be optionally
|
|
182
|
-
# enabled in all environments by setting the <tt>:bundle_assets</tt> value
|
|
183
|
-
# in <tt>config/merb.yml</tt> to +true+.
|
|
184
|
-
#
|
|
185
|
-
# ==== Examples
|
|
186
|
-
#
|
|
187
|
-
# In the development environment, this:
|
|
188
|
-
#
|
|
189
|
-
# js_include_tag :prototype, :lowpro, :bundle => true
|
|
190
|
-
#
|
|
191
|
-
# will produce two <script> elements. In the production mode, however, the
|
|
192
|
-
# two files will be concatenated in the order given into a single file,
|
|
193
|
-
# <tt>all.js</tt>, in the <tt>public/javascripts</tt> directory.
|
|
194
|
-
#
|
|
195
|
-
# To specify a different bundle name:
|
|
196
|
-
#
|
|
197
|
-
# css_include_tag :typography, :whitespace, :bundle => :base
|
|
198
|
-
# css_include_tag :header, :footer, :bundle => "content"
|
|
199
|
-
# css_include_tag :lightbox, :images, :bundle => "lb.css"
|
|
200
|
-
#
|
|
201
|
-
# (<tt>base.css</tt>, <tt>content.css</tt>, and <tt>lb.css</tt> will all be
|
|
202
|
-
# created in the <tt>public/stylesheets</tt> directory.)
|
|
203
|
-
#
|
|
204
|
-
# == Callbacks
|
|
205
|
-
#
|
|
206
|
-
# To use a Javascript or CSS compressor, like JSMin or YUI Compressor:
|
|
207
|
-
#
|
|
208
|
-
# Merb::Assets::JavascriptAssetBundler.add_callback do |filename|
|
|
209
|
-
# system("/usr/local/bin/yui-compress #{filename}")
|
|
210
|
-
# end
|
|
211
|
-
#
|
|
212
|
-
# Merb::Assets::StylesheetAssetBundler.add_callback do |filename|
|
|
213
|
-
# system("/usr/local/bin/css-min #{filename}")
|
|
214
|
-
# end
|
|
215
|
-
#
|
|
216
|
-
# These blocks will be run after a bundle is created.
|
|
217
|
-
#
|
|
218
|
-
# == Bundling Required Assets
|
|
219
|
-
#
|
|
220
|
-
# Combining the +require_css+ and +require_js+ helpers with bundling can be
|
|
221
|
-
# problematic. You may want to separate out the common assets for your
|
|
222
|
-
# application -- Javascript frameworks, common CSS, etc. -- and bundle those
|
|
223
|
-
# in a "base" bundle. Then, for each section of your site, bundle the
|
|
224
|
-
# required assets into a section-specific bundle.
|
|
225
|
-
#
|
|
226
|
-
# <b>N.B.: If you bundle an inconsistent set of assets with the same name,
|
|
227
|
-
# you will have inconsistent results. Be thorough and test often.</b>
|
|
228
|
-
#
|
|
229
|
-
# ==== Example
|
|
230
|
-
#
|
|
231
|
-
# In your application layout:
|
|
232
|
-
#
|
|
233
|
-
# js_include_tag :prototype, :lowpro, :bundle => :base
|
|
234
|
-
#
|
|
235
|
-
# In your controller layout:
|
|
236
|
-
#
|
|
237
|
-
# require_js :bundle => :posts
|
|
238
|
-
|
|
239
|
-
# The require_js method can be used to require any JavaScript
|
|
240
|
-
# file anywhere in your templates. Regardless of how many times
|
|
241
|
-
# a single script is included with require_js, Merb will only include
|
|
242
|
-
# it once in the header.
|
|
243
|
-
#
|
|
244
|
-
# ==== Examples
|
|
245
|
-
# <% require_js 'jquery' %>
|
|
246
|
-
# # A subsequent call to include_required_js will render...
|
|
247
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
248
|
-
#
|
|
249
|
-
# <% require_js 'jquery', 'effects' %>
|
|
250
|
-
# # A subsequent call to include_required_js will render...
|
|
251
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
252
|
-
# # <script src="/javascripts/effects.js" type="text/javascript"></script>
|
|
253
|
-
#
|
|
254
|
-
def require_js(*js)
|
|
255
|
-
@required_js ||= []
|
|
256
|
-
@required_js |= js
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
# The require_css method can be used to require any CSS
|
|
260
|
-
# file anywhere in your templates. Regardless of how many times
|
|
261
|
-
# a single stylesheet is included with require_css, Merb will only include
|
|
262
|
-
# it once in the header.
|
|
263
|
-
#
|
|
264
|
-
# ==== Examples
|
|
265
|
-
# <% require_css('style') %>
|
|
266
|
-
# # A subsequent call to include_required_css will render...
|
|
267
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
268
|
-
#
|
|
269
|
-
# <% require_css('style', 'ie-specific') %>
|
|
270
|
-
# # A subsequent call to include_required_css will render...
|
|
271
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
272
|
-
# # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
273
|
-
#
|
|
274
|
-
def require_css(*css)
|
|
275
|
-
@required_css ||= []
|
|
276
|
-
@required_css |= css
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
# A method used in the layout of an application to create +<script>+ tags to include JavaScripts required in
|
|
280
|
-
# in templates and subtemplates using require_js.
|
|
281
|
-
#
|
|
282
|
-
# ==== Options
|
|
283
|
-
# bundle:: The name of the bundle the scripts should be combined into.
|
|
284
|
-
# If +nil+ or +false+, the bundle is not created. If +true+, a
|
|
285
|
-
# bundle named <tt>all.js</tt> is created. Otherwise,
|
|
286
|
-
# <tt>:bundle</tt> is treated as an asset name.
|
|
287
|
-
#
|
|
288
|
-
# ==== Examples
|
|
289
|
-
# # my_action.herb has a call to require_js 'jquery'
|
|
290
|
-
# # File: layout/application.html.erb
|
|
291
|
-
# include_required_js
|
|
292
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
293
|
-
#
|
|
294
|
-
# # my_action.herb has a call to require_js 'jquery', 'effects', 'validation'
|
|
295
|
-
# # File: layout/application.html.erb
|
|
296
|
-
# include_required_js
|
|
297
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
298
|
-
# # <script src="/javascripts/effects.js" type="text/javascript"></script>
|
|
299
|
-
# # <script src="/javascripts/validation.js" type="text/javascript"></script>
|
|
300
|
-
#
|
|
301
|
-
def include_required_js(options = {})
|
|
302
|
-
return '' if @required_js.nil?
|
|
303
|
-
js_include_tag(*(@required_js + [options]))
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
# A method used in the layout of an application to create +<link>+ tags for CSS stylesheets required in
|
|
307
|
-
# in templates and subtemplates using require_css.
|
|
308
|
-
#
|
|
309
|
-
# ==== Options
|
|
310
|
-
# bundle:: The name of the bundle the stylesheets should be combined into.
|
|
311
|
-
# If +nil+ or +false+, the bundle is not created. If +true+, a
|
|
312
|
-
# bundle named <tt>all.css</tt> is created. Otherwise,
|
|
313
|
-
# <tt>:bundle</tt> is treated as an asset name.
|
|
314
|
-
#
|
|
315
|
-
# ==== Examples
|
|
316
|
-
# # my_action.herb has a call to require_css 'style'
|
|
317
|
-
# # File: layout/application.html.erb
|
|
318
|
-
# include_required_css
|
|
319
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
320
|
-
#
|
|
321
|
-
# # my_action.herb has a call to require_js 'style', 'ie-specific'
|
|
322
|
-
# # File: layout/application.html.erb
|
|
323
|
-
# include_required_css
|
|
324
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
325
|
-
# # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
|
|
326
|
-
#
|
|
327
|
-
def include_required_css(options = {})
|
|
328
|
-
return '' if @required_css.nil?
|
|
329
|
-
css_include_tag(*(@required_css + [options]))
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
# The js_include_tag method will create a JavaScript
|
|
333
|
-
# +<include>+ tag for each script named in the arguments, appending
|
|
334
|
-
# '.js' if it is left out of the call.
|
|
335
|
-
#
|
|
336
|
-
# ==== Options
|
|
337
|
-
# bundle:: The name of the bundle the scripts should be combined into.
|
|
338
|
-
# If +nil+ or +false+, the bundle is not created. If +true+, a
|
|
339
|
-
# bundle named <tt>all.js</tt> is created. Otherwise,
|
|
340
|
-
# <tt>:bundle</tt> is treated as an asset name.
|
|
341
|
-
#
|
|
342
|
-
# ==== Examples
|
|
343
|
-
# js_include_tag 'jquery'
|
|
344
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
345
|
-
#
|
|
346
|
-
# js_include_tag 'moofx.js', 'upload'
|
|
347
|
-
# # => <script src="/javascripts/moofx.js" type="text/javascript"></script>
|
|
348
|
-
# # <script src="/javascripts/upload.js" type="text/javascript"></script>
|
|
349
|
-
#
|
|
350
|
-
# js_include_tag :effects
|
|
351
|
-
# # => <script src="/javascripts/effects.js" type="text/javascript"></script>
|
|
352
|
-
#
|
|
353
|
-
# js_include_tag :jquery, :validation
|
|
354
|
-
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
|
355
|
-
# # <script src="/javascripts/validation.js" type="text/javascript"></script>
|
|
356
|
-
#
|
|
357
|
-
def js_include_tag(*scripts)
|
|
358
|
-
options = scripts.last.is_a?(Hash) ? scripts.pop : {}
|
|
359
|
-
return nil if scripts.empty?
|
|
360
|
-
|
|
361
|
-
if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && scripts.size > 1
|
|
362
|
-
bundler = Merb::Assets::JavascriptAssetBundler.new(bundle_name, *scripts)
|
|
363
|
-
bundled_asset = bundler.bundle!
|
|
364
|
-
return js_include_tag(bundled_asset)
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
tags = ""
|
|
368
|
-
|
|
369
|
-
for script in scripts
|
|
370
|
-
attrs = {
|
|
371
|
-
:src => asset_path(:javascript, script),
|
|
372
|
-
:type => "text/javascript"
|
|
373
|
-
}
|
|
374
|
-
tags << %Q{<script #{attrs.to_xml_attributes}>//</script>}
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
return tags
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
# The css_include_tag method will create a CSS stylesheet
|
|
381
|
-
# +<link>+ tag for each stylesheet named in the arguments, appending
|
|
382
|
-
# '.css' if it is left out of the call.
|
|
383
|
-
#
|
|
384
|
-
# ==== Options
|
|
385
|
-
# bundle:: The name of the bundle the stylesheets should be combined into.
|
|
386
|
-
# If +nil+ or +false+, the bundle is not created. If +true+, a
|
|
387
|
-
# bundle named <tt>all.css</tt> is created. Otherwise,
|
|
388
|
-
# <tt>:bundle</tt> is treated as an asset name.
|
|
389
|
-
# media:: The media attribute for the generated link element. Defaults
|
|
390
|
-
# to <tt>:all</tt>.
|
|
391
|
-
#
|
|
392
|
-
# ==== Examples
|
|
393
|
-
# css_include_tag 'style'
|
|
394
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" />
|
|
395
|
-
#
|
|
396
|
-
# css_include_tag 'style.css', 'layout'
|
|
397
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" />
|
|
398
|
-
# # <link href="/stylesheets/layout.css" media="all" rel="Stylesheet" type="text/css" />
|
|
399
|
-
#
|
|
400
|
-
# css_include_tag :menu
|
|
401
|
-
# # => <link href="/stylesheets/menu.css" media="all" rel="Stylesheet" type="text/css" />
|
|
402
|
-
#
|
|
403
|
-
# css_include_tag :style, :screen
|
|
404
|
-
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" />
|
|
405
|
-
# # <link href="/stylesheets/screen.css" media="all" rel="Stylesheet" type="text/css" />
|
|
406
|
-
#
|
|
407
|
-
# css_include_tag :style, :media => :print
|
|
408
|
-
# # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" />
|
|
409
|
-
def css_include_tag(*stylesheets)
|
|
410
|
-
options = stylesheets.last.is_a?(Hash) ? stylesheets.pop : {}
|
|
411
|
-
return nil if stylesheets.empty?
|
|
412
|
-
|
|
413
|
-
if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && stylesheets.size > 1
|
|
414
|
-
bundler = Merb::Assets::StylesheetAssetBundler.new(bundle_name, *stylesheets)
|
|
415
|
-
bundled_asset = bundler.bundle!
|
|
416
|
-
return css_include_tag(bundled_asset)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
tags = ""
|
|
420
|
-
|
|
421
|
-
for stylesheet in stylesheets
|
|
422
|
-
attrs = {
|
|
423
|
-
:href => asset_path(:stylesheet, stylesheet),
|
|
424
|
-
:type => "text/css",
|
|
425
|
-
:rel => "Stylesheet",
|
|
426
|
-
:media => options[:media] || :all
|
|
427
|
-
}
|
|
428
|
-
tags << %Q{<link #{attrs.to_xml_attributes} />}
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
return tags
|
|
432
|
-
end
|
|
433
|
-
|
|
434
|
-
# :section: Caching
|
|
435
|
-
# ViewContextMixin provides views with fragment caching facilities.
|
|
436
|
-
|
|
437
|
-
# The cache method is a simple helper method
|
|
438
|
-
# for caching template fragments. The value of the supplied
|
|
439
|
-
# block is stored in the cache and identified by the string
|
|
440
|
-
# in the +name+ argument.
|
|
441
|
-
#
|
|
442
|
-
# ==== Example
|
|
443
|
-
# <h1>Article list</h1>
|
|
444
|
-
#
|
|
445
|
-
# <% cache(:article_list) do %>
|
|
446
|
-
# <ul>
|
|
447
|
-
# <% @articles.each do |a| %>
|
|
448
|
-
# <li><%= a.title %></li>
|
|
449
|
-
# <% end %>
|
|
450
|
-
# </ul>
|
|
451
|
-
# <% end %>
|
|
452
|
-
#
|
|
453
|
-
# See the documentation for Merb::Caching::Fragment for more
|
|
454
|
-
# information.
|
|
455
|
-
#
|
|
456
|
-
def cache(name, &block)
|
|
457
|
-
return block.call unless caching_enabled?
|
|
458
|
-
buffer = eval("_buf", block.binding)
|
|
459
|
-
if fragment = ::Merb::Caching::Fragment.get(name)
|
|
460
|
-
buffer.concat(fragment)
|
|
461
|
-
else
|
|
462
|
-
pos = buffer.length
|
|
463
|
-
block.call
|
|
464
|
-
::Merb::Caching::Fragment.put(name, buffer[pos..-1])
|
|
465
|
-
end
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
# Calling throw_content stores the block of markup for later use.
|
|
469
|
-
# Subsequently, you can make calls to it by name with <tt>catch_content</tt>
|
|
470
|
-
# in another template or in the layout.
|
|
471
|
-
#
|
|
472
|
-
# Example:
|
|
473
|
-
#
|
|
474
|
-
# <% throw_content :header do %>
|
|
475
|
-
# alert('hello world')
|
|
476
|
-
# <% end %>
|
|
477
|
-
#
|
|
478
|
-
# You can use catch_content :header anywhere in your templates.
|
|
479
|
-
#
|
|
480
|
-
# <%= catch_content :header %>
|
|
481
|
-
#
|
|
482
|
-
# You may find that you have trouble using thrown content inside a helper method
|
|
483
|
-
# There are a couple of mechanisms to get around this.
|
|
484
|
-
#
|
|
485
|
-
# 1. Pass the content in as a string instead of a block
|
|
486
|
-
#
|
|
487
|
-
# Example:
|
|
488
|
-
#
|
|
489
|
-
# throw_content(:header, "Hello World")
|
|
490
|
-
#
|
|
491
|
-
def throw_content(name, content = "", &block)
|
|
492
|
-
content << capture(&block) if block_given?
|
|
493
|
-
controller.thrown_content[name] << content
|
|
494
|
-
end
|
|
495
|
-
|
|
496
|
-
# Concat will concatenate text directly to the buffer of the template.
|
|
497
|
-
# The binding must be supplied in order to obtian the buffer. This can be called directly in the
|
|
498
|
-
# template as
|
|
499
|
-
# concat( "text", binding )
|
|
500
|
-
#
|
|
501
|
-
# or from a helper method that accepts a block as
|
|
502
|
-
# concat( "text", block.binding )
|
|
503
|
-
def concat( string, binding )
|
|
504
|
-
_buffer( binding ) << string
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
# Creates a generic HTML tag. You can invoke it a variety of ways.
|
|
508
|
-
#
|
|
509
|
-
# tag :div
|
|
510
|
-
# # <div></div>
|
|
511
|
-
#
|
|
512
|
-
# tag :div, 'content'
|
|
513
|
-
# # <div>content</div>
|
|
514
|
-
#
|
|
515
|
-
# tag :div, :class => 'class'
|
|
516
|
-
# # <div class="class"></div>
|
|
517
|
-
#
|
|
518
|
-
# tag :div, 'content', :class => 'class'
|
|
519
|
-
# # <div class="class">content</div>
|
|
520
|
-
#
|
|
521
|
-
# tag :div do
|
|
522
|
-
# 'content'
|
|
523
|
-
# end
|
|
524
|
-
# # <div>content</div>
|
|
525
|
-
#
|
|
526
|
-
# tag :div, :class => 'class' do
|
|
527
|
-
# 'content'
|
|
528
|
-
# end
|
|
529
|
-
# # <div class="class">content</div>
|
|
530
|
-
#
|
|
531
|
-
def tag(name, contents = nil, attrs = {}, &block)
|
|
532
|
-
attrs = contents if contents.is_a?(Hash)
|
|
533
|
-
contents = capture(&block) if block_given?
|
|
534
|
-
open_tag(name, attrs) + contents.to_s + close_tag(name)
|
|
535
|
-
end
|
|
536
|
-
|
|
537
|
-
# Creates the opening tag with attributes for the provided +name+
|
|
538
|
-
# attrs is a hash where all members will be mapped to key="value"
|
|
539
|
-
#
|
|
540
|
-
# Note: This tag will need to be closed
|
|
541
|
-
def open_tag(name, attrs = nil)
|
|
542
|
-
"<#{name}#{' ' + attrs.to_html_attributes if attrs && !attrs.empty?}>"
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
# Creates a closing tag
|
|
546
|
-
def close_tag(name)
|
|
547
|
-
"</#{name}>"
|
|
548
|
-
end
|
|
549
|
-
|
|
550
|
-
# Creates a self closing tag. Like <br/> or <img src="..."/>
|
|
551
|
-
#
|
|
552
|
-
# +name+ : the name of the tag to create
|
|
553
|
-
# +attrs+ : a hash where all members will be mapped to key="value"
|
|
554
|
-
def self_closing_tag(name, attrs = nil)
|
|
555
|
-
"<#{name}#{' ' + attrs.to_html_attributes if attrs && !attrs.empty?}/>"
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
end
|