or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundle-management.mdcaching-versioning.mdcommand-line.mdconfiguration-loading.mdenvironment-configuration.mdfilter-system.mdframework-integration.mdindex.mdmerge-system.mdupdater-system.mdutilities.md

filter-system.mddocs/

0

# Filter System

1

2

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

3

4

## Capabilities

5

6

### Filter Base Classes

7

8

Core filter architecture providing the foundation for all asset transformations.

9

10

```python { .api }

11

class Filter:

12

name = None # Filter name for registration

13

options = {} # Supported configuration options

14

max_debug_level = None # Maximum debug level where filter runs

15

16

def setup(self):

17

"""Initialize filter (called before use)."""

18

19

def set_context(self, ctx):

20

"""Set processing context."""

21

22

def get_config(self, setting, env=None, require=True, what='dependency', type=None):

23

"""

24

Get configuration values.

25

26

Parameters:

27

- setting: Configuration key

28

- env: Environment instance

29

- require: Whether setting is required

30

- what: Description for error messages

31

- type: Expected value type

32

33

Returns:

34

Configuration value

35

"""

36

37

def input(self, _in, out, **kw):

38

"""

39

Process input files.

40

41

Parameters:

42

- _in: Input stream/file

43

- out: Output stream/file

44

- **kw: Additional context

45

"""

46

47

def output(self, _in, out, **kw):

48

"""

49

Process output files.

50

51

Parameters:

52

- _in: Input stream/file

53

- out: Output stream/file

54

- **kw: Additional context

55

"""

56

57

def open(self, out, source_path, **kw):

58

"""

59

Direct file processing.

60

61

Parameters:

62

- out: Output stream

63

- source_path: Source file path

64

- **kw: Additional context

65

"""

66

67

def concat(self, out, hunks, **kw):

68

"""

69

Concatenate multiple sources.

70

71

Parameters:

72

- out: Output stream

73

- hunks: List of input hunks

74

- **kw: Additional context

75

"""

76

77

def unique(self):

78

"""Return unique identifier for filter instance."""

79

80

def id(self):

81

"""Get filter cache key."""

82

83

def get_additional_cache_keys(self, **kw):

84

"""Additional cache dependencies."""

85

86

class CallableFilter:

87

def __init__(self, callable):

88

"""

89

Wrapper to create filters from callable functions.

90

91

Parameters:

92

- callable: Function to wrap as filter

93

"""

94

95

class ExternalTool(Filter):

96

argv = [] # Command line arguments template

97

method = None # Filter method to implement ('input', 'output', 'open')

98

99

def subprocess(self, argv, out, data=None, cwd=None):

100

"""

101

Execute external command.

102

103

Parameters:

104

- argv: Command arguments

105

- out: Output stream

106

- data: Input data

107

- cwd: Working directory

108

"""

109

110

def parse_binary(self, string):

111

"""Parse binary path string."""

112

113

class JavaTool(Filter):

114

"""Base for Java-based filters (JAR files)."""

115

```

116

117

### Filter Management

118

119

Functions for registering, resolving, and managing filters.

120

121

```python { .api }

122

def get_filter(f, *args, **kwargs):

123

"""

124

Resolve filter specification to filter instance.

125

126

Parameters:

127

- f: Filter name, class, or instance

128

- *args: Filter arguments

129

- **kwargs: Filter options

130

131

Returns:

132

Filter instance

133

"""

134

135

def register_filter(f):

136

"""

137

Register filter class with system.

138

139

Parameters:

140

- f: Filter class to register

141

"""

142

```

143

144

Example usage:

145

```python

146

from webassets.filter import get_filter, register_filter

147

148

# Get filter by name

149

jsmin_filter = get_filter('jsmin')

150

uglify_filter = get_filter('uglifyjs', compress=False)

151

152

# Register custom filter

153

class MyCustomFilter(Filter):

154

name = 'mycustom'

155

def input(self, _in, out, **kw):

156

# Custom processing

157

pass

158

159

register_filter(MyCustomFilter)

160

```

161

162

### JavaScript Filters

163

164

Minification and optimization filters for JavaScript files.

165

166

```python { .api }

167

# Built-in JavaScript filters (import from webassets.filter.*)

168

class JSMin:

169

"""JavaScript minification using jsmin library."""

170

171

class RJSMin:

172

"""rJSMin JavaScript minifier with better performance."""

173

174

class UglifyJS:

175

"""UglifyJS minifier with advanced optimization."""

176

options = {

177

'binary': 'uglifyjs',

178

'compress': True,

179

'mangle': True

180

}

181

182

class ClosureJS:

183

"""Google Closure Compiler for JavaScript optimization."""

184

options = {

185

'binary': 'closure-compiler',

186

'compilation_level': 'SIMPLE_OPTIMIZATIONS'

187

}

188

189

class YUIJS:

190

"""YUI JavaScript compressor."""

191

options = {

192

'binary': 'yuicompressor',

193

'jar': None

194

}

195

196

class Slimit:

197

"""Slimit JavaScript minifier."""

198

199

class JSPacker:

200

"""JavaScript packer for extreme compression."""

201

```

