Jekyll for loop over all images in a folder?

This worked like a charm for me. No plugins required.

My images are in a assets/images/slider directory.

{% for image in site.static_files %}
    {% if image.path contains 'images/slider' %}
        <img src="{{ site.baseurl }}{{ image.path }}" alt="image" />
    {% endif %}
{% endfor %}

The image.path contains 'images/slider' makes sure that only images in that folder are inserted.

Further reading here and on jekylltalk.

Troubleshooting: As mentioned in the comments, if you have trouble with this approach, you might want to try removing the indentations before the Tag.


The Jekyll Codex implementation suggested by Joosts is a great starting point. I've researched for a while and there are a bunch of similar projects but most of them are discontinued or partially working.

After some digging, I feel that the best project for the use case is Azores Image Gallery, it's reasonably fast and has a small memory footprint because rely on Minimagick a small Ruby wrapper for ImageMagick:

https://github.com/simoarpe/azores-image-gallery

DISCLAIMER: I'm the author.


Ideally, you'd like to scan an image directory, then generate a list of files from there. Jekyll doesn't have a function for doing this that I know of. It is, however, quite extensible, so you have a couple of options:

  1. Write (or find) a plugin that does the directory scan. If you know Ruby, this shouldn't be too challenging. The Jekyll site has documentation on how a plugin should look. (You probably want to go for a custom Liquid tag.)
  2. If you don't know Ruby, you could consider generating special gallery HTML pages using an external script or program, and then including the generated files into your templates. Here's a shell oneliner as an example:

    find . -name \*.jpg | sed 's:./::' | sed 's/^/<img src="/' | sed 's/$/"><br>/'

  3. If you're okay with sticking to your naming convention, you could just also fake it and just use a regular loop:

    {% for i in (1..10) %}
    <img src="photos/{{ i }}.jpg"><br>
    {% endfor %}
    

    But that would mean you'd still have to remember to keep the '10' number updated.

The second option and third options are less clean, but both have the advantage that they will work with GitHub pages (if that's what you use), while the first one won't.


Here's another solution (with multiple gallery pages) which doesn't use plugins, so it works with GitHub Pages.

I have a blog post with a more detailed explanation here:
Generating an image gallery with Jekyll and Lightbox2

  • Finished gallery overview page
  • Source code

Here's the short version:

  1. Create a YAML data file (_data/galleries.yml) with the list of images:

    - id: gallery1
      description: This is the first gallery
      imagefolder: /img/demopage
      images:
      - name: image-1.jpg
        thumb: thumb-1.jpg
        text: The first image
      - name: image-2.jpg
        thumb: thumb-2.jpg
        text: The second image
      - name: image-3.jpg
        thumb: thumb-3.jpg
        text: The third image
    - id: anothergallery
      description: This is even another gallery!
      imagefolder: /img/demopage
      images:
      - name: image-4.jpg
        thumb: thumb-4.jpg
        text: Another gallery, first image
      - name: image-5.jpg
        thumb: thumb-5.jpg
        text: Another gallery, second image
      - name: image-6.jpg
        thumb: thumb-6.jpg
        text: Another gallery, third image
    
  2. For a list of available galleries, just loop through the data file:

    {% for gallery in site.data.galleries %}
    - [{{ gallery.description }}]({{ gallery.id }})
    {% endfor %}
    
  3. Create a layout file (_layouts/gallery.html) that all galleries will be based on:

    (in my example, I'm using Lightbox2 to display the images, so there's additional HTML in my example that you don't even need when you just want to use <img src="photos/01.jpg">)

    ---
    layout: default
    ---
    
    <script src="/js/jquery-1.10.2.min.js"></script>
    <script src="/js/lightbox-2.6.min.js"></script>
    <link href="/css/lightbox.css" rel="stylesheet" />
    
    {% for gallery in site.data.galleries %}
      {% if gallery.id == page.galleryid %}
        <h1>{{ gallery.description }}</h1>
        <ol>
        {% for image in gallery.images %}
          <li>
            {{ image.text }}<br>
            <a href="{{ gallery.imagefolder }}/{{ image.name }}" data-lightbox="{{ gallery.id }}" title="{{ image.text }}">
              <img src="{{ gallery.imagefolder }}/{{ image.thumb }}">
            </a>
          </li>
        {% endfor %}
        </ol>
      {% endif %}
    {% endfor %}
    
  4. For each gallery page, create a .html or .md file that just contains three lines of YAML front-matter:

    ---
    title: the first gallery page
    layout: gallery
    galleryid: gallery1
    --- 
    

    The layout: gallery line refers to the layout file from step 3.
    The galleryid: gallery1 line refers to the data file from step 1, so that the layout file "knows" that it has to show the images from the first gallery.


That's it.

This solution doesn't automatically loop over the images folder, but you just have to insert new images into the data file, which is less tedious than creating the <img src="photos/01.jpg"> HTML lines by hand (especially when the HTML is more complex than that, as in my Lightbox2 example above).

Plus, as I said in the beginning: It works on GitHub Pages, which all solutions with plugins (with which it's possible to loop the image folder) do not.

Tags:

Jekyll