Absolute image urls


#1

Hey,

I am sending out html emails. It seems to me that in order for the
images to be properly shown in the email, their src needs to be
absolute.

More precisely, /images/email/header.gif will not work, but
http://localhost:3000/images/email/header.gif will. (If someone can
refute me here, I am eager to hear it). So I was looking to use the
image_tag helper to get the absolute url for the image source but I
could not figure out a solution. So what I am currently doing is this:

class UserMailer < ActionMailer::Base
def setup_email(user)
(…)
url_with_host = url_for(:controller => “home”, :action =>
“index”, :only_path => false)
host_pattern = /^(.://.+?)/.$/
@body[:http_host] = url_with_host[host_pattern, 1]
content_type “text/html”

end

end

(setup_email is then called from the actual mailer methods)

But this is a hack and it supposes that there is a “home” controller.
Having the image_tag helper accept the :only_path parameter would be a
nice solution. I am curious to find out how others deal with this
problem since it does not seem to be so particular.

Thank you,
Balint


#2

I am sending out html emails. It seems to me that in order for the
images to be properly shown in the email, their src needs to be
absolute.

More precisely, /images/email/header.gif will not work, but
http://localhost:3000/images/email/header.gif will. (If someone can
refute me here, I am eager to hear it).

I can’t. That’s been my experience. Also, the images have to come
from the same domain as the email is from…

 @body[:http_host] = url_with_host[host_pattern, 1]

problem since it does not seem to be so particular.
Consider setting the asset host to the URL. That should turn those
image_tags()'s into full URLs. Not sure if there is a way to do that
only for email and not the entire site though.

-philip


#3

Hey Philip,

Thanks a lot! Based on your comment, I reread the AssetTagHelper and
found a nice® solution:

I put the following in development.rb:

ENV[‘HOST’] = ‘http://localhost:3000

images in emails have to have absolute urls

ActionController::Base.asset_host = Proc.new do |source|
if source.starts_with?(’/images/email/’)
ENV[‘HOST’]
else
“”
end
end

And then it works:

ActionView::Base.new.image_tag(’/images/email/header.gif’)
=> “<img alt=“Header” src=“http://localhost:3000/images/email/
header.gif?1234982332” />”

ActionView::Base.new.image_tag(’/images/project/header.gif’)
=> “<img alt=“Header” src=”/images/project/header.gif" />"

Although I am not sure this is more robust thatn my prev. solution
since the host has to be set explicitly.

Anyway, thank you,
Balint