202

203

### CSS Filters

204

205

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

206

207

```python { .api }

208

# Built-in CSS filters

209

class CSSMin:

210

"""CSS minification using cssmin library."""

211

212

class RCSSMin:

213

"""rCSSMin CSS minifier with better performance."""

214

215

class CleanCSS:

216

"""CleanCSS minifier with advanced optimization."""

217

options = {

218

'binary': 'cleancss',

219

'level': 1

220

}

221

222

class YUICSS:

223

"""YUI CSS compressor."""

224

options = {

225

'binary': 'yuicompressor',

226

'jar': None

227

}

228

229

class CSSSlimmer:

230

"""CSS Slimmer for CSS optimization."""

231

232

class CSSUtils:

233

"""CSS utilities for parsing and processing."""

234

235

class CSSRewrite:

236

"""CSS URL rewriting for asset path correction."""

237

options = {

238

'replace': None,

239

'base': None

240

}

241

242

class CSSDataUri:

243

"""Convert CSS references to data URIs."""

244

options = {

245

'max_size': 8192,

246

'include_pattern': None

247

}

248

249

class CSSPrefixer:

250

"""CSS prefixer for vendor prefixes."""

251

252

class AutoPrefixer:

253

"""Autoprefixer for automatic vendor prefix addition."""

254

options = {

255

'binary': 'autoprefixer',

256

'browsers': None

257

}

258

```

259

260

### CSS Preprocessors

261

262

Compilation filters for CSS preprocessing languages.

263

264

```python { .api }

265

# CSS preprocessor filters

266

class Sass:

267

"""Sass/SCSS compilation using Ruby Sass."""

268

options = {

269

'binary': 'sass',

270

'style': 'compressed',

271

'includes': []

272

}

273

274

class SCSS:

275

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

276

277

class LibSass:

278

"""LibSass compilation using libsass library."""

279

options = {

280

'style': 'compressed',

281

'include_paths': []

282

}

283

284

class NodeSass:

285

"""Node-sass compilation."""

286

options = {

287

'binary': 'node-sass',

288

'output_style': 'compressed'

289

}

290

291

class RubySass:

292

"""Ruby Sass compilation."""

293

294

class RubySCSS:

295

"""Ruby SCSS compilation."""

296

297

class Less:

298

"""Less compilation."""

299

options = {

300

'binary': 'lessc',

301

'compress': True

302

}

303

304

class Stylus:

305

"""Stylus compilation."""

306

options = {

307

'binary': 'stylus',

308

'compress': True

309

}

310

311

class CleverCSS:

312

"""CleverCSS compilation."""

313

314

class PyScss:

315

"""pyScss compilation using Python library."""

316

options = {

317

'style': 'compressed',

318

'imports': []

319

}

320

321

class Compass:

322

"""Compass compilation framework."""

323

options = {

324

'binary': 'compass',

325

'style': 'compressed',

326

'images_dir': 'images'

327

}

328

329

class PostCSS:

330

"""PostCSS processing with plugins."""

331

options = {

332

'binary': 'postcss',

333

'plugins': []

334

}

335

```

336

337

### JavaScript Preprocessors and Templating

338

339

Compilation and templating filters for JavaScript and related languages.

340

341

```python { .api }

342

# JavaScript preprocessors

343

class CoffeeScript:

344

"""CoffeeScript compilation."""

345

options = {

346

'binary': 'coffee',

347

'bare': False

348

}

349

350

class TypeScript:

351

"""TypeScript compilation."""

352

options = {

353

'binary': 'tsc',

354

'target': 'es5',

355

'module': 'commonjs'

356

}

357

358

class Babel:

359

"""Babel transpilation for modern JavaScript."""

360

options = {

361

'binary': 'babel',

362

'presets': ['env']

363

}

364

365

# Template engines

366

class Handlebars:

367

"""Handlebars template compilation."""

368

options = {

369

'binary': 'handlebars',

370

'namespace': 'templates'

371

}

372

373

class Jinja2:

374

"""Jinja2 template processing."""

375

376

class JST:

377

"""JavaScript templates (Underscore.js style)."""

378

options = {

379

'namespace': 'JST',

380

'bare': False

381

}

382

383

class DustJS:

384

"""Dust.js template compilation."""

385

options = {

386

'binary': 'dustc',

387

'name': None

388

}

389

390

class Jade:

391

"""Jade template compilation."""

392

options = {

393

'binary': 'jade',

394

'pretty': False

395

}

396

```

