Images
The image service produces responsive images via Pillow (optional, lazily
imported — a text-only site pays nothing). Source images live under assets/
(or public/, or content/).
Requirements
Pillow is only required when images are actually used:
bashpip install "epresso[images]"
If Pillow (or the source image) is unavailable, image() falls back to a plain
<img> pointing at the original asset.
image() — responsive <img>
jinja<img src="{{ image('photos/hero.jpg', widths=[400, 800, 1200], alt='Hero') }}">
Renders a WebP srcset with content-hashed filenames. Default widths are
[400, 800, 1200]:
html<img src="/images/hero-<digest>-1200.webp" srcset="/images/hero-<digest>-1200.webp 1200w, ..." sizes="100vw" alt="Hero">
picture() — WebP + JPEG fallback
picture() produces a <picture> with WebP sources plus a JPEG fallback — useful when you must support browsers without WebP:
jinja{{ picture('photos/hero.jpg', widths=[400, 800], alt='Hero') }}
How it works
_register(name, widths, formats)records processing jobs per source image.- At build time,
ImagePipeline.build(out_dir)resizes each source withLANCZOSto the requested widths and formats (webpandjpeg, quality 82). - Outputs are written to
dist/images/with a content-hash digest in the filename; existing outputs are skipped (incremental/dev caching). - Outputs are written under
dist/images/<base>-<digest>-<width>.<ext>.
SVG rasterization
SVG sources are rasterized to PNG first so Pillow can process them. epresso
prefers cairosvg (needs the system cairo library); otherwise falls back to
the inkscape or rsvg-convert CLI when available.
Custom class
render_cls(name, widths, alt, cls, style="") is the class-aware variant (used
by component image helpers) and renders an <img> with the given CSS class and
optional inline style.