askama-minify 0.3.1

A procedural macro for minifying Askama templates at compile time
Documentation
# Askama Minify

[简体中文](README.zh-CN.md)

A procedural macro crate that minifies Askama templates at compile time.

Starting with `0.3.0`, `askama-minify` no longer ships a CLI. It reads a template during compilation, minifies HTML and inline CSS/JavaScript, and injects the result as Askama's `#[template(source = "...", ext = "...")]`.

Important: place `#[template_minify(...)]` above `#[derive(Template)]` so the macro can generate Askama's `#[template(...)]` attribute before the derive macro runs.

## Usage

```rust
use askama::Template;
use askama_minify::template_minify;

#[template_minify(path = "index.html")]
#[derive(Template)]
struct IndexTemplate<'a> {
    title: &'a str,
}
```

Path resolution:

- `CARGO_MANIFEST_DIR/<path>`
- `CARGO_MANIFEST_DIR/templates/<path>`

This means the common Askama layout can use the short path directly:

```rust
#[template_minify(path = "index.html")]
#[derive(Template)]
struct IndexTemplate;
```

With the corresponding file:

```text
templates/index.html
```

## Inline Templates

```rust
use askama::Template;
use askama_minify::template_minify;

#[template_minify(source = "<h1>{{ title }}</h1>", ext = "html")]
#[derive(Template)]
struct InlineTemplate<'a> {
    title: &'a str,
}
```

When `source` is used, `ext` is required.

## Forwarded Askama Arguments

`path`, `source`, and `ext` are handled by `askama-minify`. Any other arguments are forwarded to Askama's `#[template(...)]` attribute:

```rust
#[template_minify(path = "page.html", escape = "none")]
#[derive(Template)]
struct PageTemplate;
```

This expands to a minified source template:

```rust
#[template(source = "...", ext = "html", escape = "none")]
```

## Notes

- Template files are tracked through `include_str!`, so Cargo rebuilds when the source template changes.
- `html` and `htm` templates are minified as HTML. CSS and JavaScript use conservative built-in minifiers by default.
- Enable the `advanced-css` feature to use `lightningcss` for fuller CSS minification:

```toml
askama-minify = { version = "0.3", features = ["advanced-css"] }
```

- When `advanced-css` is enabled, CSS containing Askama syntax still falls back to the built-in minifier to avoid failed CSS parser work during compilation.
- Non-HTML extensions are injected unchanged as Askama `source` templates.

## Architecture

`askama-minify` is split into small modules around the procedural macro pipeline:

- `src/lib.rs`: proc-macro entry point. It parses the attribute and target item, then delegates expansion.
- `src/args.rs`: parses `path`, `source`, `ext`, and collects extra Askama arguments for forwarding.
- `src/item.rs`: parses the target derive item and rejects an existing `#[template(...)]` attribute.
- `src/loader.rs`: resolves template paths, reads template files, infers extensions, and chooses whether to minify.
- `src/expand.rs`: builds the generated `#[template(source = "...", ext = "...")]` attribute and adds `include_str!` tracking for file templates.
- `src/minifier.rs`: public internal entry for HTML minification.
- `src/minifier/html.rs`: HTML scanner that preserves Askama syntax and delegates inline `<style>` and `<script>` content.
- `src/minifier/css.rs`: CSS minification. It uses the built-in conservative minifier by default and `lightningcss` when `advanced-css` is enabled.
- `src/minifier/js.rs`: conservative JavaScript whitespace/comment minification that preserves string contents and relevant line terminators.
- `src/minifier/template.rs`: shared Askama block copier for `{{ ... }}`, `{% ... %}`, and `{# ... #}`.
- `src/minifier/util.rs`: shared string trimming helpers.

The expansion flow is:

```text
template_minify attribute
  -> parse MacroArgs
  -> parse TemplateItem
  -> load or read source template
  -> minify HTML templates
  -> inject Askama #[template(source = "...", ext = "...")]
  -> emit include_str! tracking for path-based templates
```