Rails 3 and asset_hosts in css? - ruby-on-rails

I'm using rails 3 in production and development.
How do I use the asset_host path in css, for example with background-images?
I've tried:
.blerg{ background-image:url({asset_host}/images/blerg.gif); }
But it just comes out as that in the rendered document, is there anything special you have to do when including the css to get this to work?

If you are using Rails 3.1 Asset Pipline you can use the following in sass/scss
.blerg{ background-image: image-url(blerg.gif); }
The added advantage of this approach is that in production the css image will also contain the MD5 fingerprinting so you can setup a far future expires header on your background images and still have them expire if you make changes to them.

If you are serving css files from asset host all relative linked images in your css file are served from the same host.

If you just do /assets/blerg.gif it should work fine.

Related

Rails 4 Heroku Assets not loading, though in heroku asset pipeline

I have a problem with certain assets on heroku. (local environment is working fine)
The assets are in the pipeline. If I execute in the heroku rails console:
helper.asset_path("typicons.woff")
helper.asset_path("backgrounds/1.jpg")
I get the following response:
/assets/typicons-c2430aad2b6a33948dc064cfaee8ad65ff9e3ca439834f3aaa84abec3d10dea8.woff
/assets/backgrounds/1-c2098ff7e7fbb89b2d18e9cd9089f712f2b837265d1d2e4182c36c23392760c6.jpg
So I assume that the assets are in the heroku asset pipeline. As well by opening the url directly with the digest in it, I receive the file.
However if I try to reference the files in css or javascript like this:
$('.top-content').backstretch("/assets/backgrounds/1.jpg");
The file does not load. As well opening /assets/backgrounds/1.jpg directly does not work. Referencing assets from .rb or .erb files works.
Please can someone tell me, what kind of config I have to change, so the URLs for assets work as well without the digest?
Thank you!
Assuming you are using a fairly standard asset pipeline setup, this passage from the Rails Guides should help:
If you add an erb extension to a JavaScript asset, making it something such as application.js.erb, you can then use the asset_path helper in your JavaScript code:
-- http://guides.rubyonrails.org/asset_pipeline.html (section 2.3.3)
In your example, add the erb extension to your JS file and then change the line to
$('.top-content').backstretch(<%= asset_path("backgrounds/1.jpg") %>);
The problem is that Rails 4 does not support non-digested assets at all.(For whatever reason)
Here is a more thorough explanation on the issue: Non Digested Asset Names in Rails 4
My personal workaround was to add a public asset folder to my app:
public/assets/static/
and upload the assets required there. Since it was only about fonts and background images, which do not change often, it does not seem to be a problem. In the link above there are several other solutions proposed.

How do I know my whole app is Rails Asset Pipeline Compliant?

