Custom resolvers¶
The resolver is a pluggable object that webassets uses to find the
contents of a Bundle
on the filesystem, as well as to
generate the correct urls to these files.
For example, the default resolver searches the
Environment.load_path
, or looks within
Environment.directory
. The webassets Django integration
will use Django’s staticfile finders to look for files.
For normal usage, you will not need to write your own resolver, or
indeed need to know how they work. However, if you want to integrate
webassets
with another framework, or if your application is
complex enough that it requires custom file referencing, read on.
The API as webassets sees it¶
webassets
expects to find the resolver via the
Environment.resolver
property, and expects this object to
provide the following methods:
-
Resolver.
resolve_source
(ctx, item)¶ Given
item
from a Bundle’s contents, this has to return the final value to use, usually an absolute filesystem path.Note
It is also allowed to return urls and bundle instances (or generally anything else the calling
Bundle
instance may be able to handle). Indeed this is the reason why the name of this method does not imply a return type.The incoming item is usually a relative path, but may also be an absolute path, or a url. These you will commonly want to return unmodified.
This method is also allowed to resolve
item
to multiple values, in which case a list should be returned. This is commonly used ifitem
includes glob instructions (wildcards).Note
Instead of this, subclasses should consider implementing
search_for_source()
instead.
-
Resolver.
resolve_output_to_path
(ctx, target, bundle)¶ Given
target
, this has to return the absolute filesystem path to which the output file ofbundle
should be written.target
may be a relative or absolute path, and is usually taking from theBundle.output
property.If a version-placeholder is used (
%(version)s
, it is still unresolved at this point.
-
Resolver.
resolve_source_to_url
(ctx, filepath, item)¶ Given the absolute filesystem path in
filepath
, as well as the original value fromBundle.contents
which resolved to this path, this must return the absolute url through which the file is to be referenced.Depending on the use case, either the
filepath
or theitem
argument will be more helpful in generating the url.This method should raise a
ValueError
if the url cannot be determined.
-
Resolver.
resolve_output_to_url
(ctx, target)¶ Given
target
, this has to return the url through which the output file can be referenced.target
may be a relative or absolute path, and is usually taking from theBundle.output
property.This is different from
resolve_source_to_url()
in that you do not passed along the result ofresolve_output_to_path()
. This is because in many use cases, the filesystem is not available at the point where the output url is needed (the media server may on a different machine).
Methods to overwrite¶
However, in practice, you will usually want to override the builtin
Resolver
, and customize it’s behaviour where necessary. The
default resolver already splits what is is doing into multiple
methods; so that you can either override them, or
refer to them in your own implementation, as makes sense.
Instead of the official entrypoints above, you may instead prefer to override the following methods of the default resolver class:
-
Resolver.
search_for_source
(ctx, item)¶ Called by
resolve_source()
after determining thatitem
is a relative filesystem path.You should always overwrite this method, and let
resolve_source()
deal with absolute paths, urls and other types of items that a bundle may contain.
-
Resolver.
search_load_path
(ctx, item)¶ This is called by
search_for_source()
when aEnvironment.load_path
is set.If you want to change how the load path is processed, overwrite this method.
Helpers to use¶
The following methods of the default resolver class you may find useful as helpers while implementing your subclass:
-
Resolver.
consider_single_directory
(directory, item)¶ Searches for
item
withindirectory
. Is able to resolve glob instructions.Subclasses can call this when they have narrowed done the location of a bundle item to a single directory.
-
Resolver.
glob
(basedir, expr)¶ Evaluates a glob expression. Yields a sorted list of absolute filenames.
-
Resolver.
query_url_mapping
(ctx, filepath)¶ Searches the environment-wide url mapping (based on the urls assigned to each directory in the load path). Returns the correct url for
filepath
.Subclasses should be sure that they really want to call this method, instead of simply falling back to
super()
.
Example: A prefix resolver¶
The following is a simple resolver implementation that searches for files in a different directory depending on the first directory part.
from webassets.env import Resolver
class PrefixResolver(Resolver):
def __init__(self, prefixmap):
self.map = prefixmap
def search_for_source(self, ctx, item):
parts = item.split('/', 1)
if len(parts) < 2:
raise ValueError(
'"%s" not valid; a static path requires a prefix.' % item)
prefix, name = parts
if not prefix in self.map:
raise ValueError(('Prefix "%s" of static path "%s" is not '
'registered') % (prefix, item))
# For the rest, defer to base class method, which provides
# support for things like globbing.
return self.consider_single_directory(self.map[prefix], name)
Using it:
env = webassets.Environment(path, url)
env.resolver = PrefixResolver({
'app1': '/var/www/app1/static',
'app2': '/srv/deploy/media/app2',
})
bundle = Bundle(
'app2/scripts/jquery.js',
'app1/*.js',
)
Other implementations¶
- django-assets Resolver
(search for
class DjangoResolver
). - Flask-Assets Resolver
(search for
class FlaskResolver
). - pyramid_webassets Resolver
(search for
class PyramidResolver
).