Skip to content
This repository
Browse code

Add *_url helpers to get the full assets URL

Adds `image_url`, `javascript_url`, `stylesheet_url`, `audio_url`,
`video_url`, and `font_url` to assets tag helper. These URL helpers will
return the full path to your assets. This is useful when you are going
to reference this asset from external host.
  • Loading branch information...
commit bcd3b870cea567ffc626144a0292fba7797a4c78 1 parent 20bc3d4
Prem Sichanugrist authored
4  actionpack/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,9 @@
1 1
 ## Rails 4.0.0 (unreleased) ##
2 2
 
  3
+*   Adds `image_url`, `javascript_url`, `stylesheet_url`, `audio_url`, `video_url`, and `font_url`
  4
+    to assets tag helper. These URL helpers will return the full path to your assets. This is useful
  5
+    when you are going to reference this asset from external host. *Prem Sichanugrist*
  6
+
3 7
 *   Default responder will now always use your overridden block in `respond_with` to render your response. *Prem Sichanugrist*
4 8
 
5 9
 *   Allow `value_method` and `text_method` arguments from `collection_select` and
32  actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -278,6 +278,13 @@ def image_path(source)
278 278
       end
279 279
       alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
280 280
 
  281
+      # Computes the full URL to an image asset in the public images directory.
  282
+      # This will use +image_path+ internally, so most of their behaviors will be the same.
  283
+      def image_url(source)
  284
+        URI.join(current_host, path_to_image(source)).to_s
  285
+      end
  286
+      alias_method :url_to_image, :image_url # aliased to avoid conflicts with an image_url named route
  287
+
281 288
       # Computes the path to a video asset in the public videos directory.
282 289
       # Full paths from the document root will be passed through.
283 290
       # Used internally by +video_tag+ to build the video path.
@@ -293,6 +300,13 @@ def video_path(source)
293 300
       end
294 301
       alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route
295 302
 
  303
+      # Computes the full URL to a video asset in the public videos directory.
  304
+      # This will use +video_path+ internally, so most of their behaviors will be the same.
  305
+      def video_url(source)
  306
+        URI.join(current_host, path_to_video(source)).to_s
  307
+      end
  308
+      alias_method :url_to_video, :video_url # aliased to avoid conflicts with an video_url named route
  309
+
296 310
       # Computes the path to an audio asset in the public audios directory.
297 311
       # Full paths from the document root will be passed through.
298 312
       # Used internally by +audio_tag+ to build the audio path.
@@ -308,6 +322,13 @@ def audio_path(source)
308 322
       end
309 323
       alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
310 324
 
  325
+      # Computes the full URL to a audio asset in the public audios directory.
  326
+      # This will use +audio_path+ internally, so most of their behaviors will be the same.
  327
+      def audio_url(source)
  328
+        URI.join(current_host, path_to_audio(source)).to_s
  329
+      end
  330
+      alias_method :url_to_audio, :audio_url # aliased to avoid conflicts with an audio_url named route
  331
+
311 332
       # Computes the path to a font asset in the public fonts directory.
312 333
       # Full paths from the document root will be passed through.
313 334
       #
@@ -322,6 +343,13 @@ def font_path(source)
322 343
       end
323 344
       alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route
324 345
 
  346
+      # Computes the full URL to a font asset in the public fonts directory.
  347
+      # This will use +font_path+ internally, so most of their behaviors will be the same.
  348
+      def font_url(source)
  349
+        URI.join(current_host, path_to_font(source)).to_s
  350
+      end
  351
+      alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route
  352
+
325 353
       # Returns an html image tag for the +source+. The +source+ can be a full
326 354
       # path or a file that exists in your public images directory.
327 355
       #
@@ -463,6 +491,10 @@ def multiple_sources_tag(type, sources)
463 491
             tag(type, options)
464 492
           end
465 493
         end
  494
+
  495
+        def current_host
  496
+          url_for(:only_path => false)
  497
+        end
466 498
     end
467 499
   end
468 500
 end
7  actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
@@ -87,6 +87,13 @@ def javascript_path(source)
87 87
         end
88 88
         alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
89 89
 
  90
+        # Computes the full URL to a javascript asset in the public javascripts directory.
  91
+        # This will use +javascript_path+ internally, so most of their behaviors will be the same.
  92
+        def javascript_url(source)
  93
+          URI.join(current_host, path_to_javascript(source)).to_s
  94
