-
Notifications
You must be signed in to change notification settings - Fork 66
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
handle asset_host #30
base: master
Are you sure you want to change the base?
Conversation
else | ||
# the original asset_host was a simple string value | ||
old_asset_host | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There may be a way to re-use the AssetUrlHelper
mixin rather than copying-and-pasting, but I didn't want to spend too much time on it before getting initial feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this part needs improvement. I might be able to take a stab at it if you don't have any ideas.
My initial thought is to move all of this into a new class (so the replacement proc
is as simple as possible, offloading everything to this new class) and have it include the helper. It would also make it easier to unit test.
The build failure seems to be a Rails 3.x compatibility problem – I'll fix later, if the overall approach seems ok. |
P.P.S. This may be a tangential question, but what should the relationship of |
@@ -3,6 +3,8 @@ module Rails | |||
end | |||
end | |||
|
|||
require "active_support/concern" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer not to use ActiveSupport::Concern
, but I cannot find any rational reason not to (we're inside the Rails
adapter, after all!) so I'll approve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any bad side effects for using ActiveSupport::Concern
?
I am curious (since I use in my gems as well)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just that standard Ruby handles this pretty easily itself without the extra sugar (which feels like adding sugar to your soda IMO, maybe it's a bit sweeter but I don't see the point right here).
Strawman time
It's a bit like having an ActiveSupport library that overrides the new
method on classes like this:
module NewWithOptionalBlock
def new(*)
instance = super
if block_given?
yield instance
end
instance
end
end
I just don't see the point in using an external library for this pattern when just adding it straight to your class would do. Just accept a block in initialize
and be done with it.
But again, I cannot say a good reason not to do it here as we're in Rails, and the argument that it's so easy to implement without Rails means that if Rails ever removes it, it's very easy to remove again. It's a double-edged sword that way. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Thanks for your explanation.
It's a tough question. On one hand, I'd like not to set an I think this PR has a good direction. I still feel a bit uneasy about the solution, even after sleeping on it for a bit, but it's also one of the cleanest solutions I can imagine right now. What I'm thinking about most is:
All in all, it seems like this is going in. I want som extra polish first, though. Thank you for taking it this far! You don't owe me anything, so if you want to leave it here I can take it further myself. If you, however, feel up for it, I'll welcome additional changes from you. Questions for you: What do you think about removing the automatic inclusion of the module and instead relying on either a "macro" or a manual inclusion of a module? class SomeMailer
include Roadie::Rails::Mailer
include Roadie::Railer::AssetHostSupport
# or:
# roadie_mutate_asset_host
end This requires a bit more setup, documentation and explanation, but it makes it opt-in and much easier to change around in the future, but it also removes part of the point of having a fully-integrated "rails gem". It appears like you're using this fork in a project already. Is it running in production? Is it working properly? |
Thanks for all your work on this. asset_host compatibility is the one thing that keeps roadie-rails from 100% unadulterated awesome ATM. EDIT: I'm going to try this branch on our app in prod, we'll see how it goes. |
Thank you, @nateberkopec. 😄 |
We've been using this on a Rails 4.X app for a while now and it's working as-expected. My asset_hosts are strings though, not procs, so we're probably the simplest use case :) |
That's very nice to hear! Thank you. 🐗 |
I'm gave the fork a try in my app and (obviously) I'm getting the same results: works well with the asset_host set, all images load and styles are inlined. Thanks @afeld for the PR and @Mange for Roadie! I like the idea of explicitly including EDIT:I got this error locally:
|
Does it handle asset host with protocol relative URI? |
Is there any plan to actually merge this? |
Not at this time. I have other things that take my attention right now. |
Version 1.1.0.rc2 might make this easier to handle, even though it's still nowhere near automatic. config.roadie.external_asset_providers = Roadie::PathRewriterProvider.new(config.roadie.asset_providers) do |url|
if url =~ /myapp\.com/
URI.parse(url).path.sub(%r{^/assets}, '')
else
url
end
end This will strip I'm thinking about writing a default provider that strips away the asset host and adds it as a default provider if you have a asset host configured. |
I just merged this branch on my company's fork, because we needed #47: https://github.com/modernmsg/roadie-rails/commit/69b62dd09fb1d730734d1f14ce2986510645bf2e @afeld if you're still interested in this PR, would you mind rebasing it? |
Note that even with this PR, we had to use a literal |
We actually moved to premailer GEM due to this issue, and it's been
working fine for us so far.
|
Just checking in here. Now that it's possible to handle assets from external URLs, one should be able to just use the normal It's a bit crazy to think about all the pieces you need to fit together to make it work[1], so if we figure out a nice way to do it here, I might make it more first-class. It's also possible to keep working on this to try to get everything working transparently out of the box, but I'm still worried about overriding private APIs of Rails and I'd like to avoid it as far as possible. [1]: You'd need to add something like this as external provider: def roadie_options
options = super.dup
# Always try this first of all
options.external_providers.push(
# Rewrite the URL to a local path, and delegate it to the local providers
# Rewrites "https://cdn.myapp.com/assets/stylesheets/foo-1234.css" to "/stylesheets/foo-1234.css".
Roadie::PathRewriterProvider.new(options.providers) do |url|
# Make your own match here, that fits your case
if url =~ /cdn\.myapp\.com/
# Strip everything except for the path, then remove the `/assets` prefix
URI.parse(url).path.sub(%r{^/assets}, '')
else
url
end
)
options
end [EDIT: I should add, you can add this to the global configuration too, without the need to override a method, |
@Mange I think that's a good solution – confirming it works: def roadie_options
options = super.dup
options.external_asset_providers = [
Roadie::PathRewriterProvider.new(options.asset_providers) do |url|
url =~ Regexp.new(Regexp.escape(Settings.asset_host)) ? URI.parse(url).path : url
end
]
options
end |
Fixes #10. Fixes #11.
I was running into the same problem as #9, where I had stylesheets and images linked from my HTML emails. This PR takes a slightly different approach than the existing code, where it intercepts the
asset_host
as the email is being rendered, rather than using matchers to strip them after the fact, as was being discussed in #10, which is messy for non-trivialasset_host
Procs.Please let me know if there are edge cases that I didn't consider!