44
votes

I'd like to make a dirt-simple portfolio of sorts on my jekyll blog. I have all my image files in a folder.

Currently, I have it generating the photos page like this:

<p style="line-height: 100px;">
<img src="photos/01.jpg"><br>
<img src="photos/02.jpg"><br>
<img src="photos/03.jpg"><br>
<img src="photos/04.jpg"><br>
<img src="photos/05.jpg"><br>
<img src="photos/06.jpg"><br>
<img src="photos/07.jpg"><br>
<img src="photos/08.jpg"><br>
<img src="photos/09.jpg"><br>
<img src="photos/10.jpg"><br>
</p>

Which isn't convenient at all if I want to add or remove new photographs. Is it possible to do something like the for loop I have for posts:

{% for post in site.posts %}
     <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
{% endfor %}

Except to loop over all the images?

Thanks!

6

6 Answers

75
votes

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.

16
votes

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

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.

9
votes

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.

0
votes

You can do also with collection
under root create _collection folder put images there

at _config.yaml add this code

collections:
  - collection

with front matter
create collections attribute

And then the code to list the image would be something like

{% for image in site.collection %}
     <img src="{{ file.url }}" />
{% endfor %}
0
votes

Listing the jpg files in the current directory in Jekyll can be done like this:

{% for file in site.static_files %}
  {% assign pageurl = page.url | replace: 'index.html', '' %}
  {% if file.path contains pageurl %}
    {% if file.extname == '.jpg' or file.extname == '.jpeg' or file.extname == '.JPG' or file.extname == '.JPEG' %}
    <img src="{{ file.path }}" />
    {% endif %}
  {% endif %}
{% endfor %}

A nice multi-purpose solution. More about this solution can be found here: http://jekyllrb.com/docs/static-files/


UPDATE: Jekyll Codex has implemented this code for easy re-use, allowing you to simply write:

{% include image-gallery.html folder="/uploads/album" %}
0
votes

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.