+        end
  95
+        alias_method :url_to_javascript, :javascript_url # aliased to avoid conflicts with a javascript_url named route
  96
+
90 97
         # Returns an HTML script tag for each of the +sources+ provided.
91 98
         #
92 99
         # Sources may be paths to JavaScript files. Relative paths are assumed to be relative
7  actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
@@ -65,6 +65,13 @@ def stylesheet_path(source)
65 65
         end
66 66
         alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route
67 67
 
  68
+        # Computes the full URL to a stylesheet asset in the public stylesheets directory.
  69
+        # This will use +stylesheet_path+ internally, so most of their behaviors will be the same.
  70
+        def stylesheet_url(source)
  71
+          URI.join(current_host, path_to_stylesheet(source)).to_s
  72
+        end
  73
+        alias_method :url_to_stylesheet, :stylesheet_url # aliased to avoid conflicts with a stylesheet_url named route
  74
+
68 75
         # Returns a stylesheet link tag for the sources specified as arguments. If
69 76
         # you don't specify an extension, <tt>.css</tt> will be appended automatically.
70 77
         # You can modify the link attributes by passing a hash as the last argument.
131  actionpack/test/template/asset_tag_helper_test.rb
@@ -88,6 +88,18 @@ def teardown
88 88
     %(path_to_javascript("/super/xmlhr.js")) => %(/super/xmlhr.js)
89 89
   }
90 90
 
  91
