lib/roadie/path_rewriter_provider.rb
# frozen_string_literal: true
module Roadie
# @api public
# This provider acts a bit like a pipeline in normal UNIX parlour by enabling
# you to make changes to the requested path. Some uses of this include:
#
# * Convert absolute URLs into local filesystem paths.
# * Convert between external DNS name into internal naming.
# * Changing path structure of filenames.
# * Removing digests from filenames.
# * Handle query string logic.
# * Skipping known-bad paths.
#
# There might be other useful things you could use it for. The basic premise
# is that a path is sent in to this provider, maybe modified and then passed
# on to the "upstream" provider (or {ProviderList}).
#
# If the block returns {nil} or {false}, the upstream provider will not be
# invoked and it will be treated as "not found". This makes it possible to
# use this provider as a filter only.
#
# @example Simple regex
# provider = Roadie::PathRewriterProvider.new(other_provider) { |path|
# path.gsub(/-[a-f0-9]+\.css$/, '.css')
# }
#
# @example Filtering assets
# # Only assets containing "email" in the path will be considered by other_provider
# only_email_provider = Roadie::PathRewriterProvider.new(other_provider) { |path|
# path =~ /email/ ? path : nil
# }
#
# @example Handling "external" app assets as local assets
# document.external_asset_providers = [
# # Look for assets from "myapp.com" just like if we just specified a local path
# Roadie::PathRewriterProvider.new(document.asset_providers) { |url|
# uri = URI.parse(url)
# uri.path if uri.host == "myapp.com"
# },
# # Any other asset should be downloaded like normal
# Roadie::NetHttpProvider.new
# ]
class PathRewriterProvider
attr_reader :provider, :filter
def initialize(provider, &filter)
@provider = provider
@filter = filter
end
def find_stylesheet(path)
new_path = filter.call(path)
provider.find_stylesheet(new_path) if new_path
end
def find_stylesheet!(path)
new_path = filter.call(path)
if new_path
provider.find_stylesheet!(new_path)
else
raise CssNotFound.new(
css_name: path,
message: "Filter returned #{new_path.inspect}"
)
end
end
end
end