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.
Files changed (294) hide show
  1. data/LICENSE +0 -20
  2. data/README +0 -277
  3. data/Rakefile +80 -199
  4. data/TODO +0 -3
  5. metadata +19 -438
  6. data/SVN_REVISION +0 -1
  7. data/app_generators/merb/USAGE +0 -5
  8. data/app_generators/merb/merb_generator.rb +0 -108
  9. data/app_generators/merb/templates/Rakefile +0 -124
  10. data/app_generators/merb/templates/app/controllers/application.rb +0 -3
  11. data/app_generators/merb/templates/app/controllers/exceptions.rb +0 -13
  12. data/app_generators/merb/templates/app/helpers/global_helper.rb +0 -5
  13. data/app_generators/merb/templates/app/mailers/views/layout/application.html.erb +0 -1
  14. data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +0 -1
  15. data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +0 -1
  16. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +0 -216
  17. data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +0 -38
  18. data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +0 -40
  19. data/app_generators/merb/templates/app/views/layout/application.html.erb +0 -11
  20. data/app_generators/merb/templates/config/boot.rb +0 -11
  21. data/app_generators/merb/templates/config/dependencies.rb +0 -41
  22. data/app_generators/merb/templates/config/environments/development.rb +0 -1
  23. data/app_generators/merb/templates/config/environments/production.rb +0 -1
  24. data/app_generators/merb/templates/config/environments/test.rb +0 -1
  25. data/app_generators/merb/templates/config/merb.yml +0 -82
  26. data/app_generators/merb/templates/config/merb_init.rb +0 -17
  27. data/app_generators/merb/templates/config/plugins.yml +0 -1
  28. data/app_generators/merb/templates/config/router.rb +0 -35
  29. data/app_generators/merb/templates/config/upload.conf +0 -0
  30. data/app_generators/merb/templates/public/images/merb.jpg +0 -0
  31. data/app_generators/merb/templates/public/merb.fcgi +0 -6
  32. data/app_generators/merb/templates/public/stylesheets/master.css +0 -119
  33. data/app_generators/merb/templates/script/destroy +0 -32
  34. data/app_generators/merb/templates/script/generate +0 -32
  35. data/app_generators/merb/templates/script/stop_merb +0 -13
  36. data/app_generators/merb/templates/script/win_script.cmd +0 -1
  37. data/app_generators/merb/templates/spec/spec.opts +0 -6
  38. data/app_generators/merb/templates/spec/spec_helper.rb +0 -15
  39. data/app_generators/merb/templates/test/test_helper.rb +0 -14
  40. data/app_generators/merb_plugin/USAGE +0 -5
  41. data/app_generators/merb_plugin/merb_plugin_generator.rb +0 -68
  42. data/app_generators/merb_plugin/templates/LICENSE +0 -20
  43. data/app_generators/merb_plugin/templates/README +0 -4
  44. data/app_generators/merb_plugin/templates/Rakefile +0 -35
  45. data/app_generators/merb_plugin/templates/TODO +0 -5
  46. data/app_generators/merb_plugin/templates/merbtasks.rb +0 -6
  47. data/app_generators/merb_plugin/templates/sampleplugin.rb +0 -10
  48. data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +0 -7
  49. data/app_generators/merb_plugin/templates/spec_helper.rb +0 -2
  50. data/bin/merb +0 -4
  51. data/lib/autotest/discover.rb +0 -3
  52. data/lib/autotest/merb_rspec.rb +0 -80
  53. data/lib/merb.rb +0 -188
  54. data/lib/merb/abstract_controller.rb +0 -399
  55. data/lib/merb/assets.rb +0 -160
  56. data/lib/merb/assets.rb.orig +0 -119
  57. data/lib/merb/boot_loader.rb +0 -286
  58. data/lib/merb/boot_loader.rb.orig +0 -235
  59. data/lib/merb/caching.rb +0 -5
  60. data/lib/merb/caching/action_cache.rb +0 -92
  61. data/lib/merb/caching/fragment_cache.rb +0 -39
  62. data/lib/merb/caching/store/file_cache.rb +0 -90
  63. data/lib/merb/caching/store/memory_cache.rb +0 -85
  64. data/lib/merb/config.rb +0 -290
  65. data/lib/merb/constants.rb +0 -50
  66. data/lib/merb/controller.rb +0 -220
  67. data/lib/merb/cookies.rb +0 -95
  68. data/lib/merb/core_ext.rb +0 -15
  69. data/lib/merb/core_ext/array.rb +0 -0
  70. data/lib/merb/core_ext/class.rb +0 -180
  71. data/lib/merb/core_ext/enumerable.rb +0 -49
  72. data/lib/merb/core_ext/get_args.rb +0 -76
  73. data/lib/merb/core_ext/hash.rb +0 -306
  74. data/lib/merb/core_ext/inflections.rb +0 -112
  75. data/lib/merb/core_ext/inflector.rb +0 -275
  76. data/lib/merb/core_ext/kernel.rb +0 -242
  77. data/lib/merb/core_ext/mash.rb +0 -88
  78. data/lib/merb/core_ext/module.rb +0 -67
  79. data/lib/merb/core_ext/numeric.rb +0 -72
  80. data/lib/merb/core_ext/object.rb +0 -183
  81. data/lib/merb/core_ext/string.rb +0 -53
  82. data/lib/merb/core_ext/symbol.rb +0 -6
  83. data/lib/merb/dispatcher.rb +0 -109
  84. data/lib/merb/drb_server.rb +0 -19
  85. data/lib/merb/erubis_ext.rb +0 -10
  86. data/lib/merb/exceptions.rb +0 -192
  87. data/lib/merb/generators/merb_app/merb_app.rb +0 -22
  88. data/lib/merb/generators/merb_generator_helpers.rb +0 -318
  89. data/lib/merb/generators/merb_plugin.rb +0 -22
  90. data/lib/merb/logger.rb +0 -78
  91. data/lib/merb/mail_controller.rb +0 -268
  92. data/lib/merb/mailer.rb +0 -87
  93. data/lib/merb/mixins/basic_authentication.rb +0 -35
  94. data/lib/merb/mixins/controller.rb +0 -160
  95. data/lib/merb/mixins/erubis_capture.rb +0 -68
  96. data/lib/merb/mixins/general_controller.rb +0 -253
  97. data/lib/merb/mixins/inline_partial.rb +0 -32
  98. data/lib/merb/mixins/render.rb +0 -465
  99. data/lib/merb/mixins/responder.rb +0 -449
  100. data/lib/merb/mixins/view_context.rb +0 -558
  101. data/lib/merb/mixins/web_controller.rb +0 -36
  102. data/lib/merb/mongrel_handler.rb +0 -168
  103. data/lib/merb/part_controller.rb +0 -29
  104. data/lib/merb/plugins.rb +0 -16
  105. data/lib/merb/rack_adapter.rb +0 -37
  106. data/lib/merb/request.rb +0 -465
  107. data/lib/merb/router.rb +0 -646
  108. data/lib/merb/server.rb +0 -169
  109. data/lib/merb/session.rb +0 -23
  110. data/lib/merb/session/cookie_store.rb +0 -118
  111. data/lib/merb/session/mem_cache_session.rb +0 -131
  112. data/lib/merb/session/memory_session.rb +0 -176
  113. data/lib/merb/template.rb +0 -37
  114. data/lib/merb/template/erubis.rb +0 -68
  115. data/lib/merb/template/haml.rb +0 -87
  116. data/lib/merb/template/markaby.rb +0 -59
  117. data/lib/merb/template/xml_builder.rb +0 -50
  118. data/lib/merb/test/fake_request.rb +0 -74
  119. data/lib/merb/test/helper.rb +0 -260
  120. data/lib/merb/test/hpricot.rb +0 -136
  121. data/lib/merb/test/multipart.rb +0 -66
  122. data/lib/merb/test/rspec.rb +0 -18
  123. data/lib/merb/test/rspec_matchers/controller_matchers.rb +0 -117
  124. data/lib/merb/test/rspec_matchers/markup_matchers.rb +0 -98
  125. data/lib/merb/upload_handler.rb +0 -80
  126. data/lib/merb/upload_progress.rb +0 -48
  127. data/lib/merb/version.rb +0 -49
  128. data/lib/merb/view_context.rb +0 -79
  129. data/lib/tasks.rb +0 -7
  130. data/lib/tasks/merb.rake +0 -54
  131. data/merb_default_generators/model/USAGE +0 -0
  132. data/merb_default_generators/model/model_generator.rb +0 -16
  133. data/merb_default_generators/model/templates/new_model_template.erb +0 -5
  134. data/merb_default_generators/resource_controller/USAGE +0 -0
  135. data/merb_default_generators/resource_controller/resource_controller_generator.rb +0 -26
  136. data/merb_default_generators/resource_controller/templates/controller.rb +0 -30
  137. data/merb_default_generators/resource_controller/templates/edit.html.erb +0 -1
  138. data/merb_default_generators/resource_controller/templates/helper.rb +0 -5
  139. data/merb_default_generators/resource_controller/templates/index.html.erb +0 -1
  140. data/merb_default_generators/resource_controller/templates/new.html.erb +0 -1
  141. data/merb_default_generators/resource_controller/templates/show.html.erb +0 -1
  142. data/merb_generators/controller/USAGE +0 -5
  143. data/merb_generators/controller/controller_generator.rb +0 -16
  144. data/merb_generators/controller/templates/controller.rb +0 -8
  145. data/merb_generators/controller/templates/helper.rb +0 -5
  146. data/merb_generators/controller/templates/index.html.erb +0 -3
  147. data/merb_generators/part_controller/USAGE +0 -5
  148. data/merb_generators/part_controller/part_controller_generator.rb +0 -27
  149. data/merb_generators/part_controller/templates/controller.rb +0 -8
  150. data/merb_generators/part_controller/templates/helper.rb +0 -5
  151. data/merb_generators/part_controller/templates/index.html.erb +0 -3
  152. data/merb_generators/resource/USAGE +0 -0
  153. data/merb_generators/resource/resource_generator.rb +0 -67
  154. data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +0 -67
  155. data/rspec_generators/merb_controller_test/templates/controller_spec.rb +0 -8
  156. data/rspec_generators/merb_controller_test/templates/edit_spec.rb +0 -12
  157. data/rspec_generators/merb_controller_test/templates/helper_spec.rb +0 -5
  158. data/rspec_generators/merb_controller_test/templates/index_spec.rb +0 -12
  159. data/rspec_generators/merb_controller_test/templates/new_spec.rb +0 -12
  160. data/rspec_generators/merb_controller_test/templates/show_spec.rb +0 -5
  161. data/rspec_generators/merb_model_test/merb_model_test_generator.rb +0 -26
  162. data/rspec_generators/merb_model_test/templates/model_spec_template.erb +0 -7
  163. data/script/destroy +0 -14
  164. data/script/generate +0 -14
  165. data/spec/fixtures/config/environments/environment_config_test.yml +0 -1
  166. data/spec/fixtures/config/merb.yml +0 -18
  167. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +0 -235
  168. data/spec/fixtures/controllers/render_spec_controllers.rb +0 -184
  169. data/spec/fixtures/foo.rb +0 -3
  170. data/spec/fixtures/mailers/views/layout/application.html.erb +0 -3
  171. data/spec/fixtures/mailers/views/layout/application.text.erb +0 -3
  172. data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +0 -1
  173. data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +0 -1
  174. data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +0 -1
  175. data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +0 -1
  176. data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +0 -1
  177. data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +0 -1
  178. data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +0 -1
  179. data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +0 -1
  180. data/spec/fixtures/models/router_spec_models.rb +0 -30
  181. data/spec/fixtures/parts/views/layout/todo_part.html.erb +0 -3
  182. data/spec/fixtures/parts/views/layout/todo_part.xml.erb +0 -3
  183. data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +0 -1
  184. data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +0 -1
  185. data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +0 -1
  186. data/spec/fixtures/parts/views/todo_part/list.html.erb +0 -3
  187. data/spec/fixtures/sample.txt +0 -1
  188. data/spec/fixtures/views/erubis.html.erb +0 -1
  189. data/spec/fixtures/views/examples/_erubis.html.erb +0 -1
  190. data/spec/fixtures/views/examples/_haml.html.haml +0 -1
  191. data/spec/fixtures/views/examples/_markaby.html.mab +0 -1
  192. data/spec/fixtures/views/examples/_throw_content.html.erb +0 -6
  193. data/spec/fixtures/views/examples/hello.xml.builder +0 -1
  194. data/spec/fixtures/views/examples/js.js.erb +0 -1
  195. data/spec/fixtures/views/examples/template_catch_content.html.erb +0 -15
  196. data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +0 -6
  197. data/spec/fixtures/views/examples/template_throw_content.html.erb +0 -10
  198. data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +0 -3
  199. data/spec/fixtures/views/exceptions/admin_access_required.html.erb +0 -1
  200. data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +0 -1
  201. data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +0 -1
  202. data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +0 -1
  203. data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +0 -1
  204. data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +0 -1
  205. data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +0 -1
  206. data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +0 -1
  207. data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
  208. data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +0 -1
  209. data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +0 -1
  210. data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +0 -1
  211. data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
  212. data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
  213. data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +0 -1
  214. data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +0 -1
  215. data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +0 -1
  216. data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +0 -4
  217. data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +0 -1
  218. data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +0 -1
  219. data/spec/fixtures/views/haml.html.haml +0 -1
  220. data/spec/fixtures/views/haml.xml.haml +0 -2
  221. data/spec/fixtures/views/layout/application.html.erb +0 -1
  222. data/spec/fixtures/views/layout/application.xml.erb +0 -1
  223. data/spec/fixtures/views/layout/nested/example.html.erb +0 -1
  224. data/spec/fixtures/views/markaby.html.mab +0 -1
  225. data/spec/fixtures/views/nested/example/test.html.erb +0 -1
  226. data/spec/fixtures/views/partials/_erubis.html.erb +0 -1
  227. data/spec/fixtures/views/partials/_erubis_collection.html.erb +0 -1
  228. data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +0 -1
  229. data/spec/fixtures/views/partials/_erubis_new.html.erb +0 -1
  230. data/spec/fixtures/views/partials/_haml.html.haml +0 -1
  231. data/spec/fixtures/views/partials/_haml_collection.html.haml +0 -1
  232. data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +0 -1
  233. data/spec/fixtures/views/partials/_haml_new.html.haml +0 -1
  234. data/spec/fixtures/views/partials/_markaby.html.mab +0 -1
  235. data/spec/fixtures/views/partials/_markaby_collection.html.mab +0 -1
  236. data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +0 -1
  237. data/spec/fixtures/views/partials/_markaby_new.html.mab +0 -1
  238. data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +0 -1
  239. data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +0 -1
  240. data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +0 -1
  241. data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +0 -4
  242. data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +0 -7
  243. data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +0 -7
  244. data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +0 -15
  245. data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +0 -15
  246. data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +0 -4
  247. data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +0 -12
  248. data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +0 -11
  249. data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +0 -14
  250. data/spec/fixtures/views/test.dir/the_template.html.erb +0 -1
  251. data/spec/merb/abstract_controller_spec.rb +0 -38
  252. data/spec/merb/assets_spec.rb +0 -207
  253. data/spec/merb/caching_spec.rb +0 -102
  254. data/spec/merb/config_spec.rb +0 -29
  255. data/spec/merb/controller_filters_spec.rb +0 -253
  256. data/spec/merb/controller_spec.rb +0 -126
  257. data/spec/merb/cookie_store_spec.rb +0 -72
  258. data/spec/merb/cookies_spec.rb +0 -96
  259. data/spec/merb/core_ext/class_spec.rb +0 -97
  260. data/spec/merb/core_ext/enumerable_spec.rb +0 -27
  261. data/spec/merb/core_ext/hash_spec.rb +0 -251
  262. data/spec/merb/core_ext/inflector_spec.rb +0 -34
  263. data/spec/merb/core_ext/kernel_spec.rb +0 -25
  264. data/spec/merb/core_ext/numeric_spec.rb +0 -26
  265. data/spec/merb/core_ext/object_spec.rb +0 -47
  266. data/spec/merb/core_ext/string_spec.rb +0 -22
  267. data/spec/merb/core_ext/symbol_spec.rb +0 -7
  268. data/spec/merb/dependency_spec.rb +0 -22
  269. data/spec/merb/dispatch_spec.rb +0 -528
  270. data/spec/merb/fake_request_spec.rb +0 -80
  271. data/spec/merb/generator_spec.rb +0 -248
  272. data/spec/merb/handler_spec.rb +0 -169
  273. data/spec/merb/mail_controller_spec.rb +0 -177
  274. data/spec/merb/mailer_spec.rb +0 -87
  275. data/spec/merb/multipart_spec.rb +0 -50
  276. data/spec/merb/part_controller_spec.rb +0 -124
  277. data/spec/merb/plugins_spec.rb +0 -80
  278. data/spec/merb/render_spec.rb +0 -469
  279. data/spec/merb/request_spec.rb +0 -287
  280. data/spec/merb/responder_spec.rb +0 -562
  281. data/spec/merb/router_spec.rb +0 -900
  282. data/spec/merb/server_spec.rb +0 -19
  283. data/spec/merb/template_spec.rb +0 -41
  284. data/spec/merb/upload_handler_spec.rb +0 -108
  285. data/spec/merb/version_spec.rb +0 -33
  286. data/spec/merb/view_context_spec.rb +0 -366
  287. data/spec/spec_generator_helper.rb +0 -34
  288. data/spec/spec_helper.rb +0 -101
  289. data/spec/spec_helpers/url_shared_behaviour.rb +0 -112
  290. data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +0 -53
  291. data/test_unit_generators/merb_controller_test/templates/functional_test.rb +0 -17
  292. data/test_unit_generators/merb_controller_test/templates/helper_test.rb +0 -9
  293. data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +0 -29
  294. data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +0 -9
@@ -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