397

398

### Specialized Filters

399

400

Advanced filters for specific optimization and processing tasks.

401

402

```python { .api }

403

# Specialized filters

404

class RequireJS:

405

"""RequireJS optimizer (r.js)."""

406

options = {

407

'binary': 'r.js',

408

'baseUrl': None,

409

'optimize': 'uglify2'

410

}

411

412

class Spritemapper:

413

"""CSS sprite generation."""

414

options = {

415

'binary': 'spritemapper',

416

'output_css': None,

417

'output_image': None

418

}

419

420

class ClosureTemplateFilter:

421

"""Closure Templates compilation."""

422

options = {

423

'binary': 'SoyToJsSrcCompiler.jar',

424

'jar': None

425

}

426

427

class ClosureStylesheetsCompiler:

428

"""Closure Stylesheets compiler."""

429

options = {

430

'binary': 'closure-stylesheets.jar',

431

'jar': None

432

}

433

434

class ClosureStylesheetsMinifier:

435

"""Closure Stylesheets minifier."""

436

options = {

437

'binary': 'closure-stylesheets.jar',

438

'jar': None

439

}

440

```

441

442

## Advanced Filter Usage

443

444

### Custom Filter Creation

445

446

```python

447

from webassets.filter import Filter

448

449

class CustomSassFilter(Filter):

450

name = 'custom_sass'

451

options = {

452

'style': 'compressed',

453

'include_paths': []

454

}

455

456

def input(self, _in, out, **kw):

457

import sass

458

459

# Get configuration

460

style = self.get_config('style', require=False) or 'compressed'

461

include_paths = self.get_config('include_paths', require=False) or []

462

463

# Process input

464

source = _in.read()

465

result = sass.compile(

466

string=source,

467

output_style=style,

468

include_paths=include_paths

469

)

470

471

out.write(result)

472

473

# Register and use

474

from webassets.filter import register_filter

475

register_filter(CustomSassFilter)

476

477

# Use in bundle

478

Bundle('style.scss', filters='custom_sass', output='style.css')

479

```

480

481

### Filter Chaining

482

483

```python

484

# Chain multiple filters

485

Bundle(

486

'app.js',

487

'utils.js',

488

filters=['babel', 'uglifyjs'], # Babel first, then UglifyJS

489

output='gen/app.js'

490

)

491

492

# CSS preprocessing and optimization

493

Bundle(

494

'style.scss',

495

filters=['sass', 'autoprefixer', 'cssmin'],

496

output='gen/style.css'

497

)

498

499

# Complex filter chain

500

Bundle(

501

'template.handlebars',

502

'app.coffee',

503

filters=['handlebars', 'coffeescript', 'uglifyjs'],

504

output='gen/compiled.js'

505

)

506

```

507

508

### Filter Configuration

509

510

```python

511

from webassets import Environment, Bundle

512

513

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

514

515

# Global filter configuration

516

env.config['uglifyjs_binary'] = '/usr/local/bin/uglifyjs'

517

env.config['sass_style'] = 'compressed'

518

env.config['autoprefixer_browsers'] = ['last 2 versions', 'ie >= 9']

519

520

# Bundle-specific filter options

521

Bundle(

522

'app.js',

523

filters={'uglifyjs': {'compress': False, 'mangle': True}},

524

output='gen/app.js'

525

)

526

527

# Environment-specific settings

528

if env.debug:

529

js_filters = None # No minification in debug

530

else:

531

js_filters = ['babel', 'uglifyjs']

532

533

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

534

```

535

536

### Conditional Filter Application

537

538

```python

539

def get_js_filters(debug=False):

540

if debug:

541

return ['babel'] # Only transpile, don't minify

542

else:

543

return ['babel', 'uglifyjs'] # Transpile and minify

544

545

def get_css_filters(debug=False):

546

base_filters = ['sass', 'autoprefixer']

547

if not debug:

548

base_filters.append('cssmin')

549

return base_filters

550

551

# Create bundles with conditional filters

552

js_bundle = Bundle(

553

'app.js',

554

filters=get_js_filters(env.debug),

555

output='gen/app.js'

556

)

557

558

css_bundle = Bundle(

559

'style.scss',

560

filters=get_css_filters(env.debug),

561

output='gen/style.css'

562

)

563

```