- PHP 61.5%
- CSS 20.9%
- JavaScript 13.3%
- Twig 4.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
README was missing a Licence section, unlike the rest of the family. blueprints.yaml's homepage was still the yourname/grav-plugin- subfolder-gallery placeholder from scaffolding; now points at the real repo. |
||
| css | ||
| js | ||
| templates/subfolder-gallery | ||
| blueprints.yaml | ||
| CHANGELOG.md | ||
| LICENSE | ||
| README.md | ||
| subfolder-gallery.php | ||
| subfolder-gallery.yaml | ||
Subfolder Gallery
Automatically builds an image gallery from any subfolder of images inside a blog post's page folder. If a post has more than one such subfolder, each becomes its own gallery, positioned with a shortcode. Uploading is done entirely from Grav Admin2's own page editor - nothing to install or edit anywhere else, and the front end shows nothing but the rendered gallery, no extra buttons or links.
Built and tested against Grav 2.0.17 with Admin2 + the API plugin. No
third-party libraries, Composer packages, or custom JavaScript admin
components - it uses Grav core's own documented self@:<subfolder> file
upload destination and the API plugin's onApiBlueprintResolved event, so
uploads go through Admin2's native drag-and-drop file field. Image resizing
uses PHP's built-in GD extension (standard on cPanel).
Known limitation: the upload field doesn't preview images that were
already uploaded in a previous save - you'll see an empty dropzone each time
you open the editor, even if the folder already has images in it. This is a
limitation of how Admin2 handles self@: subfolder destinations for upload
fields specifically. To work around it, each gallery slot also gets a
read-only Browse field showing current contents (thumbnails included).
Deleting an unwanted upload isn't possible from the editor - a
text-field-based attempt at this didn't work, because Admin2 doesn't track
changes typed into a dynamically-added field for saving. Use FTP/file
manager to remove an unwanted image for now.
Install
git clone forgejo@code.hall.me.uk:david/subfolder-gallery.git user/plugins/subfolder-gallery
Or copy the subfolder-gallery folder into user/plugins/ manually.
- In Admin2: Plugins → Subfolder Gallery → enable it.
- While you're there, check Gallery folder names under "Gallery upload
slots" - this is the list of subfolder names you'll use across your site
(default:
gallery, gallery-2, gallery-3). Each name becomes its own upload field in every page's editor.
Uploading images
Open any post in Admin2's page editor:
-
Page-root images (no subfolder): use the editor's normal Media panel, exactly as you would for any other page - nothing special needed, and this one previews existing uploads normally.
-
Subfolder galleries: open the Galleries tab. Each configured slot gives you two fields:
- Gallery:
<slot>- drag images here to upload into that subfolder. - Browse:
<slot>- read-only, shows what's currently in the folder.
To remove an unwanted upload, delete it via FTP/file manager - there's no in-editor delete yet (a text-field-based attempt didn't work reliably, see the limitation above).
- Gallery:
There is nothing to configure per-post beyond that - which slots have images in them is exactly what determines which galleries exist on that page.
How galleries are found on the front end
A page's own folder is scanned for images:
- Directly in the page folder (no subfolder) → the page-root gallery,
referenced as
[gallery:_page], or picked up first by a bare[gallery]. - Inside a subfolder (e.g.
gallery/,gallery-2/) → a gallery named after that subfolder, e.g.[gallery:gallery],[gallery:gallery-2].
Folders that contain a .md file (i.e. are actual Grav subpages) are always
ignored, as are any folder names in exclude_folders (default: assets,
thumbs, thumbnails).
Positioning galleries with the shortcode
In the post's Markdown content:
Some intro text about the trip.
[gallery:gallery]
More text about the hike.
[gallery:gallery-2]
A bare [gallery] shortcode consumes galleries in folder order (alphabetical)
each time it's used. Any gallery folders not placed via a shortcode are
automatically appended to the bottom of the page (auto_append, on by
default) - so if you don't add any shortcodes at all, uploaded galleries
still show up, just at the end of the post.
Layouts
Every gallery renders in one of six layouts, all with click-to-enlarge lightbox behaviour on top:
- Grid — even, cropped thumbnails in a responsive grid (the classic look).
- Masonry — natural aspect ratio, Pinterest-style flowing columns.
- Justified — equal-height rows sized to each photo's natural aspect ratio (like Grid and Masonry's photography-portfolio cousin) - a mix of portrait and landscape photos wrap into rows without anything being cropped or looking oddly stretched next to the others.
- Portrait — fixed, taller grid cells that never crop; a photo that doesn't fill the cell is letterboxed instead of having its edges cut off. Good when a gallery is mostly portrait-orientation shots.
- Mosaic — a grid with occasional larger "feature" tiles mixed among regular ones, magazine-style. Like Grid, images are cropped to fit their cell - this one's about visual rhythm and variety, not preserving every aspect ratio.
- Carousel — a horizontal scrolling slider with prev/next buttons.
Set a site-wide default in the plugin config (default_layout), and override
it per gallery by adding the layout name as a third part of the shortcode:
[gallery:gallery] " uses the site default layout
[gallery:gallery:masonry] " forces masonry for this gallery
[gallery:gallery-2:carousel]
[gallery:beach:justified]
[gallery:portraits:portrait]
[gallery:trip:mosaic]
[gallery::carousel] " next unplaced gallery, forced to carousel
[gallery:masonry] " also works: shorthand for [gallery::masonry]
" when no folder is actually named "masonry"
The columns setting controls the column count for grid/masonry/portrait/
mosaic and the number of visible slides in the carousel. Justified doesn't
use a fixed column count - row height adapts responsively instead (220px on
desktop, narrower on smaller screens).
Automatic image resizing
After you save a page in Admin2, the plugin checks every image in that
page's galleries and shrinks any that are wider or taller than the
configured max_width / max_height (default 2000 × 2000px), re-saving at
jpeg_quality (default 82) for JPEG/WebP or png_compression (default 6)
for PNG. Images already within bounds are left untouched, so they aren't
repeatedly re-compressed on every save. Requires PHP's GD extension
(standard on cPanel); if it's unavailable, resizing is silently skipped.
Visitor downloads
When allow_downloads is on (default), each thumbnail shows a small download
button, and the lightbox has one too. These use the HTML download
attribute, so images open a "Save As" dialog rather than navigating to the
raw image.
Configuration
Set in Admin2: Plugins → Subfolder Gallery, or in
user/config/plugins/subfolder-gallery.yaml:
| Option | Default | Description |
|---|---|---|
enabled |
true |
Enable/disable the plugin |
columns |
3 |
Columns (grid/masonry) or visible slides (carousel) |
default_layout |
grid |
grid, masonry, or carousel — overridable per shortcode |
lightbox |
true |
Click-to-enlarge lightbox with prev/next/keyboard |
allow_downloads |
true |
Show a download button on thumbnails and the lightbox |
auto_append |
true |
Append galleries not placed via shortcode |
gallery_slots |
gallery, gallery-2, gallery-3 |
Subfolder names that get an upload field in the editor |
image_extensions |
jpg, jpeg, png, gif, webp |
Which files count as images |
exclude_folders |
assets, thumbs, thumbnails |
Folder names to never treat as galleries |
max_width |
2000 |
Max width (px) before an image is resized |
max_height |
2000 |
Max height (px) before an image is resized |
jpeg_quality |
82 |
JPEG/WebP save quality (1-100) |
png_compression |
6 |
PNG compression level (0-9, lossless either way) |
Notes / limitations
- Gallery slot names are a small, site-wide configured list rather than
freely typed per post - this is what lets uploads use Admin2's native file
field with no custom code. If you need a one-off gallery name outside your
configured slots, you can still create the subfolder and drop images in
via FTP/file manager; the front end will pick it up as a gallery
automatically (it just won't have its own upload field in the editor
unless you add that name to
gallery_slots). - The upload field not previewing already-uploaded files (see the top of this file) is the main rough edge - everything else (upload, resize, front-end display, downloads, layouts) works normally.
- Images are served as static files directly from the page folder (the same mechanism Grav already uses for images referenced in Markdown), so no extra webserver configuration is needed on cPanel.
- Thumbnails in the gallery grid are the same files as the full-size
lightbox image, sized down with CSS (
object-fit: cover) rather than a separate server-generated thumbnail - since uploads are already capped at a sane max size, this keeps things simple without a second image variant to manage.
Licence
MIT.