CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-webassets

Media asset management for Python, with glue code for various web frameworks

Overview
Eval results
Files

filter-system.mddocs/

Filter System

Comprehensive filter ecosystem for asset transformation including minification, compilation, preprocessing, and optimization. Filters process individual files or bundles through configurable transformation pipelines.

Capabilities

Filter Base Classes

Core filter architecture providing the foundation for all asset transformations.

class Filter:
    name = None  # Filter name for registration
    options = {}  # Supported configuration options
    max_debug_level = None  # Maximum debug level where filter runs
    
    def setup(self):
        """Initialize filter (called before use)."""
    
    def set_context(self, ctx):
        """Set processing context."""
    
    def get_config(self, setting, env=None, require=True, what='dependency', type=None):
        """
        Get configuration values.
        
        Parameters:
        - setting: Configuration key
        - env: Environment instance
        - require: Whether setting is required
        - what: Description for error messages
        - type: Expected value type
        
        Returns:
        Configuration value
        """
    
    def input(self, _in, out, **kw):
        """
        Process input files.
        
        Parameters:
        - _in: Input stream/file
        - out: Output stream/file
        - **kw: Additional context
        """
    
    def output(self, _in, out, **kw):
        """
        Process output files.
        
        Parameters:
        - _in: Input stream/file  
        - out: Output stream/file
        - **kw: Additional context
        """
    
    def open(self, out, source_path, **kw):
        """
        Direct file processing.
        
        Parameters:
        - out: Output stream
        - source_path: Source file path
        - **kw: Additional context
        """
    
    def concat(self, out, hunks, **kw):
        """
        Concatenate multiple sources.
        
        Parameters:
        - out: Output stream
        - hunks: List of input hunks
        - **kw: Additional context
        """
    
    def unique(self):
        """Return unique identifier for filter instance."""
    
    def id(self):
        """Get filter cache key."""
    
    def get_additional_cache_keys(self, **kw):
        """Additional cache dependencies."""

class CallableFilter:
    def __init__(self, callable):
        """
        Wrapper to create filters from callable functions.
        
        Parameters:
        - callable: Function to wrap as filter
        """

class ExternalTool(Filter):
    argv = []  # Command line arguments template  
    method = None  # Filter method to implement ('input', 'output', 'open')
    
    def subprocess(self, argv, out, data=None, cwd=None):
        """
        Execute external command.
        
        Parameters:
        - argv: Command arguments
        - out: Output stream
        - data: Input data
        - cwd: Working directory
        """
    
    def parse_binary(self, string):
        """Parse binary path string."""

class JavaTool(Filter):
    """Base for Java-based filters (JAR files)."""

Filter Management

Functions for registering, resolving, and managing filters.

def get_filter(f, *args, **kwargs):
    """
    Resolve filter specification to filter instance.
    
    Parameters:
    - f: Filter name, class, or instance
    - *args: Filter arguments
    - **kwargs: Filter options
    
    Returns:
    Filter instance
    """

def register_filter(f):
    """
    Register filter class with system.
    
    Parameters:
    - f: Filter class to register
    """

Example usage:

from webassets.filter import get_filter, register_filter

# Get filter by name
jsmin_filter = get_filter('jsmin')
uglify_filter = get_filter('uglifyjs', compress=False)

# Register custom filter
class MyCustomFilter(Filter):
    name = 'mycustom'
    def input(self, _in, out, **kw):
        # Custom processing
        pass

register_filter(MyCustomFilter)

JavaScript Filters

Minification and optimization filters for JavaScript files.

# Built-in JavaScript filters (import from webassets.filter.*)
class JSMin:
    """JavaScript minification using jsmin library."""

class RJSMin:
    """rJSMin JavaScript minifier with better performance."""
    
class UglifyJS:
    """UglifyJS minifier with advanced optimization."""
    options = {
        'binary': 'uglifyjs',
        'compress': True,
        'mangle': True
    }

