Kntnt Photo Drop
Gutenberg blocks: a front-end bulk photo uploader and a server-rendered gallery with a lightbox.
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/kntnt/kntnt-photo-drop/releases/download/v0.13.3/kntnt-photo-drop.zipReadme
kntnt-photo-drop
A WordPress plugin with two Gutenberg blocks: a front-end Photo Drop Zone that optimises images in the browser and uploads them in bulk, and a public Photo Drop Gallery that renders those images with a lightbox. It lets a field photographer drag in hundreds of images at once, and lets anyone browse them later.
Description
kntnt-photo-drop solves one job end to end: getting a large set of photos onto a WordPress site quickly, in a sensible web format, and presenting them well. The Photo Drop Zone block is a capability-gated uploader you place on a page; a logged-in user with upload rights drags in single images, many images, or a whole folder, and each is downscaled, converted to WebP, and compressed in the browser before it ever leaves the machine. The Photo Drop Gallery block renders a chosen set of those images as a server-rendered grid or justified-rows layout, with an accessible lightbox.
The plugin does not use the WordPress Media Library. Images live as files on disk, in collections under the site's uploads directory, and the filesystem is the single source of truth: there are no database rows for collection images. A collection carries a fixed set of output rules, so everything inside it is conforming by construction. Because the images are plain files, they are served directly by URL, which is what makes the gallery, responsive srcset, and native lazy-loading work without a PHP proxy.
Key Features
- Two blocks. Photo Drop Zone (front-end bulk uploader) and Photo Drop Gallery (public gallery with a lightbox), both server-rendered and registered under the Kntnt block category.
- In-browser optimisation. Images are downscaled and re-encoded to WebP in the browser (via the Canvas API) before upload, so a several-hundred-image batch transfers a fraction of the original bytes.
- Collections on disk. Each collection is a directory under the uploads root; discovery is a directory scan, so a collection copied in from another site appears automatically and a deleted directory disappears, with no registry to keep in sync.
- Three renditions per image. Each image is stored as up to three renditions: a high-fidelity main image (the download/archival copy), a mid-size full image shown in the lightbox and slideshow, and a small thumbnail shown in the grid. Each tier is derived from the one above it and skipped when the source is no wider, so a small image collapses to a single file.
- An immutable upload contract, re-derivable display sizes. A collection fixes its upload width and upload quality once, at creation — the only irreversible pair, because the original bytes are discarded once the main image is encoded. The stored format is always WebP. The full and thumbnail width/quality are not frozen: they are losslessly re-derivable from the main image, so they stay editable on the admin page and regenerate the affected renditions when changed.
- Folder-aware uploads with a placement template. Dropping a folder and choosing one through the Select a folder control behave identically: the folder is walked recursively and its sub-directory structure is preserved on the server. A mutable path-components template (default
%year%/%month%/%day%/%uploader%) then prefixes every Drop Zone upload, expanded server-side in the site timezone, so uploads are organised by date and contributor without collisions. - Two gallery layouts with an overlay system. A uniform grid (core Grid layout) or bespoke justified rows, an Interactivity-API lightbox that degrades to a plain link without JavaScript, and four configurable image overlays — breadcrumbs, download, add-to-media, and trash — each with its own visibility, nine-point position, and shared appearance.
- Fullscreen slideshow. An optional, endlessly looping fullscreen playback of the gallery with a configurable per-image time and a dissolve transition, started from a built-in button or any custom element on the page, and ended with Escape or a close button. Images uploaded while the slideshow plays join the rotation on the next loop — ideal for a photo frame rolling during an ongoing event.
- A complete WP-CLI surface. Create, update, delete, and
doctorcollections, and import or delete images, from the command line. - First-party by design. No third-party request is made when a visitor views a page. The only external call is the admin-side update check against GitHub.
The problem
Bulk-uploading photos to WordPress is awkward. The Media Library accepts originals at full size, so a folder of camera images consumes large amounts of disk and bandwidth unless each file is resized by hand first. There is no built-in way to enforce a consistent maximum size and format across a set of images, and no simple way to drop in a whole folder and have the structure preserved. Presenting the result as a tidy, responsive gallery then means reaching for a heavier gallery plugin.
How this plugin helps
A collection fixes its own upload rules – an upload width and an upload quality for the main image – and every image that enters it, whether through the Drop Zone or through image import, is made to conform at the point of entry, then has its full image and thumbnail derived from it. The browser does the heavy resizing and WebP encoding before upload, so the transfer is small; the server re-applies the same rules on arrival, so a file cannot enter non-conforming even if it bypasses the browser. Because the images are ordinary files served by URL, the Gallery block can render them with responsive srcset and lazy-loading straight from disk, and you compose pages out of the two blocks like any other Gutenberg content.
Limitations
- Collections are public-by-path. Images are served directly as files, so anyone who knows a file's URL can fetch it, including an image not yet shown in any gallery. Directory listing is disabled so paths cannot be enumerated, but this is a public-gallery model, not access-controlled storage. True access control would require a PHP proxy and is out of scope.
- The upload contract is irreversible. Upload width and upload quality are fixed when a collection is created and cannot be changed afterwards. Raising the upload width later cannot enlarge images that were already downscaled, because the original is not kept. (The full and thumbnail sizes are re-derivable and can be changed afterwards.)
- No EXIF or IPTC metadata survives. Re-encoding through the Canvas API strips all embedded metadata, so there is no capture date or embedded caption to draw on; the gallery's breadcrumbs overlay is derived from the folder path only.
- The gallery does not navigate folders. A Gallery block renders all images under a start path as one flattened set. To present folders separately, place several blocks and compose them with the page builder.
Requirements
- WordPress 7.0 or later. The blocks use current block-editor APIs (the
react-jsx-runtimescript handle and stabilised block-support keys); no support for older WordPress is carried. - PHP 8.4 or later. (The plugin checks the PHP version on load and deactivates itself with an admin notice on an older runtime.)
- A server image library – GD or Imagick with WebP support – for the server-side re-encoding that backs uploads and
image import.
The plugin is not on the WordPress.org directory; it is distributed through GitHub Releases and updates itself from there.
Installation
- Download the latest release ZIP:
kntnt-photo-drop.zip. - In WordPress, go to Plugins → Add New → Upload Plugin, choose the ZIP, and install it.
- Activate Kntnt Photo Drop.
On activation the plugin creates its uploads root (wp-content/uploads/kntnt-photo-drop/ by default) and seeds it so the directory cannot be listed. No further setup is required before you create your first collection.
Once installed, the plugin keeps itself up to date. It checks https://api.github.com/repos/Kntnt/kntnt-photo-drop/releases/latest during WordPress's normal update cycle and offers any newer release in the admin UI, just like a plugin from the directory. This check runs admin-side only; it is the single external request the plugin makes.
Usage
The plugin has three surfaces: an admin page where collections are created and managed, the Photo Drop Zone block for uploading, and the Photo Drop Gallery block for displaying.
Create a collection
Collections are created and managed on a dedicated admin page at Media → Photo Drop (gated by manage_options). Blocks never create or reconfigure a collection; they only select one.
To create a collection, open the page and choose Create collection. You provide:
- a display name (optional; defaults to a humanised slug);
- a slug (optional; lowercase, URL-safe, and unique) – the placeholder shows the unique default derived from the display name, and a blank field uses it; a typed collision is an error. It becomes the directory name and the durable identity a block stores to point at the collection;
- path components (optional; defaults to
%year%/%month%/%day%/%uploader%) – the template that prefixes every Drop Zone upload, expanded server-side at upload time (%year%/%month%/%day%from the upload date in the site timezone,%uploader%from the uploader's nicename); - then the six rendition fields: upload width (blank = the source's own dimensions) ⚠️, upload quality (default 95) ⚠️, full width (default 1920), full quality (default 85), thumbnail width (default 640), and thumbnail quality (default 75), each pre-filled from its
kntnt_photo_drop_default_*filter (see Extending).
There is no format field – the format is always WebP. The slug and the upload width/quality fields carry a ⚠️ marker: they are set once and cannot be changed after the collection is created. The full and thumbnail fields carry a mild note that changing them later regenerates existing images.
[!WARNING] Upload width and upload quality fix the collection's immutable output contract, and that pair cannot be changed afterwards. Every image is downscaled and re-encoded to WebP as it enters the collection, and the original is never kept, so raising the upload width later cannot recover detail that was already discarded. Choose these two values deliberately. The display name, the path-components template, and the re-derivable full/thumbnail sizes all remain editable after creation; the slug and the upload contract do not.
The list view shows every discovered collection – name, slug, upload width (or Original), full and thumbnail widths, format (WebP), and image count – with always-visible Edit and Delete buttons on each row. Edit changes the display name, the path-components template, and the re-derivable full/thumbnail settings; the slug and upload contract are shown read-only. Deleting a collection removes its directory and everything under it; blocks that referenced its slug then render nothing for visitors and an editor-only notice for logged-in users.
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v0.13.3 | Jun 21, 2026 | kntnt-photo-drop.zip | 1 |
| v0.13.2 | Jun 21, 2026 | kntnt-photo-drop.zip | 1 |
| v0.13.1 | Jun 20, 2026 | kntnt-photo-drop.zip | 1 |
| v0.13.0 | Jun 20, 2026 | kntnt-photo-drop.zip | 2 |
| v0.12.0 | Jun 20, 2026 | kntnt-photo-drop.zip | 1 |
| v0.11.0 | Jun 19, 2026 | kntnt-photo-drop.zip | 2 |
| v0.10.1 | Jun 12, 2026 | kntnt-photo-drop.zip | 1 |
| v0.10.0 | Jun 12, 2026 | kntnt-photo-drop.zip | 1 |
| v0.9.0 | Jun 12, 2026 | kntnt-photo-drop.zip | 0 |
| v0.8.0 | Jun 12, 2026 | kntnt-photo-drop.zip | 4 |
| v0.7.1 | Jun 11, 2026 | kntnt-photo-drop.zip | 1 |
| v0.7.0 | Jun 11, 2026 | kntnt-photo-drop.zip | 1 |
| v0.6.0 | Jun 11, 2026 | kntnt-photo-drop.zip | 0 |
| v0.5.0 | Jun 11, 2026 | kntnt-photo-drop.zip | 1 |
| v0.4.0 | Jun 10, 2026 | kntnt-photo-drop.zip | 1 |
| v0.3.0 | Jun 10, 2026 | kntnt-photo-drop.zip | 1 |
| v0.2.0 | Jun 10, 2026 | kntnt-photo-drop.zip | 0 |
| v0.1.0 | Jun 8, 2026 | kntnt-photo-drop.zip | 1 |