+  JavascriptUrlToTag = {
  92
+    %(javascript_url("xmlhr")) => %(http://www.example.com/javascripts/xmlhr.js),
  93
+    %(javascript_url("super/xmlhr")) => %(http://www.example.com/javascripts/super/xmlhr.js),
  94
+    %(javascript_url("/super/xmlhr.js")) => %(http://www.example.com/super/xmlhr.js)
  95
+  }
  96
+
  97
+  UrlToJavascriptToTag = {
  98
+    %(url_to_javascript("xmlhr")) => %(http://www.example.com/javascripts/xmlhr.js),
  99
+    %(url_to_javascript("super/xmlhr")) => %(http://www.example.com/javascripts/super/xmlhr.js),
  100
+    %(url_to_javascript("/super/xmlhr.js")) => %(http://www.example.com/super/xmlhr.js)
  101
+  }
  102
+
91 103
   JavascriptIncludeToTag = {
92 104
     %(javascript_include_tag("bank")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
93 105
     %(javascript_include_tag("bank.js")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
@@ -119,6 +131,20 @@ def teardown
119 131
     %(path_to_stylesheet('/dir/file.rcss')) => %(/dir/file.rcss)
120 132
   }
121 133
 
  134
+  StyleUrlToTag = {
  135
+    %(stylesheet_url("bank")) => %(http://www.example.com/stylesheets/bank.css),
  136
+    %(stylesheet_url("bank.css")) => %(http://www.example.com/stylesheets/bank.css),
  137
+    %(stylesheet_url('subdir/subdir')) => %(http://www.example.com/stylesheets/subdir/subdir.css),
  138
+    %(stylesheet_url('/subdir/subdir.css')) => %(http://www.example.com/subdir/subdir.css)
  139
+  }
  140
+
  141
+  UrlToStyleToTag = {
  142
+    %(url_to_stylesheet("style")) => %(http://www.example.com/stylesheets/style.css),
  143
+    %(url_to_stylesheet("style.css")) => %(http://www.example.com/stylesheets/style.css),
  144
+    %(url_to_stylesheet('dir/file')) => %(http://www.example.com/stylesheets/dir/file.css),
  145
+    %(url_to_stylesheet('/dir/file.rcss')) => %(http://www.example.com/dir/file.rcss)
  146
+  }
  147
+
122 148
   StyleLinkToTag = {
123 149
     %(stylesheet_link_tag("bank")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
124 150
     %(stylesheet_link_tag("bank.css")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
@@ -149,6 +175,20 @@ def teardown
149 175
     %(path_to_image("/dir/xml.png")) => %(/dir/xml.png)
150 176
   }
151 177
 
  178
+  ImageUrlToTag = {
  179
+    %(image_url("xml"))          => %(http://www.example.com/images/xml),
  180
+    %(image_url("xml.png"))      => %(http://www.example.com/images/xml.png),
  181
+    %(image_url("dir/xml.png"))  => %(http://www.example.com/images/dir/xml.png),
  182
+    %(image_url("/dir/xml.png")) => %(http://www.example.com/dir/xml.png)
  183
+  }
  184
+
  185
+  UrlToImageToTag = {
  186
+    %(url_to_image("xml"))          => %(http://www.example.com/images/xml),
  187
+    %(url_to_image("xml.png"))      => %(http://www.example.com/images/xml.png),
  188
+    %(url_to_image("dir/xml.png"))  => %(http://www.example.com/images/dir/xml.png),
  189
+    %(url_to_image("/dir/xml.png")) => %(http://www.example.com/dir/xml.png)
  190
+  }
  191
+
152 192
   ImageLinkToTag = {
153 193
     %(image_tag("xml.png")) => %(<img alt="Xml" src="/images/xml.png" />),
154 194
     %(image_tag("rss.gif", :alt => "rss syndication")) => %(<img alt="rss syndication" src="/images/rss.gif" />),
@@ -189,6 +229,20 @@ def teardown
189 229
     %(path_to_video("/dir/xml.ogg")) => %(/dir/xml.ogg)
190 230
   }
191 231
 
  232
+  VideoUrlToTag = {
  233
+    %(video_url("xml"))          => %(http://www.example.com/videos/xml),
  234
+    %(video_url("xml.ogg"))      => %(http://www.example.com/videos/xml.ogg),
  235
+    %(video_url("dir/xml.ogg"))  => %(http://www.example.com/videos/dir/xml.ogg),
  236
+    %(video_url("/dir/xml.ogg")) => %(http://www.example.com/dir/xml.ogg)
  237
+  }
  238
+
  239
+  UrlToVideoToTag = {
  240
+    %(url_to_video("xml"))          => %(http://www.example.com/videos/xml),
  241
+    %(url_to_video("xml.ogg"))      => %(http://www.example.com/videos/xml.ogg),
  242
+    %(url_to_video("dir/xml.ogg"))  => %(http://www.example.com/videos/dir/xml.ogg),
  243
+    %(url_to_video("/dir/xml.ogg")) => %(http://www.example.com/dir/xml.ogg)
  244
+  }
  245
+
192 246
   VideoLinkToTag = {
193 247
     %(video_tag("xml.ogg")) => %(<video src="/videos/xml.ogg" />),
194 248
     %(video_tag("rss.m4v", :autoplay => true, :controls => true)) => %(<video autoplay="autoplay" controls="controls" src="/videos/rss.m4v" />),
@@ -206,7 +260,7 @@ def teardown
206 260
     %(video_tag(["multiple.ogg", "multiple.avi"], :size => "160x120", :controls => true)) => %(<video controls="controls" height="120" width="160"><source src="/videos/multiple.ogg" /><source src="/videos/multiple.avi" /></video>)
207 261
   }
208 262
 
209  
- AudioPathToTag = {
  263
+  AudioPathToTag = {
210 264
     %(audio_path("xml"))          => %(/audios/xml),
211 265
     %(audio_path("xml.wav"))      => %(/audios/xml.wav),
212 266
     %(audio_path("dir/xml.wav"))  => %(/audios/dir/xml.wav),
@@ -220,6 +274,20 @@ def teardown
220 274
     %(path_to_audio("/dir/xml.wav")) => %(/dir/xml.wav)
221 275
   }
222 276
 
  277
+  AudioUrlToTag = {
  278
+    %(audio_url("xml"))          => %(http://www.example.com/audios/xml),
  279
+    %(audio_url("xml.wav"))      => %(http://www.example.com/audios/xml.wav),
  280
+    %(audio_url("dir/xml.wav"))  => %(http://www.example.com/audios/dir/xml.wav),
  281
+    %(audio_url("/dir/xml.wav")) => %(http://www.example.com/dir/xml.wav)
  282
+  }
  283
+
  284
+  UrlToAudioToTag = {
  285
+    %(url_to_audio("xml"))          => %(http://www.example.com/audios/xml),
  286
+    %(url_to_audio("xml.wav"))      => %(http://www.example.com/audios/xml.wav),
  287
+    %(url_to_audio("dir/xml.wav"))  => %(http://www.example.com/audios/dir/xml.wav),
  288
+    %(url_to_audio("/dir/xml.wav")) => %(http://www.example.com/dir/xml.wav)
  289
+  }
  290
+
223 291
   AudioLinkToTag = {
224 292
     %(audio_tag("xml.wav")) => %(<audio src="/audios/xml.wav" />),
225 293
     %(audio_tag("rss.wav", :autoplay => true, :controls => true)) => %(<audio autoplay="autoplay" controls="controls" src="/audios/rss.wav" />),
@@ -242,6 +310,14 @@ def test_path_to_javascript_alias_for_javascript_path
242 310
     PathToJavascriptToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
243 311
   end
244 312
 
  313
+  def test_javascript_url
  314
+    JavascriptUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  315
+  end
  316
+
  317
+  def test_url_to_javascript_alias_for_javascript_url
  318
+    UrlToJavascriptToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  319
+  end
  320
+
245 321
   def test_javascript_include_tag_with_blank_asset_id
246 322
     ENV["RAILS_ASSET_ID"] = ""
247 323
     JavascriptIncludeToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
@@ -349,6 +425,15 @@ def test_path_to_stylesheet_alias_for_stylesheet_path
349 425
     PathToStyleToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
350 426
   end
351 427
 
  428
+  def test_stylesheet_url
  429
+    ENV["RAILS_ASSET_ID"] = ""
  430
+    StyleUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  431
+  end
  432
+
  433
+  def test_url_to_stylesheet_alias_for_stylesheet_url
  434
+    UrlToStyleToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  435
+  end
  436
+
352 437
   def test_stylesheet_link_tag
353 438
     ENV["RAILS_ASSET_ID"] = ""
354 439
     StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
@@ -433,6 +518,14 @@ def test_path_to_image_alias_for_image_path
433 518
     PathToImageToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
434 519
   end
435 520
 
  521
+  def test_image_url
  522
+    ImageUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  523
+  end
  524
+
  525
+  def test_url_to_image_alias_for_image_url
  526
+    UrlToImageToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  527
+  end
  528
+
436 529
   def test_image_alt
437 530
     [nil, '/', '/foo/bar/', 'foo/bar/'].each do |prefix|
438 531
       assert_equal 'Rails', image_alt("#{prefix}rails.png")
@@ -478,6 +571,14 @@ def test_path_to_video_alias_for_video_path
478 571
     PathToVideoToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
479 572
   end
480 573
 
  574
+  def test_video_url
  575
+    VideoUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  576
+  end
  577
+
  578
+  def test_url_to_video_alias_for_video_url
  579
+    UrlToVideoToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  580
+  end
  581
+
481 582
   def test_video_tag
482 583
     VideoLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
483 584
   end
@@ -490,6 +591,14 @@ def test_path_to_audio_alias_for_audio_path
490 591
     PathToAudioToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
491 592
   end
492 593
 
  594
+  def test_audio_url
  595
+    AudioUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  596
+  end
  597
+
  598
+  def test_url_to_audio_alias_for_audio_url
  599
+    UrlToAudioToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
  600
+  end
  601
+
493 602
   def test_audio_tag
494 603
     AudioLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
495 604
   end
@@ -573,7 +682,6 @@ def test_caching_image_path_with_caching_and_proc_asset_host_using_request
573 682
       end
574 683
     end
575 684
 
576  
-
577 685
     @controller.request.stubs(:ssl?).returns(false)
578 686
     assert_equal "http://assets15.example.com/images/xml.png", image_path("xml.png")
579 687
 
@@ -1141,6 +1249,22 @@ def test_should_compute_proper_path_with_asset_host_and_default_protocol
1141 1249
     assert_dom_equal(%(<img alt="Mouse2" onmouseover="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse_over2.png'" onmouseout="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse2.png'" src="gopher://assets.example.com/collaboration/hieraki/images/mouse2.png" />), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png")))
1142 1250
   end
1143 1251
 
  1252
+  def test_should_compute_proper_url_with_asset_host
  1253
+    @controller.config.asset_host = "assets.example.com"
  1254
+    assert_dom_equal(%(<link href="http://www.example.com/collaboration/hieraki" rel="alternate" title="RSS" type="application/rss+xml" />), auto_discovery_link_tag)
  1255
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_url("xmlhr"))
  1256
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_url("style"))
  1257
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/images/xml.png), image_url("xml.png"))
  1258
+  end
  1259
+
  1260
+  def test_should_compute_proper_url_with_asset_host_and_default_protocol
  1261
+    @controller.config.asset_host = "assets.example.com"
  1262
+    @controller.config.default_asset_host_protocol = :request
  1263
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_url("xmlhr"))
  1264
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_url("style"))
  1265
+    assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/images/xml.png), image_url("xml.png"))
  1266
+  end
  1267
+
1144 1268
   def test_should_ignore_asset_host_on_complete_url
1145 1269
     @controller.config.asset_host = "http://assets.example.com"
1146 1270
     assert_dom_equal(%(<link href="http://bar.example.com/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag("http://bar.example.com/stylesheets/style.css"))
@@ -1154,16 +1278,19 @@ def test_should_ignore_asset_host_on_scheme_relative_url
1154 1278
   def test_should_wildcard_asset_host_between_zero_and_four
1155 1279
     @controller.config.asset_host = 'http://a%d.example.com'
1156 1280
     assert_match(%r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_path('xml.png'))
  1281
+    assert_match(%r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_url('xml.png'))
1157 1282
   end
1158 1283
 
1159 1284
   def test_asset_host_without_protocol_should_be_protocol_relative
1160 1285
     @controller.config.asset_host = 'a.example.com'
1161 1286
     assert_equal 'gopher://a.example.com/collaboration/hieraki/images/xml.png', image_path('xml.png')
  1287
+    assert_equal 'gopher://a.example.com/collaboration/hieraki/images/xml.png', image_url('xml.png')
1162 1288
   end
1163 1289
 
1164 1290
   def test_asset_host_without_protocol_should_be_protocol_relative_even_if_path_present
1165 1291
     @controller.config.asset_host = 'a.example.com/files/go/here'
1166 1292
     assert_equal 'gopher://a.example.com/files/go/here/collaboration/hieraki/images/xml.png', image_path('xml.png')
  1293
+    assert_equal 'gopher://a.example.com/files/go/here/collaboration/hieraki/images/xml.png', image_url('xml.png')
1167 1294
   end
1168 1295
 
1169 1296
   def test_assert_css_and_js_of_the_same_name_return_correct_extension
24  railties/guides/source/action_view_overview.textile
Source Rendered
@@ -585,6 +585,14 @@ Computes the path to an image asset in the +public/images+ directory. Full paths
585 585
 image_path("edit.png") # => /images/edit.png
586 586
 </ruby>
587 587
 
  588
+h5. image_url
  589
+
  590
+Computes the url to an image asset in the +public/images+ directory. This will call +image_path+ internally and merge with your current host or your asset host.
  591
+
  592
+<ruby>
  593
+image_url("edit.png") # => http://www.example.com/images/edit.png
  594
+</ruby>
  595
+
588 596
 h5. image_tag
589 597
 
590 598
 Returns an html image tag for the source. The source can be a full path or a file that exists in your +public/images+ directory.
@@ -629,6 +637,14 @@ Computes the path to a JavaScript asset in the +public/javascripts+ directory. I
629 637
 javascript_path "common" # => /javascripts/common.js
630 638
 </ruby>
631 639
 
  640
+h5. javascript_url
  641
+
  642
+Computes the url to a JavaScript asset in the +public/javascripts+ directory. This will call +javascript_path+ internally and merge with your current host or your asset host.
  643
+
  644
+<ruby>
  645
+javascript_url "common" # => http://www.example.com/javascripts/common.js
  646
+</ruby>
  647
+
632 648
 h5. stylesheet_link_tag
633 649
 
634 650
 Returns a stylesheet link tag for the sources specified as arguments. If you don't specify an extension, +.css+ will be appended automatically.
@@ -659,6 +675,14 @@ Computes the path to a stylesheet asset in the +public/stylesheets+ directory. I
659 675
 stylesheet_path "application" # => /stylesheets/application.css
660 676
 </ruby>
661 677
 
  678
+h5. stylesheet_url
  679
+
  680
+Computes the url to a stylesheet asset in the +public/stylesheets+ directory. This will call +stylesheet_path+ internally and merge with your current host or your asset host.
  681
+
  682
+<ruby>
  683
+stylesheet_url "application" # => http://www.example.com/stylesheets/application.css
  684
+</ruby>
  685
+
662 686
 h4. AtomFeedHelper
663 687
 
664 688
 h5. atom_feed

0 notes on commit bcd3b87

Please sign in to comment.
Something went wrong with that request. Please try again.