class ClosureJS:
    """Google Closure Compiler for JavaScript optimization."""
    options = {
        'binary': 'closure-compiler',
        'compilation_level': 'SIMPLE_OPTIMIZATIONS'
    }

class YUIJS:
    """YUI JavaScript compressor."""
    options = {
        'binary': 'yuicompressor',
        'jar': None
    }

class Slimit:
    """Slimit JavaScript minifier."""

class JSPacker:
    """JavaScript packer for extreme compression."""

CSS Filters

Minification, optimization, and URL processing filters for CSS files.

# Built-in CSS filters
class CSSMin:
    """CSS minification using cssmin library."""

class RCSSMin:
    """rCSSMin CSS minifier with better performance."""

class CleanCSS:
    """CleanCSS minifier with advanced optimization."""
    options = {
        'binary': 'cleancss',
        'level': 1
    }

class YUICSS:
    """YUI CSS compressor."""
    options = {
        'binary': 'yuicompressor',
        'jar': None
    }

class CSSSlimmer:
    """CSS Slimmer for CSS optimization."""

class CSSUtils:
    """CSS utilities for parsing and processing."""

class CSSRewrite:
    """CSS URL rewriting for asset path correction."""
    options = {
        'replace': None,
        'base': None
    }

class CSSDataUri:
    """Convert CSS references to data URIs."""
    options = {
        'max_size': 8192,
        'include_pattern': None
    }

class CSSPrefixer:
    """CSS prefixer for vendor prefixes."""

class AutoPrefixer:
    """Autoprefixer for automatic vendor prefix addition."""
    options = {
        'binary': 'autoprefixer',
        'browsers': None
    }

CSS Preprocessors

Compilation filters for CSS preprocessing languages.

# CSS preprocessor filters
class Sass:
    """Sass/SCSS compilation using Ruby Sass."""
    options = {
        'binary': 'sass',
        'style': 'compressed',
        'includes': []
    }

class SCSS:
    """SCSS compilation (alias for Sass)."""

class LibSass:
    """LibSass compilation using libsass library."""
    options = {
        'style': 'compressed',
        'include_paths': []
    }

class NodeSass:
    """Node-sass compilation."""
    options = {
        'binary': 'node-sass',
        'output_style': 'compressed'
    }

class RubySass:  
    """Ruby Sass compilation."""

class RubySCSS:
    """Ruby SCSS compilation."""

class Less:
    """Less compilation."""
    options = {
        'binary': 'lessc',
        'compress': True
    }

class Stylus:
    """Stylus compilation."""
    options = {
        'binary': 'stylus',
        'compress': True
    }

class CleverCSS:
    """CleverCSS compilation."""

class PyScss:
    """pyScss compilation using Python library."""
    options = {
        'style': 'compressed',
        'imports': []
    }

class Compass:
    """Compass compilation framework."""
    options = {
        'binary': 'compass',
        'style': 'compressed',
        'images_dir': 'images'
    }

class PostCSS:
    """PostCSS processing with plugins."""
    options = {
        'binary': 'postcss',
        'plugins': []
    }

JavaScript Preprocessors and Templating

Compilation and templating filters for JavaScript and related languages.

# JavaScript preprocessors
class CoffeeScript:
    """CoffeeScript compilation."""
    options = {
        'binary': 'coffee',
        'bare': False
    }

class TypeScript:
    """TypeScript compilation."""
    options = {
        'binary': 'tsc',
        'target': 'es5',
        'module': 'commonjs'
    }

class Babel:
    """Babel transpilation for modern JavaScript."""
    options = {
        'binary': 'babel',
        'presets': ['env']
    }

# Template engines
class Handlebars:
    """Handlebars template compilation."""
    options = {
        'binary': 'handlebars',
        'namespace': 'templates'
    }

class Jinja2:
    """Jinja2 template processing."""

class JST:
    """JavaScript templates (Underscore.js style)."""
    options = {
        'namespace': 'JST',
        'bare': False
    }

class DustJS:
    """Dust.js template compilation."""
    options = {
        'binary': 'dustc',
        'name': None
    }

