Skip to content

Releases: plan2net/webp

14.7.0

16 Jun 07:34

Choose a tag to compare

Two editorial/optimization features on top of the per-image quality override from 14.6.0.

Per-image compression report

The file metadata form now shows, right below the compression quality field, what each enabled format achieved for that image: per processed variant (each rendered size), the generated WebP / AVIF / JPEG XL sibling's size and the saving versus the source it replaces. Read-only; it fills in as the image is rendered at more sizes.

Compress larger variants harder

Optional per-format width-to-quality curves (quality_by_width, quality_by_width_avif, quality_by_width_jxl) map a rendered variant's width to a quality, so larger variants are compressed harder automatically — the responsive-image best practice (a large hero that produced no smaller WebP at the global quality now does). Off by default; a per-image quality override still wins, and lossless parameters are left untouched. The README has a copy-paste recommended starting curve.

Full changelog: 14.6.0...14.7.0

14.6.0

15 Jun 12:51

Choose a tag to compare

Per-image compression quality override

Editors can set a Compression quality (1–100) on an individual image's metadata in the Filelist. It overrides the global converter quality for that file across every enabled output format (WebP / AVIF / JPEG XL); leave it at 0 to use the global setting.

Quality is read from the file's current metadata at conversion time, so changing it regenerates the sibling on the next image processing, and it applies everywhere the image is used. Folder-mode sweeps continue to use the global quality.

Full changelog: 14.5.4...14.6.0

14.5.4

15 Jun 05:14

Choose a tag to compare

Fixed

  • webp:diagnose no longer fails on PostgreSQL when probing for sibling files; the sibling suffix is now inlined as a literal instead of an untyped bound parameter inside CONCAT().

14.5.3

10 Jun 06:40

Choose a tag to compare

Changed

  • Configuration memoizes parsed settings (enabled formats, mime-type lists, exclude directories) instead of re-parsing them on every processed image. The cache is keyed by the raw setting value, so runtime configuration changes are still picked up.
  • FileNameFilter now also caches an absent filter pattern instead of re-resolving the configuration for every backend file-list row.
  • webp:process-queue --folder converts images while scanning instead of loading the complete file list into memory first.

Fixed

  • The folder sweep now matches uppercase and mixed-case file extensions (IMAGE.JPG), consistent with the FAL-driven conversion path.

14.5.2

08 Jun 08:36

Choose a tag to compare

Documentation

  • Added a Caddy webserver recipe for Accept-header content negotiation, alongside the existing nginx and Apache examples. All three configs are now exercised by the E2E suite.
  • Rewrote the core-vs-extension comparison: TYPO3 core handles WebP (13.0+) and AVIF (13.4+, ImageMagick); this extension's distinct value is unchanged URLs, transparent per-request fallback, and JPEG XL.

Changed

  • FileNameFilter caches the resolved filter pattern instead of recompiling it on every backend file-list row.

14.5.1

26 May 14:15

Choose a tag to compare

Changed

  • parameters_avif and parameters_jxl now ship ImageMagick-compatible defaults; converter_avif and converter_jxl default to MagickConverter. Enabling AVIF or JPEG XL via formats_enabled works out of the box on the typical TYPO3 host — no manual parameter string required. Override either to switch to libvips or an external binary.

Fixed

  • webp:diagnose parameter-parsing check now distinguishes empty, malformed-global, and missing-per-mime cases and emits the concrete recommended value for the configured converter, instead of pointing at the README.

Documentation

  • README adds dedicated parameters_avif and parameters_jxl sections with per-backend recipes (ImageMagick, libvips, external binaries).

14.5.0

26 May 13:39

Choose a tag to compare