I am trying to figure out where my issue is for when I try to use aws cloudfront to render the rails assets. Not sure if there is a tool that will determine if my whole app is rails asset pipeline compliant (whether it meets its standards, etc). Any help would be appreciated, even helping me figure out how do I know for sure that my assets are coming from CloudFront and not from my app.
Here's a good tutorial to do that
https://ruby.awsblog.com/post/Tx3VS6Q2Q2K0LJR/Caching-the-Rails-Asset-Pipeline-with-Amazon-CloudFront
You can tell if serving your assets from cloudfront worked or not by viewing the page source of your production environment and see where are your css and js files served from, if it's working you'll find something like this
<link data-turbolinks-track="true" href="http://your-distribution-url.cloudfront.net/assets/application-bfe54945dee8eb9f51b20d52b93aa177.css" media="all" rel="stylesheet" />
Or if you configured a domain for your assets cdn.myapp.com for example you'll find that the assets are served from it
---------------- Update -----------------
Generally you want to organize your assets first before moving them on to a CDN, for the img tag it doesn't matter if you use image_tag or not what matters is the url of the image; if it's an asset image (that can be found in app/assets/images for example use the asset_url helper so that it is served through your asset pipeline (that doesn't apply to you application's images like user profile images).
Also in your CSS files when you use assets (background images for example) use the asset-url helper to get the image through asset pipeline.
Also it's a bad practice to add javascript into your views because you won't be able to server this javascript from your assets pipeline, try to have all your javascript in separate js or coffescript files and use the "Unobtrusive Javascript" practice (more about that in this answer What's the best way to embed a small chunk of javascript in Rails?).

Serving only font assets directly from app server

In my rails app I am serving all my assets through a CDN. I'd like to serve only my fonts directly from my app server. font_url/font-url will always include the the cdn url. Is there any convenient way to generate the path to the font (with digest) without the CDN domain or the protocol (http[s]) included?
The only thing I can think of is writing my own method that replicates the functionality of asset_path -- hopefully there is a more elegant way to achieve this.
update -- backgroun
I want to serve fonts from my main domain only to IE users so they don't break when in "high security" mode.
How to serve fonts from different servers for IE users?
IE conditional comments with Sass and Bourbon
Update:
Copy the font files into a separate folder, say "ie-high-security" for example. This is to identify them in step #2.
Serve files in the folder ("ie-high-security" in the example) by configuring the asset_host in "config/application.rb":
ActionController::Base.asset_host = Proc.new { |source|
if source.include?('/ie-high-security/')
""
else
"http://assets.example.com"
end
}
Reference the fonts in the "ie-high-security" folder in a separate stylesheet intended only for IE9.
Serve the IE9 stylesheet with conditional comments as suggested in https://stackoverflow.com/a/25415002/368697:
<!--[if IE 9]>
stylesheet using internally served fonts
<![endif]-->
Old suggestion:
Use font_path instead of font_url. The first method generates an absolute path without the asset host prepended.
If the font is being included from a stylesheet that is served from your CDN, you'll need a full path back to the app server though.

Rails 3.1 Asset Pipeline - Why should I use the Asset Helpers in a SCSS file?

I'm just getting into the Asset Pipeline; I'm using SASS/SCSS, but I'm not understanding why I should be using the Asset Helpers.
For example, if I have some CSS/SCSS without using an Asset Helper:
background-image: url('rails.png');
This will work fine because both my .SCSS file and image are in and accessible through the assets directory.
What's the point of doing this?:
background-image: asset-url("rails.png", image);
I understand it will add "/assets/" to the url, but why should I be using the Asset Helpers if the standard CSS way will work?
I think I'm missing something. Does it have something to do with deploying to production?
Using the helpers gives you access to the finger printed URLs in production. From the Asset Pipeline guide:
In the production environment Rails uses the fingerprinting scheme outlined above. By default it is assumed that assets have been precompiled and will be served as static assets by your web server.
During the precompilation phase an MD5 is generated from the contents of the compiled files, and inserted into the filenames as they are written to disc. These fingerprinted names are used by the Rails helpers in place of the manifest name.
So in production, the paths have an MD5 appended and you have things like this:
/assets/pancakes-af27b6a414e6da00003503148be9b409.png
With the checksums in place, Rails can tell browsers to cache these files forever. Then, if you do a new release that changes one of your assets, the checksum changes and that changes the whole path; the new path makes the browser think it is a whole new file so it will fetch it again. Without the checksums you can easily get old files stuck in browser caches and that sort of thing isn't exactly a happy fun time.

Rails 3.1 Asset Pipeline - turn off image asset fingerprinting on Heroku?

Because a jQuery plugin I use in my application has direct references to images, I'm trying to turn off asset fingerprinting.
So I set config.assets.digest = false in my production.rb, but now none of my image references work at all. /assets/foo.png just returns a blank response.
I really don't want to alter the jQuery plugin's code and add erb image helpers, but I'm not sure what else to do. And frankly, the asset fingerprinting for images seems to be much more trouble than it's worth.
Does anybody have any insight?
Thanks!
Someone made a gem for this purpose:
https://github.com/spohlenz/digestion
The asset pipeline is a great new component of Rails 3.1. However it
has a feature known as fingerprinting that makes it impossible to
properly incorporate many popular JavaScript libraries (including
TinyMCE, CKEditor and FancyZoom to name just a few) into the asset
pipeline.
This gem patches the asset pipeline to allow these libraries to be
used, by disabling the fingerprinting functionality for specific files
or paths.
If you are using a large plugin, like ckeditor, then your only real option is to move that plugin into the public directory.
For smaller plugins you can move their images into the correct asset path. For example if your plugin references images/icon.jpg under the plugin folder this would need to be moved to something like app/assets/images/plugin_name/icon.png and then referenced in the plugin with <%= asset_tag('plugin_name/icon.png') %>.
The pipeline IS worth it. Not using digests in production pretty much negates the point of using it at all, which is to set far-future headers so that the asset gets cached somewhere.
If you are set on removing digests then you must precompile the assets (so that Sprockets does not serve them with far-future headers), and make sure no headers are set on the server.

Resources