class Jade:
    """Jade template compilation."""
    options = {
        'binary': 'jade',
        'pretty': False
    }

Specialized Filters

Advanced filters for specific optimization and processing tasks.

# Specialized filters
class RequireJS:
    """RequireJS optimizer (r.js)."""
    options = {
        'binary': 'r.js',
        'baseUrl': None,
        'optimize': 'uglify2'
    }

class Spritemapper:
    """CSS sprite generation."""
    options = {
        'binary': 'spritemapper',
        'output_css': None,
        'output_image': None
    }

class ClosureTemplateFilter:
    """Closure Templates compilation."""
    options = {
        'binary': 'SoyToJsSrcCompiler.jar',
        'jar': None
    }

class ClosureStylesheetsCompiler:
    """Closure Stylesheets compiler."""
    options = {
        'binary': 'closure-stylesheets.jar',
        'jar': None
    }

class ClosureStylesheetsMinifier:
    """Closure Stylesheets minifier."""
    options = {
        'binary': 'closure-stylesheets.jar',
        'jar': None
    }

Advanced Filter Usage

Custom Filter Creation

from webassets.filter import Filter

class CustomSassFilter(Filter):
    name = 'custom_sass'
    options = {
        'style': 'compressed',
        'include_paths': []
    }
    
    def input(self, _in, out, **kw):
        import sass
        
        # Get configuration  
        style = self.get_config('style', require=False) or 'compressed'
        include_paths = self.get_config('include_paths', require=False) or []
        
        # Process input
        source = _in.read()
        result = sass.compile(
            string=source,
            output_style=style,
            include_paths=include_paths
        )
        
        out.write(result)

# Register and use
from webassets.filter import register_filter
register_filter(CustomSassFilter)

# Use in bundle
Bundle('style.scss', filters='custom_sass', output='style.css')

Filter Chaining

# Chain multiple filters
Bundle(
    'app.js',
    'utils.js',
    filters=['babel', 'uglifyjs'],  # Babel first, then UglifyJS
    output='gen/app.js'
)

# CSS preprocessing and optimization
Bundle(
    'style.scss',
    filters=['sass', 'autoprefixer', 'cssmin'],
    output='gen/style.css'
)

# Complex filter chain
Bundle(
    'template.handlebars',
    'app.coffee',
    filters=['handlebars', 'coffeescript', 'uglifyjs'],
    output='gen/compiled.js'
)

Filter Configuration

from webassets import Environment, Bundle

env = Environment('./static', '/static')

# Global filter configuration
env.config['uglifyjs_binary'] = '/usr/local/bin/uglifyjs'
env.config['sass_style'] = 'compressed'
env.config['autoprefixer_browsers'] = ['last 2 versions', 'ie >= 9']

# Bundle-specific filter options
Bundle(
    'app.js',
    filters={'uglifyjs': {'compress': False, 'mangle': True}},
    output='gen/app.js'
)

# Environment-specific settings
if env.debug:
    js_filters = None  # No minification in debug
else:
    js_filters = ['babel', 'uglifyjs']

Bundle('app.js', filters=js_filters, output='gen/app.js')

Conditional Filter Application

def get_js_filters(debug=False):
    if debug:
        return ['babel']  # Only transpile, don't minify
    else:
        return ['babel', 'uglifyjs']  # Transpile and minify

def get_css_filters(debug=False):
    base_filters = ['sass', 'autoprefixer']
    if not debug:
        base_filters.append('cssmin')
    return base_filters

# Create bundles with conditional filters
js_bundle = Bundle(
    'app.js',
    filters=get_js_filters(env.debug),
    output='gen/app.js'
)

css_bundle = Bundle(
    'style.scss', 
    filters=get_css_filters(env.debug),
    output='gen/style.css'
)

Install with Tessl CLI

npx tessl i tessl/pypi-webassets

docs

bundle-management.md

caching-versioning.md

command-line.md

configuration-loading.md

environment-configuration.md

filter-system.md

framework-integration.md

index.md

merge-system.md

updater-system.md

utilities.md

tile.json