The following filters are included in webassets, though some may require the installation of an external library, or the availability of external tools.
You can also write custom filters.
Minifies Javascript by removing whitespace, comments, etc.
Uses the rJSmin library, which is included with webassets. However, if you have the external package installed, it will be used instead. You may want to do this to get access to the faster C-extension.
Minify Javascript and CSS with YUI Compressor.
YUI Compressor is an external tool written in Java, which needs to be available. One way to get it is to install the yuicompressor package:
pip install yuicompressor
No configuration is necessary in this case.
You can also get YUI compressor a different way and define a YUI_COMPRESSOR_PATH setting that points to the .jar file. Otherwise, an environment variable by the same name is tried. The filter will also look for a JAVA_HOME environment variable to run the .jar file, or will otherwise assume that java is on the system path.
Minify Javascript with Google Closure Compiler.
Google Closure Compiler is an external tool written in Java, which needs to be available. One way to get it is to install the closure package:
pip install closure
No configuration is necessary in this case.
You can also define a CLOSURE_COMPRESSOR_PATH setting that points to the .jar file. Otherwise, an environment variable by the same name is tried. The filter will also look for a JAVA_HOME environment variable to run the .jar file, or will otherwise assume that java is on the system path.
Supported configuration options:
A list of further options to be passed to the Closure compiler. There are a lot of them.
For options which take values you want to use two items in the list:
['--output_wrapper', 'foo: %output%']
Minify Javascript using UglifyJS.
The filter requires version 2 of UglifyJS.
UglifyJS is an external tool written for NodeJS; this filter assumes that the uglifyjs executable is in the path. Otherwise, you may define a UGLIFYJS_BIN setting.
Additional options may be passed to uglifyjs using the setting UGLIFYJS_EXTRA_ARGS, which expects a list of strings.
Minifies Javascript by removing whitespace, comments, etc.
This filter uses a Python port of Douglas Crockford’s JSMin, which needs to be installed separately.
There are actually multiple implementations available, for example one by Baruch Even. Easiest to install via PyPI is the one by Dave St. Germain:
$ pip install jsmin
The filter is tested with this jsmin package from PyPI, but will work with any module that exposes a JavascriptMinify object with a minify method.
If you want to avoid installing another dependency, use the webassets.filter.rjsmin.RJSMin filter instead.
Reduces the size of Javascript using an inline compression algorithm, i.e. the script will be unpacked on the client side by the browser.
Based on Dean Edwards’ jspacker 2, as ported by Florian Schulze.
Minifies CSS.
Requires the cssmin package (http://github.com/zacharyvoase/cssmin), which is a port of the YUI CSS compression algorithm.
Converts less markup to real CSS.
This depends on the NodeJS implementation of less, installable via npm. To use the old Ruby-based version (implemented in the 1.x Ruby gem), see Less.
Supported configuration options:
Compiling less in the browser
less is an interesting case because it is written in Javascript and capable of running in the browser. While for performance reason you should prebuild your stylesheets in production, while developing you may be interested in serving the original less files to the client, and have less compile them in the browser.
To do so, you first need to make sure the less filter is not applied when Environment.debug is True. You can do so via an option:
env.config['less_run_in_debug'] = False
Second, in order for the less to identify the less source files as needing to be compiled, they have to be referenced with a rel="stylesheet/less" attribute. One way to do this is to use the Bundle.extra dictionary, which works well with the template tags that webassets provides for some template languages:
less_bundle = Bundle(
'**/*.less',
filters='less',
extra={'rel': 'stylesheet/less' if env.debug else 'stylesheet'}
)
Then, for example in a Jinja2 template, you would write:
{% assets less_bundle %}
<link rel="{{ EXTRA.rel }}" type="text/css" href="{{ ASSET_URL }}">
{% endassets %}
With this, the <link> tag will sport the correct rel value both in development and in production.
Finally, you need to include the less compiler:
if env.debug:
js_bundle.contents += 'http://lesscss.googlecode.com/files/less-1.3.0.min.js'
Converts Less markup to real CSS.
This uses the old Ruby implementation available in the 1.x versions of the less gem. All 2.x versions of the gem are wrappers around the newer NodeJS/Javascript implementation, which you are generally encouraged to use, and which is available in webassets via the Less filter.
This filter for the Ruby version is being kept around for backwards-compatibility.
Supported configuration options:
Converts Sass markup to real CSS.
Requires the Sass executable to be available externally. To install it, you might be able to do:
$ sudo gem install sass
By default, this works as an “input filter”, meaning sass is called for each source file in the bundle. This is because the path of the source file is required so that @import directives within the Sass file can be correctly resolved.
However, it is possible to use this filter as an “output filter”, meaning the source files will first be concatenated, and then the Sass filter is applied in one go. This can provide a speedup for bigger projects.
To use Sass as an output filter:
from webassets.filter import get_filter
sass = get_filter('sass', as_output=True)
Bundle(...., filters=(sass,))
If you want to use the output filter mode and still also use the @import directive in your Sass files, you will need to pass along the includes_dir argument, which specifies the path to which the imports are relative to (this is implemented by changing the working directory before calling the sass executable):
sass = get_filter('sass', as_output=True, includes_dir='/tmp')
If you are confused as to why this is necessary, consider that in the case of an output filter, the source files might come from various places in the filesystem, put are merged together and passed to Sass as one big chunk. The filter cannot by itself know which of the source directories to use as a base.
Support configuration options:
If set to True, will cause Sass to output debug information to be used by the FireSass Firebug plugin. Corresponds to the --debug-info command line option of Sass.
Note that for this, Sass uses @media rules, which are not removed by a CSS compressor. You will thus want to make sure that this option is disabled in production.
By default, the value of this option will depend on the environment DEBUG setting.
Version of the sass filter that uses the SCSS syntax.
Converts Compass .sass files to CSS.
Requires at least version 0.10.
To compile a standard Compass project, you only need to have to compile your main screen.sass, print.sass and ie.sass files. All the partials that you include will be handled by Compass.
If you want to combine the filter with other CSS filters, make sure this one runs first.
Supported configuration options:
Converts Scss markup to real CSS.
This uses PyScss, a native Python implementation of the Scss language. The PyScss module needs to be installed. It’s API has been changing; currently, version 1.1.5 is known to be supported.
This is an alternative to using the sass or scss filters, which are based on the original, external tools.
Note
The Sass syntax is not supported by PyScss. You need to use the sass filter based on the original Ruby implementation instead.
Supported configuration options:
Include debug information in the output for use with FireSass.
If unset, the default value will depend on your Environment.debug setting.
Additional load paths that PyScss should use.
Warning
The filter currently does not automatically use Environment.load_path for this.
Converts Stylus markup to CSS.
Requires the Stylus executable to be available externally. You can install it using the Node Package Manager:
$ npm install -g stylus
Supported configuration options:
Converts CoffeeScript to real JavaScript.
If you want to combine it with other JavaScript filters, make sure this one runs first.
Supported configuration options:
This filter processes generic JavaScript templates. It will generate JavaScript code that runs all files through a template compiler, and makes the templates available as an object.
It was inspired by Jammit.
For example, if you have a file named license.jst:
<div class="drivers-license">
<h2>Name: <%= name %></h2>
<em>Hometown: <%= birthplace %></em>
</div>
Then, after applying this filter, you could use the template in JavaScript:
JST.license({name : "Moe", birthplace : "Brooklyn"});
The name of each template is derived from the filename. If your JST files are spread over different directories, the path up to the common prefix will be included. For example:
Bundle('templates/app1/license.jst', 'templates/app2/profile.jst',
filters='jst')
will make the templates available as app1/license and app2/profile.
Note
The filter is “generic” in the sense that it does not actually compile the templates, but wraps them in a JavaScript function call, and can thus be used with any template language. webassets also has filters for specific JavaScript template languages like DustJS or Handlebars, and those filters precompile the templates on the server, which means a performance boost on the client-side.
Unless configured otherwise, the filter will use the same micro-templating language that Jammit uses, which is turn is the same one that is available in underscore.js. The JavaScript code necessary to compile such templates will implicitly be included in the filter output.
Supported configuration options:
A string that is inserted into the generated JavaScript code in place of the function to be called that should do the compiling. Unless you specify a custom function here, the filter will include the JavaScript code of it’s own micro-templating language, which is the one used by underscore.js and Jammit.
If you assign a custom function, it is your responsibility to ensure that it is available in your final JavaScript.
If this option is set to False, then the template strings will be output directly, which is to say, JST.foo will be a string holding the raw source of the foo template.
Whether everything generated by this filter should be wrapped inside an anonymous function. Default to False.
Note
If you enable this option, the namespace must be a property of the window object, or you won’t be able to access the templates.
Compile Handlebars templates.
This filter assumes that the handlebars executable is in the path. Otherwise, you may define a HANDLEBARS_BIN setting.
Note
Use this filter if you want to precompile Handlebars templates. If compiling them in the browser is acceptable, you may use the JST filter, which needs no external dependency.
Warning
Currently, this filter is not compatible with input filters. Any filters that would run during the input-stage will simply be ignored. Input filters tend to be other compiler-style filters, so this is unlikely to be an issue.
DustJS templates compilation filter.
Takes a directory full .dust files and creates a single Javascript object that registers to the dust global when loaded in the browser:
Bundle('js/templates/', filters='dustjs')
Note that in the above example, a directory is given as the bundle contents, which is unusual, but required by this filter.
This uses the dusty compiler, which is a separate project from the DustJS implementation. To install dusty together with LinkedIn’s version of dustjs (the original does not support NodeJS > 0.4):
npm install dusty
rm -rf node_modules/dusty/node_modules/dust
git clone https://github.com/linkedin/dustjs node_modules/dust
Note
To generate the DustJS client-side Javascript, you can then do:
cd node_modules/dust
make dust
cp dist/dist-core...js your/static/assets/path
For compilation, set the DUSTY_PATH=.../node_modules/dusty/bin/dusty. Optionally, set NODE_PATH=.../node.
Source filter that rewrites relative urls in CSS files.
CSS allows you to specify urls relative to the location of the CSS file. However, you may want to store your compressed assets in a different place than source files, or merge source files from different locations. This would then break these relative CSS references, since the base URL changed.
This filter transparently rewrites CSS url() instructions in the source files to make them relative to the location of the output path. It works as a source filter, i.e. it is applied individually to each source file before they are merged.
No configuration is necessary.
The filter also supports a manual mode:
get_filter('cssrewrite', replace={'old_directory':'/custom/path/'})
This will rewrite all urls that point to files within old_directory to use /custom/path as a prefix instead.
You may plug in your own replace function:
get_filter('cssrewrite', replace=lambda url: re.sub(r'^/?images/', '/images/', url))
get_filter('cssrewrite', replace=lambda url: '/images/'+url[7:] if url.startswith('images/') else url)
Will replace CSS url() references to external files with internal data: URIs.
The external file is now included inside your CSS, which minimizes HTTP requests.
Note
Data Uris have clear disadvantages, so put some thought into if and how you would like to use them. Have a look at some performance measurements.
The filter respects a DATAURI_MAX_SIZE option, which is the maximum size (in bytes) of external files to include. The default limit is what I think should be a reasonably conservative number, 2048 bytes.
Uses CSSPrefixer to add vendor prefixes to CSS files.
Process a file through the Jinja2 templating engine.
Requires the jinja2 package (https://github.com/mitsuhiko/jinja2).
The Jinja2 context can be specified with the JINJA2_CONTEXT configuration option or directly with context={...}. Example:
Bundle('input.css', filters=Jinja2(context={'foo': 'bar'}))
Additionally to enable template loading mechanics from your project you can provide JINJA2_ENV or jinja2_env arg to make use of already created environment.
Generate CSS spritemaps using Spritemapper, a Python utility that merges multiple images into one and generates CSS positioning for the corresponding slices. Installation is easy:
pip install spritemapper
Supported configuration options:
Note: Since the spritemapper command-line utility expects source and output files to be on the filesystem, this filter interfaces directly with library internals instead. It has been tested to work with Spritemapper version 1.0.