=== BitBlade Gallery ===
Contributors: mauricesobiera
Tags: gallery, photography, lightbox, avif, webp
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.6.5
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Gallery block that decides which image version each visitor receives, converts to AVIF and WebP, and zooms to the full original.

== Description ==

Most gallery plugins arrange pictures. Most image plugins convert them. Neither side decides **which version of a picture a given visitor actually downloads** — and that decision is where photo sites lose either sharpness or bandwidth.

BitBlade Gallery is a gallery block that owns that decision.

= The problem it solves =

A responsive image is only as good as the `sizes` attribute describing it. That attribute is written on the server, before anyone knows how wide the image will really be rendered. So it is an estimate, and when the estimate is wrong the browser dutifully fetches the wrong file.

* **Estimate too small** and the browser picks a candidate below the display width. The photo looks soft. No setting in the media library repairs this, because the file on disk is fine — only the announcement about it was wrong.
* **Estimate too large, or the candidate list has a gap**, and a phone reaches upward. Measured on a production photo site: a grid slot 390 pixels wide, a candidate list that jumped from 1024 pixels straight to the 8640-pixel original, and a phone at triple pixel density downloading **3.9 MB for one thumbnail**.

An image optimizer cannot fix this — it never learns the rendered width. A gallery plugin usually does not try.

= What this plugin does differently =

**It measures instead of estimating.** Once the layout is known, the browser-side script writes the real pixel width of every slot back into `sizes`, on the `img` element and on each `source`. The server-side value is only a starting guess until that happens.

**It caps the candidate list.** The unscaled original is never offered in the grid — it belongs to the lightbox, where the visitor has asked to see detail. Where a site generates no intermediate size above 1024 pixels, the plugin can create the missing one so there is no gap to fall through.

**It verifies what it converts.** An encoder that runs out of memory on a large source can leave a valid-looking file behind. Checking that a file exists is not enough, so this plugin checks size and format signature, deletes what fails, and never advertises an unusable variant. The bug that prompted this was a 145-byte AVIF being served to browsers as a real image.

**It never crops.** Portrait and landscape sit side by side in rows of equal height. Optionally a portrait spans two rows with two stacked landscape images beside it. In neither arrangement is an image trimmed to make a row line up.

= The rest =

* Lightbox zooming into the unscaled original, panning with mouse, wheel or touch
* AVIF and WebP generated in the background after upload, so a large upload is never held up by encoding
* Encoders: `avifenc` and `cwebp` where available, otherwise Imagick, otherwise GD — the settings page shows which route is in use
* Sorting by upload order, capture date, or by hand, set globally and per gallery
* Exactly one image per row on phones
* Nothing leaves your server: no external service, no account, no tracking

= Who it is for =

Photographers and photo-led editorial sites — anyone who uploads straight from the camera and wants visitors to see that quality without paying for it in page weight. If what you need is mainly a lightbox, a slider or a portfolio grid, the directory has excellent plugins for that and this one is more machinery than the job requires.

== Installation ==

1. Install and activate the plugin.
2. Add the **BitBlade Gallery** block to a post and pick your images.
3. Optional: under **Media → BitBlade Gallery**, queue existing images so they get their AVIF and WebP versions too.

== Frequently Asked Questions ==

= Does the plugin contact any external server? =

No. Images are converted on your own server. No external service, no API key, no account, no usage tracking.

= I already use an image optimization plugin. Is this redundant? =

No, and the two work together. An optimizer produces smaller files. This plugin decides which of those files each visitor receives, because it is the part that knows how wide the image is actually rendered. If your optimizer already produces AVIF and WebP, switch conversion off here and keep the delivery logic.

= How large should I upload my images? =

As large as the camera produces them, at good JPEG quality. Visitors never receive the large file in the grid — only when they zoom into the lightbox, and there every pixel counts. An image with a 6000 pixel long edge stays sharp to nearly three times magnification; one with 2500 only to about one and a half.

= My server has no AVIF support. =

Then WebP is used, and where that is missing too, the original JPEG. The settings page shows what is available and, on a server you administer yourself, which packages supply the missing encoders.

= Conversion seems slow. =

It is deliberately spread over background runs so uploads and page views are never blocked. A large existing library takes hours. The **Process a batch now** button moves things along, and WP-CLI (`wp bitblade-gallery convert`) is considerably faster than cron.

= Is anything cropped to make the rows line up? =

No. Both arrangements show every image complete.

= Which languages are included? =

German (Germany, Austria, Switzerland, formal and informal), French (France, Belgium, Canada), Italian, Russian and Ukrainian.

== Screenshots ==

1. A gallery with portrait and landscape images in justified rows
2. The lightbox with zoom
3. Block settings in the editor
4. The plugin settings page

== Changelog ==

= 1.6.5 =
* Drop the plugin URI: it pointed at the same page as the author URI, which the directory does not accept. The author URI is the one that applies here.

= 1.6.4 =
* Ship German in all five regional variants and French in three. WordPress looks for the exact locale name and does not fall back to a related one: on a site running `de_DE_formal`, a `de_DE` file is never loaded and the interface stays English.
* German for Germany and Austria now uses ß; the Swiss variants keep the ss spelling.
* Replace a hand-written format check with `wp_get_image_mime()`, which is both the core API for this and the more thorough test.
* Translate the one plural string that had been missed, and give each language its own plural rule — three forms for Russian and Ukrainian, two for the rest.

= 1.6.0 =
* Cap the candidate list in the grid so the unscaled original is never offered there. Without the cap, phones with a high pixel density downloaded the full-size file for a hand-sized slot.
* Verify every converted file (size and format signature) instead of trusting that it exists. Imagick and GD reported success on very large sources while writing a truncated file.
* Ignore unusable variant files when building the markup, so files written before this check are no longer served.
* Skip encoding of sources above 40 megapixels, where the encoder failed reliably and cost minutes per attempt.
* Add the missing intermediate image size on sites that generate none above 1024 pixels, including a background job for existing images and a disk space guard.
* New maintenance action to find and delete truncated variant files, time limited and resumable.

= 1.5.0 =
* Choice between justified rows and a mosaic arrangement, with a configurable maximum number of images per row.
* Sorting by upload order, capture date, or manual arrangement, settable globally and per gallery.
* Exactly one image per row on phones.

== Upgrade Notice ==

= 1.6.5 =
Adds the regional language variants WordPress actually looks for. Update if the interface stayed English on a non-English site.
