diff --git a/Changelog.md b/Changelog.md index f863a83..9a49d7b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,8 @@ * `Roadie::FilesystemProvider` shows the given path when inspected. * `data-roadie-ignore` attributes will now be removed from markup; hiding "development markers" in the final email. * Add a `Roadie::CachedProvider` asset provider that wraps other providers and cache them. + * Add a `Roadie::PathRewriterProvider` asset provider that rewrites asset names for other providers. + * This saves you from having to create custom providers if you require small tweaks to the lookup in order to use an official provider. * **Deprecations:** * `Roadie::Stylesheet#each_inlinable_block` is now deprecated. You can iterate and filter the `blocks` at your own discresion. diff --git a/README.md b/README.md index dbf773a..a861f43 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ Included providers: * `NullProvider` – Does not actually provide anything, it always finds empty stylesheets. Use this in tests or if you want to ignore stylesheets that cannot be found by your other providers (or if you want to force the other providers to never run). * `NetHttpProvider` – Downloads stylesheets using `Net::HTTP`. Can be given a whitelist of hosts to download from. * `CachedProvider` – Wraps another provider (or `ProviderList`) and caches responses inside the provided cache store. +* `PathRewriterProvider` – Rewrites the passed path and then passes it on to another provider (or `ProviderList`). If you want to search several locations on the filesystem, you can declare that: @@ -229,6 +230,34 @@ document.external_asset_providers = Roadie::CachedProvider.new( ) ``` +#### `PathRewriterProvider` #### + +With this provider, you can rewrite the paths that are searched in order to more easily support another provider. Examples could include rewriting absolute URLs into something that can be found on the filesystem, or to access internal hosts instead of external ones. + +```ruby +filesystem = Roadie::FilesystemProvider.new("assets") +document.asset_providers << Roadie::PathRewriterProvider.new(filesystem) do |path| + path.sub('stylesheets', 'css').downcase +end + +document.external_asset_providers = Roadie::PathRewriterProvider.new(filesystem) do |url| + if url =~ /myapp\.com/ + URI.parse(url).path.sub(%r{^/assets}, '') + else + url + end +end +``` + +You can also wrap a list, for example to implement `external_asset_providers` by composing the normal `asset_providers`: + +```ruby +document.external_asset_providers = + Roadie::PathRewriterProvider.new(document.external_asset_providers) do |url| + URI.parse(url).path + end +``` + ### Writing your own provider ### Writing your own provider is also easy. You need to provide: diff --git a/lib/roadie.rb b/lib/roadie.rb index 69db067..49f810f 100644 --- a/lib/roadie.rb +++ b/lib/roadie.rb @@ -18,6 +18,7 @@ module Roadie require 'roadie/null_provider' require 'roadie/net_http_provider' require 'roadie/cached_provider' +require 'roadie/path_rewriter_provider' require 'roadie/asset_scanner' require 'roadie/markup_improver' diff --git a/lib/roadie/path_rewriter_provider.rb b/lib/roadie/path_rewriter_provider.rb new file mode 100644 index 0000000..6776491 --- /dev/null +++ b/lib/roadie/path_rewriter_provider.rb @@ -0,0 +1,16 @@ +module Roadie + class PathRewriterProvider + def initialize(provider, &block) + @provider = provider + @block = block + end + + def find_stylesheet(path) + @provider.find_stylesheet(@block.call(path)) + end + + def find_stylesheet!(path) + @provider.find_stylesheet!(@block.call(path)) + end + end +end diff --git a/spec/lib/roadie/path_rewriter_provider_spec.rb b/spec/lib/roadie/path_rewriter_provider_spec.rb new file mode 100644 index 0000000..7e52ae6 --- /dev/null +++ b/spec/lib/roadie/path_rewriter_provider_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' +require 'roadie/rspec' +require 'shared_examples/asset_provider' + +module Roadie + describe PathRewriterProvider do + let(:upstream) { TestProvider.new "good.css" => "body { color: green; }" } + + subject(:provider) do + PathRewriterProvider.new(upstream) do |path| + path.gsub('well', 'good') + end + end + + it_behaves_like "roadie asset provider", valid_name: "well.css", invalid_name: "bad" + end +end