Unblocks production use on sites previously running Smush.
migrate-from-smush:
- Reads wp-smpro-smush-data postmeta, writes _h4b_img_optim marker
- --dry-run / --force-rescan / --remove-smush-meta / --limit flags
- Verified: 100 attachments migrated cleanly on dev.rds.ink,
bulk count drops from 734 → 634
Picture_Tag rewriter:
- Hooks the_content + post_thumbnail_html + widget_text + Elementor
frontend + wp_get_attachment_image at priority 99
- Wraps <img> in <picture><source avif><source webp><img></picture>
when sibling files exist
- Double-wrap protection via byte-range tracking of existing <picture> blocks
- Per-image opt-out via data-no-h4b attribute
- Cached sibling lookups per request
- 8 edge-case tests pass
LOC: 2480 (was 1997). Adds class-cli-migrate.php (193 LOC) and
class-picture-tag.php (284 LOC).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4.5 KiB
4.5 KiB
CHANGELOG
All notable changes to h4b-image-optim will be documented here.
Format follows Keep a Changelog and Semantic Versioning.
[0.2.0] — 2026-05-19
Added migrate-from-smush + Picture-tag rewriter. The plugin is now usable end-to-end on a site that previously ran Smush — no double-processing, and WebP / AVIF actually get served to visitors.
Added
wp h4b-img migrate-from-smush— reads Smush'swp-smpro-smush-datapostmeta, writes equivalent_h4b_img_optimmarkers so our bulk command skips already-optimised attachments.--dry-runto see counts only--force-rescanto mark for re-optimisation instead (use when migrating off Smush completely)--remove-smush-metato delete the Smush postmeta after migration
Picture_Tagrewriter (the_content + post_thumbnail_html + widget_text + Elementor frontend + wp_get_attachment_image filters at priority 99). Wraps<img>tags with<picture><source type="image/avif"><source type="image/webp"><img></picture>when sibling files exist on disk.- Skips images already inside a
<picture>block (double-wrap protection via byte-range tracking) - Skips images with
data-no-h4battribute (per-image opt-out) - Resolves siblings either alongside the JPG (
foo.jpg.webp) or in Smush'swp-content/smush-webp/mirror tree - Caches sibling lookups per request to keep it cheap
- Preserves srcset, sizes, alt, class, and all other original
<img>attrs
- Skips images already inside a
Verified
- migrate-from-smush: 100 attachments migrated cleanly on dev.rds.ink
- bulk count correctly drops after migration (734 → 634)
- Picture_Tag: 8 edge-case tests pass (no siblings, multiple images, opt-out,
srcset preservation, external URLs, no
<img>, existing<picture>, mixed)
[0.1.0] — 2026-05-19
Initial MVP. Replaces Smush Pro's optimisation pipeline without the grey-wash bug. CLI-only in this release (admin UI comes in 0.2).
Added
- Plugin scaffold with PSR-12-style namespaced classes (
H4B\ImageOptim\*) Optimizer— in-place JPG / PNG re-encode using Imagick + jpegoptim / pngquant- ICC profile preservation (the Smush-bug fix) via bundled sRGB v4 profile fallback
- 4:4:4 chroma subsampling for large images; 4:2:0 for small ones
- Configurable size threshold (
min_optimise_bytes, default 20 KB) to skip thumbnails that re-encoding would inflate - Atomic file replacement with ownership preservation
- GPS EXIF stripping on by default for privacy
- EXIF orientation applied before encode
Format_Generator— WebP (synchronous) + AVIF (queued via WP-Cron) siblingsUploader_Hook— interceptswp_generate_attachment_metadataAttachment_Meta— per-attachment optimisation history in_h4b_img_optimRescue_Detector— PHP port of the Python grey-wash detector- Originals backup to
wp-content/h4b-img-originals/with 90-day cron prune - WP-CLI commands:
wp h4b-img status— tool detection + settings dumpwp h4b-img optimise --id=<n>— single-attachment optimise (+--dry-run)wp h4b-img bulk— bulk-optimise unprocessed attachments (+--limit,--force,--dry-run,--batch,--pause)wp h4b-img rescue— scan + optionally repair Smush-mangled JPGs from their.webpsiblings (+--scan,--apply,--min-severity,--csv,--manifest)
uninstall.php— clean removal of plugin options + cron, preserves user data (backups + .webp/.avif siblings + optimisation postmeta)
Required system tools (AlmaLinux 9 / Debian 13)
| Tool | AlmaLinux | Debian |
|---|---|---|
cwebp |
libwebp-tools |
webp |
jpegoptim |
jpegoptim |
jpegoptim |
cjpeg / jpegtran |
libjpeg-turbo-utils |
libjpeg-turbo-progs |
avifenc |
libavif-tools |
libavif-bin |
pngquant |
pngquant |
pngquant |
optipng |
optipng |
optipng |
Known limitations
- No admin settings page (CLI/
wp optiononly) - No Picture-tag rewriting on
the_content(Smush still serving WebPs) - No
.htaccesscontent-negotiation fallback - No
migrate-from-smushcommand yet - No PHPUnit test suite yet
Verified against
- AlmaLinux 9.7 / PHP 8.4.21 / Imagick 3.8.1 (production)
- Debian 13 / PHP 8.4 / wordpress:php8.4-apache (dev container)
- Tested on 20 rds.ink attachments in bulk mode: 487 KB saved (10.4%), 0 errors
- Rescue mechanic verified end-to-end on the WorkingAsOne_horse900-800x524.jpg fixture