Guggenheim - An algorithm for a perfectly balanced Gallery for Kirby


An algorithm for a perfectly balanced Gallery for Kirby CMS

Let’s kick things off with a demo :heart_eyes:

See it live:


Screenshot of Guggenheim


Guggenheim is a plugin for Kirby CMS which generates beautiful galleries through an algorithm for a perfectly balanced layout, which you might know from the awesome image grids at

Read more into the math and science behind the algorithm here: The algorithm for a perfectly balanced photo gallery

In my search for the perfect gallery, which could do this linear partition against the images,
I really wasen’t getting excited about all the countless client-side javascript solutions to the problem.
As I care deeply about mobile, i simply didn’t wanted to make the devices responsible for this task and wanted a PHP solution for the linear partition.

Single Domain License

Buy a Single Domain License here - I am currently struggling pretty bad :disappointed_relieved:

Pre-launch Option

  • I’ll send you the plugin as a regular ol’ .zip file to the email provided at purchase.
  • If you for some reason don’t like it, send me an email me for an refund.
  • I’m working on an easier way to ship updates through Git - I’ll send you an email when it’s ready.


Grab yourself a copy of Kirby - a awesome NoDB file-based CMS

  • Copy the guggenheim folder into site/plugins

As Guggenheim now ships with PhotoSwipe, there’s two ways to get up and running with Guggenheim and PhotoSwipe.

If you’re using the Kirby Cachebuster Plugin or your sever policy doesn’t allow loading assets from the plugin folder, you might want to fallback using the next and more preferred setup method and link up the sources in your own main assets/ folder.

The easy ‘out of the box’ way:
If you’re in a hurry, prototyping or just quickly want to test out Guggenheim with PhotoSwipe, the easiest way is to just put this in your head

<?= css('plugins/guggenheim/assets/css/guggenheim-❤-photoswipe.min.css') ?>

and this in your footer

<?= photoswipe() ?>
<?= js('plugins/guggenheim/assets/js/guggenheim-❤-photoswipe.min.js', true) ?>

off you go, you’re now all setup to use Guggenheim with PhotoSwipe.

The best way:
To preserve your total hackable and artistic freedom, the preferred and best way is still that you manually implement the stuff from guggenheim/src into your specific design or fronted framework in your assets/ folder. And maybe only outputs the PhotoSwipe DOM in your footer, like so

<?= photoswipe() ?>

Dependency order


  • PhotoSwipe DOM found in guggenheim/snippets/photoswipe-dom.php and documented here
  • photoswipe.css
  • default-skin.css (and its image dependencies)
  • photoswipe.min.js
  • photoswipe-ui-default.min.js


  • guggenheim.css
  • guggenheim-❤-photoswipe.min.js (you can leave PhotoSwipe and this binding out entirely, if you just want to use Guggenheim on its own)


in your site/config/config.php

// Add aditional classes to the guggenheim gallery element
c::set('guggenheim.classes', 'gallery zoom margin-center');

// Guggenheim is meant to be used with PhotoSwipe
// But if you for some reason don't want to use it, you can remove it additionals with
c::set('guggenheim.photoswipe', false);

// Guggenheim uses some basic srcset and sizes for basic responsiveness and highres support
// if you want to disable it, and make your own
c::set('guggenheim.srcset', false);

// Guggenheim adds a kirbytext tag, the default is 'gallery', but you can change it with
c::set('guggenheim.kirbytext.tagname', 'guggenheim');


With kirbytext

Super simplistic -Generate a Guggenheim gallery with all the page images

(gallery:) or (gallery: all)

More generally, you want to pick out the pictures to make the gallery from, you do it like this

Comma separated:
(gallery: image-1.jpg, image-2.jpg, image-3.jpg)

Pipe separated:
(gallery: image-1.jpg | image-2.jpg | image-3.jpg)

..heck even both:
(gallery: image-1.jpg | image-2.jpg, image-3.jpg)


Guggenheim lets you set some options for each gallery.

  • width (Default is 800px) Which is the width of the gallery, all image will be resized through a linear partition to fit this width, and it will also be the max-width of the gallery (to prevent upscaling).
  • height (Default is floor(width/3.5)) This is a ideal hight for images to fit too, it’ll only be used as a guideline for the linear partition to maximum fit into, it’s there for you to play around with for each specifik gallery
  • border (Default is 4px) Sets the space between images in pixels
  • max-width (Default is width) With this you can overwrite the max-width of the gallary a regular number is in pixels, but you can also do max-width: 100% - but do note that the images will still be resized according to the width option, so here you have the power to really screw things up for bigger screensizes if you aren’t aware and doesn’t overwrites the default srcset and sizes guggenheim ships with
  • class With this you can add additional classes on a per gallery level
(gallery: image-1.jpg, image-2.jpg, image-3.jpg width: 800 height: 350 border: 10 class: mycustomclass)

In your templates

Use the Guggenheim gallery in your templates