Added

  • WebP, AVIF, and JPEG XL output in any combination. A new formats_enabled setting (default webp) lets you pick which sibling formats this install produces — e.g. formats_enabled = webp,avif to ship both, or webp,avif,jxl to ship all three. Each non-webp format has its own converter, parameters, and mime-types tab in the Extension Configuration form (converter_avif, parameters_avif, mime_types_avif; same for jxl). The existing converter / parameters / mime_types keys remain the source of truth for the WebP slot. The 4-converter × 3-format support matrix (VipsConverter, MagickConverter, ExternalConverter, PhpGdConverter) is in the README. Closes #94.
  • webp:diagnose --format=<webp|avif|jxl> to restrict the report to one format. The delivery probe now sends four Accept headers (avif/jxl/webp/*/*) and verifies the server returns the highest-priority format the install actually generates. Storages, converter health, async pipeline, failed-attempts cache, and per-file deep-dive all report per format.
  • webp:process-queue --folder=<path> now sweeps for every enabled output format, not just WebP.

Changed

  • Sibling lifecycle (move / rename / replace / delete) now covers all three formats. Any on-disk .avif or .jxl sibling follows its original alongside the existing .webp handling.
  • Default filter_pattern now matches .avif and .jxl siblings as well as .webp. Custom values are left untouched; admins who pinned a webp-only regex keep their value.

Fixed

  • A previously-good sibling is no longer deleted when a fresh conversion attempt turns out larger than the original. The failed-attempts cache already prevents the next render from retrying with the same parameters; we keep the file the webserver was happily serving.
  • Renaming a source file no longer overwrites a same-named file at the destination. The orphaned source sibling is cleaned up and the next render produces a fresh destination sibling, instead of silently replacing whatever was there.
  • Enabling a format without its converter or parameters no longer generates an error on every render. The listener skips the unconfigured format with a one-line notice instead.
  • webp:diagnose degrades gracefully on installs that haven't run the TYPO3 Database Analyzer after upgrade — the affected sections detect the missing format column and point the admin at the analyzer instead of throwing.
  • webp:diagnose no longer certifies PhpGdConverter as AVIF/JPEG XL capable. PhpGd is WebP-only at runtime; the diagnose check now mirrors that.
  • webp:diagnose Accept-header probe grades against the format actually available on disk, instead of always comparing against the highest-priority enabled format — eliminates the spurious "server prefers webp over avif" warning when a file has no AVIF sibling yet.
  • PhpGdConverter clamps quality values above 100 (PHP imagewebp documents 0–100).
  • ext_emconf.php now declares php >= 8.2.0, matching the long-standing composer constraint. TER installs on PHP 8.1 no longer fetch the extension only to fatal on first request.
  • Async-mode label in the Extension Configuration backend module no longer breaks mid-sentence — TYPO3's EM UI was splitting the label on the webp: colon.
  • composer.json now suggests typo3/cms-frontend for installs that pick the PhpGd backend (PhpGd imports TYPO3\CMS\Frontend\Imaging\GifBuilder).

Upgrade notes

  • Run the TYPO3 Database Analyzer. tx_webp_queue and tx_webp_failed gain a format column; existing rows remain valid (format defaults to webp) but the schema must match. Stop the Scheduler before running the analyzer if you're worried about concurrent enqueues during the ALTER TABLE — queued work is a transient working set and TRUNCATE tx_webp_queue before the analyzer is also fine.
  • Flush all caches after deploy. The compiled DI container caches references to the renamed service classes; a stale container will fatal on the first request that touches them. vendor/bin/typo3 cache:flush or Install Tool → Maintenance → Flush cache resolves it.
  • Re-save the Extension Configuration if you customised filter_pattern to the previous webp-only default. The old default '/\.(jpe?g|png|gif)\.webp$/i' does not hide .avif / .jxl siblings. The new default covers all three; admins who pinned a webp-only regex keep their value untouched.

14.4.1

21 May 09:04

Choose a tag to compare

A bugfix release: webp:diagnose no longer crashes on classic-mode (non-Composer) TYPO3 v12 installs.

Bug fixes

  • webp:diagnose no longer requires symfony/process. Classic-mode TYPO3 v12 core does not bundle that package, so the command crashed with Class "Symfony\Component\Process\Process" not found. The MagickConverter health check now uses PHP's native proc_open with the same 5-second timeout behaviour. symfony/process is dropped from composer.json require entirely. A new smoke test (Tests/Functional/Command/DiagnoseCommandTest) keeps the command exercised in every PHP × TYPO3 CI matrix cell. Closes #116.

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns.

14.4.0

19 May 08:26

Choose a tag to compare

libvips becomes a first-class WebP conversion backend, either in-process via jcupitt/vips 2.x + PHP ext-ffi (typically 2–3× faster than MagickConverter at equivalent quality, substantially less memory) or as the vips CLI binary through the existing ExternalConverter. Both routes preserve animated GIFs as animated WebP.

New features

  • libvips (native) backend. A new VipsConverter calling libvips in-process via jcupitt/vips (2.x) + PHP ext-ffi. Pick libvips (native) in the converter dropdown. Parameters are space-separated key=value pairs per mime type (e.g. image/jpeg::Q=85 smart_subsample=true effort=4|…) passed straight to libvips's webpsave — see the option reference for the full list.
  • Animated GIFs survive as animated WebP. VipsConverter loads all frames automatically (n=-1) and emits multi-frame WebP when mixed=true is set. The vips CLI binary via ExternalConverter also preserves animation when the GIF entry uses %s[n=-1] on the source argument.
  • webp:diagnose reports libvips availability. Distinguishes ext-ffi missing / disabled / preload mode, jcupitt/vips not installed, and libvips shared library unreachable via Vips\Config::version(). Warns on PHP 8.3+ if zend.max_allowed_stack_size=-1 is not set (jcupitt/vips runs FFI callbacks off the main thread).

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns. Default backend stays MagickConverter — existing installs are unaffected until you opt in.
  • To use the native backend, install libvips-tools on the host (Debian/Ubuntu pulls in libvips42 / libvips42t64 as a dependency), enable PHP's ext-ffi with ffi.enable=true in php.ini (not preload — jcupitt/vips does not support preloading), composer require jcupitt/vips, and set the converter to libvips (native) in the extension configuration. On PHP 8.3+ also set zend.max_allowed_stack_size=-1. Full recipe in the README's Using libvips natively section.

14.3.0

16 May 07:18

Choose a tag to compare

A new webp:diagnose CLI command walks the full delivery chain end-to-end and points at the first failing link.

New features

  • webp:diagnose CLI command. Run vendor/bin/typo3 webp:diagnose for a single-pass health check covering:
    • Storages — WebP mode, driver, .webp sibling counts, silent-off cases, phantom storage rows with unregistered drivers.
    • Converter — class, binary availability, parameter string.
    • Async pipeline — queue size, oldest entry age, scheduler task state.
    • Failed-conversion cache — recent rows, dominant configuration_hash warning.
    • Optional HTTP probe (--url=<url>) — Accept-header rewrite + Vary: Accept check.
    • Optional per-file deep dive (--file=<uid>) — metadata, sibling lookups, failed-attempts rows.
  • Output uses coloured markers ( ok, ! warning, failure). Exit code is 1 only on real failures, so the command works as a deployment gate.

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns.