Will Grav work for a gallery with hundreds of images?

Hi there,

I have been ‘on’ Wordpress since 1.0 :wink: and I feel like trying something new. I need a very very basic minimal site, just a couple of text pages and one gallery page. I want to display 3 high quality thumbs in a row and 3 rows on a page. Every photo can be opened in some kind of lightbox. It’s a photoblog (one photo every couple of days I suppose). Think of it as a selfhosted instagram kinda page.

Grave coder theme is exactly what I needed. Installing was easy but now the big challenge is the gallery. I coudn’t find a lot of gallery plugins. And as far as I know none that does pagination or offers a load more button. So two question: does anyone know it this is achievable for a new user without twig knowledge (but a fast learner), and I am not entirely sure if Grav i suitable for say 600 images.

Hope someone can give me some solid advice here and point me in the right direction :slight_smile:

I have done image galleries in Grav without using any plugins. It works well, but the images are processed by the server and the bigger they are, the more work the server needs to do to process them. Once the images are processed, they are cached on the server and they load fast but if you are doing a single page with 600 images, you are going to need a decent hosting provider. I have moved most sites to Digital Ocean droplets from Wirenine and the photo galleries load much qicker.

What I like about using Grav for this sort of thing is the flexibility. More often than not, I just need to dump a bunch of photos on a page so all the site admin needs to do is put them in the folder using the admin module and my twig template does all the work of putting them on the page. If I want to use Masonry, no problem. I can adjust the thumbnails to be anything all using twig and no plugins.

For example, here is some twig to make a masonry gallery. I am using the filename as a photo caption. I am sure this is not the best code in the world, but I am not the best coder.

                    <div class="grid js-masonry">
                    {% for image in page.media.images %}
                        {% set imgtitle = image.filename|replace({'.JPG':'','.jpg':'','_':' ','-':' '}) %}
                       <div class="grid-item text-center">
                         <a href="{{ image.cropResize(800,800).url }}" rel="lightbox">
                           <img src="{{ image.cropResize(200,400).url }}" alt="{{ page.title }} {{ imgtitle }}" style="padding:5px;" />
                         </a>
                            {% if page.header.show_captions %}
                                <p><small>{{ imgtitle }}</small></p>
                            {% endif %}
                       </div>
                    {% endfor %}
                    </div>

Thanks you very much for your elaborate response mikegcox. That sounds great actually! I am going to give it a go.

One thing: will this work with pagination as well?

Kind regards

ps I have been playing aronf for a couple of hors with Grav and I really like it! Much more flexible and feature rich than I thought

I don’t see why it wouln’t work with pagination. I haven’t done it, but I am sure with a little bit of twig it could be figured out.

Just a hint: Don’t forget Grav comes with a built in lightbox action already. That should simplify the coding stage. Keep in mind though that this just creates the disired HTML output for a lightbox - you still need a lightbox (js) to make it work (featherlight or sim).

Hi slarchter,

Thanks. I haven’t had time to give it a try to built a gallery but I will soon. I did however try to install featherlight in my Grav Coder theme but somehow it does’t work. It did work in defaukt theme. Featheright seems to load though. Weird.

I am really started to like Grav :slight_smile: I got featherlight working. I noticed my theme was using jquery slim, when I started using a full version it worked.

I also tried the twig you (Mike) provided above and got that working as well. I am missing masonry or preferably responsive grid presentation. I suppose I need some (Jquery) plugin for that? Could you please point me into the right direction?

Edit: I had a look at your code and googled a bit, found a jquery plugin (https://masonry.desandro.com), put it on the server and loaded it with custom.js plugin. And it actually worked :slight_smile: Not bad for someone who doesn’t know what he is doing :slight_smile:

Next step is pagination or infinite scroll or a load more button, if anyone has any idea how to achieve this using this jquery / twig I would be very happy to learn

Some of the demo’s of Masonry use infinite scroll and lazy loading of images. Maybe that’s already handled by that library?

A general approach when integrating some Javascript code is to first get it working with a simple static HTML page. Then add the JS and CSS as assets to your Twig base template and in the appropriate templates for processing or output of HTML.

Regarding pagination, there’s the official (meaning created by the Grav dev team) Grav Pagination Plugin.

Thank you, that’s a some good advice! I will try your that approach. Easier to learn that way.

I have only one item on my to-do list and that is pagination (endless scroll is fine as well), and for the life of my I cannot figure out how to get this working.

@bleutzinn refered to the official plugin but does that work with media-items on a single blog item as well?

I am using @mikegcox twig which works great.

			<div class="grid js-masonry">
                {% for image in page.media.images|sort|reverse %}
                    {% set imgtitle = image.filename|replace({'.JPG':'','.jpg':'','_':' ','-':' '}) %}

                   <div class="grid-item text-center">
                     <a href="{{ image.resize(1920,1280).url }}" rel="lightbox">
                       <img src="{{ image.resize(600,400).quality(100).url }}" alt="{{ page.title }} {{ imgtitle }}" />
                     </a>
                        {% if page.header.show_captions %}
                            <p><small>{{ imgtitle }}</small></p>
                        {% endif %}
                   </div>
                {% endfor %}
                </div>

With this css

/* ---- grid ---- */

.grid {
  max-width: 960px;
}

/* clearfix */
.grid:after {
  content: '';
  display: block;
  clear: both;
}

/* ---- grid-item ---- */

.grid-item {
  width: 300px;
  height: 200px;
  float: left;
  /* vertical gutter */
  margin-bottom: 30px;
}

And this inline javascript

// init Masonry
var $grid = $('.grid').masonry({
  // options...
});

// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
  $grid.masonry('layout');
});

$('.grid').masonry({
  itemSelector: '.grid-item',
  columnWidth: 300,
  gutter: 30
});

I tried infinite scroll with masonry but couldn’t get it to work in Grav -> https://codepen.io/desandro/pen/eRRQVo

If someone is willing to help me out here (and has the patience), I would greatly appreciate that.

In case someone is looking for a similar solution.

I went with Media Boxes (not free, not expensive either) and Fancybox instead of Desandro’s Masonry and featherlight and used @mikegcox twig as an example. So I ended up with this:

</header>
    <div class="page-content">
        {{ page.content }}
		<div id="grid">
			{% for image in page.media.images|sort|reverse %}
            {% set imgtitle = image.filename|replace({'.JPG':'','.jpg':'','_':' ','-':' '}) %}
			<div class="media-box category1">
			<div class="media-box-image">
				<div data-thumbnail="{{ image.resize(600,400).quality(100).url }}"></div>
				<div class="thumbnail-overlay">
				<i class="fa fa-plus mb-open-popup" data-src="{{ image.resize(1920,1280).url }}" data-title="{{ imgtitle }}"></i>
			</div>
				</div>
			</div>
			{% endfor %}
		</div>
	</div>

Apart from that it’s basically just loading all the js and css files in the template you need them and initialize with as many options you need.

    <script>
    
    $('#grid').mediaBoxes(); 
    
</script>

Very happy with the result! very happy with Grav!