$images = $page->images()->sortBy('sort', 'asc');
echo guggenheim($images, array('width' => 800, 'height' => 350, 'border' => 10));


  • Perfectly Balanced Gallery generated by a linear partition algorithm server-side, to preventing the usual overhead that JavaScript brings in terms of browser paint, reflows, grid calculations and DOM manipulations.
  • If a ‘caption’ field is present for the image, it’ll be added as a visually hidden figcaption, visible when opened in PhotoSwipe.


Guggenheim 1.0.4

  • [x] Fixes an important issue when PHP locale was set to a locale which uses comma as a decimal separator - floats that was outputted in the inline styles got screwed, as decimal separators in CSS has to be periods.
  • [x] Ships with PhotoSwipe 4.0.1 and especially the PhotoSwipe DOM which you now easily can either manually copy from the guggenheim/snippets/photoswipe-dom.php or simply include it in your footer with <?= photoswipe() ?>

Guggenheim 1.0.3

  • [x] Only output figcaptions if a ‘caption’ field is present and filled for the image
  • [x] Add a option for setting the max-width of the gallery like (gallery: all width: 1200 max-width: 100%)
  • [x] Add the option for adding per gallery classes like (gallery: all class: customclass anotherclass)

I just might love you right now :smiley:

1 Like

Thank you so much @distantnative! :heart_eyes: :blush:

I need to test it tomorrow but I have tried to get such a gallery working for the last half year. And I was never happy with all those JS solutions – that didn’t even really work.

@distantnative Exactly, I spent well over a week on it, math isn’t really my strong side, so I researched my way to the algorithm (Linear Partition) from a variety of different sources, as I simply gave up making my own from scratch :grin:


Looks fantastic! Great work!

1 Like

Thank you very much @lukasbestle! :blush:

This a very elegant gallery solution for Kirby.
Pleased to see that the grid still renders perfectly sans-JS.
Awesome work! :smile:

Thank you @aoimedia! Yeah every other solution was made in javascript, but medium does it server-side so I knew it was possible, but man it was quite the challenge - I spent half the time figuring out the border / spacing between the images while still have everything adding up correctly :grin:

1 Like

Awesome plugin! One question though: is it currently possible to add a caption to the images? Didn’t find a hint in the source code (though it was just a quick text search by “caption” and “title”). Would be great if that would be possible as well, by just using an image file field…

Thanks mate!

Edit: Another thing which came to my mind for a even easier image selection when using kirbytext would be some wildcard objects. This would be a killer: (gallery: *-before.jpg) and (gallery: *-after.jpg) :heart_eyes:

Thank you! :blush:

Visual captions won’t be a great fit for this type of gallery i think -that said, there might be some SEO accessibility benefits in having visually hidden figcaptions AND then have these show up when the image is opened in PhotoSwipe (in the bottom) I already have ensured support for figcaptions in the PhotoSwipe script for singular images, so if you’re adding the .zoom class to a regulaer images figure element, and also adds the data-size attribute to its anchor element, everything should be fine -I’ve actually overwritten the default image kirbytext tag to do exactly this and also automatically generate thumbs :smiley:

I have a quick gist for it here it’s hasn’t been tested too much as i’m also about to have it make aspect ratio fills, for reducing expensive browser -reflows and paints :thumbsup:

@jakobploens Your last additions, about the wildcards do sound like neatly great fun! :yum: I think I’ll give that a tinker!

That was exactly what I meant, captions for PhotoSwipe in the gallery – sorry for the unclear description :wink:

Regarding wildcars – sounds great!

1 Like

Looks really good mate, will give it a play shortly and donate - we have to look after each other :wink:

1 Like

Thank you very much, it’s much appreciated - i hope you’ll like it! :blush: :+1:

Isn’t this using the default Photoswipe plugin?

…I use that plugin for years now, in my apps.

O my, I can be complety wrong - ofcourse :slight_smile:

Yes, you can.

It’s just plain .js - check the source :slight_smile:

And let’s not forget; you can swipe, pinch to zoom, pan, etc… to manipulate both the image and it’s navigation;

I am using this script for years in my Cordova apps and I really love it!

I just searched for a possibility through the plugin to take a caption out of the txt source files when using the kirbytag to display it in Photoswipe – that it’s possible just with the plugin was the reason for asking :wink: So my wish would be:

  • have an image with a custom form field labeled “caption” or whatever
  • display this automatically as a caption in photoswipe using the kirbytag (gallery: all) for example

Hope it’s clear now :slight_smile:

I’m not the creator of the plug-in, neither am I the creator of the Kirby-wrapper of this plug-in.

But you can simple extend the plug-in with a (caption:foo-bar) option, in order to show your captions in combination with the images.

As far as I understand, this plug-in uses the Photoswipe engine for almost 95%… so it’s not that difficult to add a caption to it?

Please, correct me if I’m wrong :slight_smile:

By the way - I líke the idea of wrapping the existing plug-in into a Kirby-tag!

I think you are missing the point that this plugin is not just a wrapper for photoswipe, even thought it works with it, but creates perfectly balanced galleries server side.