-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: How to work with remote asset? #10
Comments
Have you set an asset_host? That is most likely the "problem". You should be able to create an asset provider that recognizes your asset
|
|
+1 |
I'll look into it. |
You should be able to turn off class MyMailer < ActionMailer::Base
self.asset_host = nil
end This will not use the asset host for your images, so it's not a full "solution" to the problem. |
Planning for the fix happens in #11. It's not trivial to support this, so be prepared to use a workaround for some time. |
I have managed to maintain use of the |
Here's another workaround: class MyMailer < ActionMailer::Base
include Roadie::Rails::Automatic
protected
def roadie_options
super.combine({
before_transformation: method(:reverse_asset_host_on_stylesheets)
})
end
def reverse_asset_host_on_stylesheets(dom)
dom.all_css("link[rel=stylesheet]").each do |link_tag|
if link_tag["href"]
link_tag["href"] = link_tag["href"].sub(%r{^https?://assets\d\.mycoolapp\.com}, "")
end
end
end
end Does that make sense? At least you get |
Just came across this and found that while it works in principle, one also has to filter out the digest from the asset path. def reverse_asset_host_on_stylesheets(dom)
unless Rails.application.config.action_mailer.asset_host.nil?
dom.search('link[rel=stylesheet]').each do |link_tag|
if link_tag['href']
pipeline_path = link_tag['href'][Rails.application.config.action_mailer.asset_host.length..-1]
pipeline_path.sub!(/-[0-9a-f]{32,}(\.\w{1,4})(?:\?.*)\Z?/, '\1')
link_tag['href'] = '/' + pipeline_path
end
end
end
end Edited to fix regex. |
Thank you for the heads-up, Marcus! 👍 For other people: Note that his code does not work if the asset host is configured with a block, or an array. Only a single string is supported by the above code. It is also important to remember what happens if you use a |
A new version of Maybe you can use this capability to work around this problem? See the You should also upgrade |
Let me test it on Friday (if I have time then) |
Successful case (asset provider) for development: class UserAssetsProvider
ABSOLUTE_ASSET_PATH_REGEXP = /\A#{Regexp.escape("//")}.+#{Regexp.escape("/assets/")}/i
def find_stylesheet(name)
puts "name: #{name}"
return nil unless file_exists?(name)
Roadie::Stylesheet.new("whatever", stylesheet_content(name))
end
def find_stylesheet!(name)
stylesheet = find_stylesheet(name)
if stylesheet.nil?
raise Roadie::CssNotFound.new(
name,
"does not exists",
self,
)
end
stylesheet
end
private
def file_exists?(name)
if assets_precompiled?
File.exists?(local_file_path(name))
else
sprockets_asset(name)
end
end
# If on-the-fly asset compilation is disabled, we must be precompiling assets.
def assets_precompiled?
!Rails.configuration.assets.compile rescue false
end
def local_file_path(name)
asset_path = asset_path(name)
if asset_path.match(ABSOLUTE_ASSET_PATH_REGEXP)
asset_path.gsub!(ABSOLUTE_ASSET_PATH_REGEXP, "assets/")
end
File.join(Rails.public_path, asset_path)
end
def sprockets_asset(name)
asset_path = asset_path(name)
if asset_path.match(ABSOLUTE_ASSET_PATH_REGEXP)
asset_path.gsub!(ABSOLUTE_ASSET_PATH_REGEXP, "")
end
Rails.application.assets.find_asset(asset_path)
end
def asset_path(name)
name.gsub(%r{^[/]?assets/}, "")
end
Contract String => String
def stylesheet_content(name)
if assets_precompiled?
File.read(local_file_path(name))
else
# This will compile and return the asset
sprockets_asset(name).to_s
end.strip
end
end I put this class within app to make it easier to test And I put the following code in ApplicationMailer to make the image URLs absolute: def roadie_options
::Rails.application.config.roadie.tap do |options|
options.asset_providers = UserAssetsProvider.new
options.external_asset_providers = UserAssetsProvider.new
options.url_options = url_options.slice(*[
:host,
:port,
:path,
:protocol,
:scheme,
])
end
end I have the following code to ensure roadie works on mail preview: def mail(*args, &block)
super.tap do |m|
options = roadie_options
next unless options
Roadie::Rails::MailInliner.new(m, options).execute
end
end |
Tested on a remote server (staging, similar env to production) |
With my code above, it's working on production :) |
I'm using the http provider in combination with the default Rails cache store. Seems to work fine 😄 # config/initializers/roadie.rb
class RoadieRailsCacheStore
def [](path)
Rails.cache.read(path)
end
def []=(path, stylesheet)
Rails.cache.write(path, stylesheet)
end
end
Rails.configuration.roadie.external_asset_providers =
Roadie::CachedProvider.new(Roadie::NetHttpProvider.new, RoadieRailsCacheStore.new) |
@harmdewit you are a life saver! |
@harmdewit You saved my day! |
@harmdewit You're are awesome, man! |
@harmdewit You, legend! |
Haha :) |
Ok @harmdewit what happened in the last 8 hours?!! |
I got something like
//assets.my.domain/assets/mailer-4d19915455ba1fec1f18ca31aaccf9ce.css
I got this generated URL with this code:
= stylesheet_link_tag('mailer.css')
I have no idea how to get local assets
The text was updated successfully, but these errors were encountered: