As far as blogging platforms go, Jekyll is both a blessing and a curse. It has taken time to turn it into something I like; let me show you what I’ve done.

I had previouly created my blog with WordPress and moved to Drupal. I don’t need dynamic online content creation, and I was tired of getting notices from Dreamhost that my site was compromised and I needed to clean it up. Jekyll is static, manageable with git, uses ruby, and easy for me to configure to publish with a simple git push live.

These days with smartwatches, 5K desktops, and everything in between, it’s important to serve up appropriately-sized images for every site visitor. You don’t want pixelated images, you don’t want people to use up their data plan, and you don’t want them to wait forever for pixels they’re never going to see. Cloudinary is great for this service, as they handle resizing and CDN needs with aplomb.

Problems

Cloud, only sometimes: nhoizey wrote a Jekyll plugin which adds a {% cloudinary image_path %} liquid tag. It is highly customizable, but the most important features for me are pass-through upload and defining imagesets. I don’t have to worry about uploading images to them myself, and Cloudinary serves up resized versions appropriate for different devices via their CDN. However, the plugin doesn’t work for images when they’re hosted on localhost, only when your posts are in a production (internet-accessible) environment!

Galleries, but easy: I want to be able to easily put small galleries of images together (like above) with captions. Lightbox2 serves the stylesheets and javascript, and it does so marvelously. However, creating galleries out of liquid tags for each image is too cumbersome. I’m too lazy for that.

Solution

Jekyll is highly customizable. The front matter section of each post is YAML which you can use for any purpose. Therefore I used it to define as many galleries for the post as I’d like.

Advantages:

  • Galleries for a post are kept in the same file. No bouncing back and forth between different documents.
  • Posts read cleanly when editing. A huge amount of image, gallery, and caption markdown is abstracted away.
  • Images use Cloudinary when the blog is pushed live, but just read from jekyll server when in developer_mode.
  • Images are expected to exist in a folder according to the post’s year and month. This allows a reasonable level of image file organization, without going too crazy.

Disadvantages:

  • Cloudinary transformations and resizes are not performed when drafting your posts locally.
  • If captions are key to your post’s narrative, it can be annoying to scroll to the top of the .md to edit the front-matter and go back down to your content markdown.
  • I sometimes forget the format of the include statement.

Code

Site config

# _config_dev.yml
developer_mode: true

Then start your local server using jekyll serve --config _config_dev.yml,_config.yml.

Post front matter

# my-blog-post.md
----
title: "Jekyll with Cloud Images and Galleries"
galleries:
  gallery1:
    pictures:
      - url: "picture1.jpg"
        caption: "Picture 1 has a nice caption."
      - url: "picture2.jpg"
        caption: "Picture 2 has a caption"
      - url: "picture3.jpg"
  gallery2:
    pictures:
      - url: "you-get-it.png"
        caption: "I think you see how this works now."
----

Gallery include

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- /_includes/gallery.html -->
{% capture year %}{{ page.date | date: "%Y" }}{% endcapture %}
{% capture month %}{{ page.date | date: "%m" }}{% endcapture %}
<div class="mdl-grid">
{% for picture in page.galleries[include.gallery_id].pictures %}
  {% if page.galleries[include.gallery_id].pictures.size > 1 %}
  <div class="mdl-cell mdl-cell--4-col">
  {% else %}
  <div class="mdl-cell mdl-cell--12-col">
  {% endif %}
    {% capture picture_url %}/img/{{year}}/{{month}}/{{picture.url}}{% endcapture %}
    <a href="{{picture_url}}" data-lightbox="{{include.gallery_id}}" title="{{picture.caption}}">
      {% if site.developer_mode %}
        <img src="{{picture_url}}"/>
      {% else %}
        {% cloudinary {{picture_url}} %}
      {% endif %}
    </a>
  </div>
{% endfor %}
</div>

Now inserting a gallery in a post is as simple as including {% include gallery.html gallery_id="gallery1" %}.

Image include

For inline images, without galleries and captions, I defined /_includes/image.md which works similarly.

1
2
3
4
5
{% if site.developer_mode %}
  ![]({{include.image_url}})
{% else %}
  {% cloudinary {{include.image_url}} %}
{% endif %}

A little more

The jekyll-cloudinary plugin already makes extensive use of _config.yml variables. It may make sense to add a ‘passthrough’ option, similar to my developer_mode _config variable. Unfortunately, since no resizes or other transforms would be performed on the images, it may lead to confusion for rookie bloggers. It has been discussed by nhoizey and hasn’t happened yet, so I’m not too keen on submitting a pull request. Maybe I’ll make my own branch, which you can pull if you’d like.

I also don’t handle image titles and alt tags yet, so accessibility suffers right now. Some small modification to the front matter schema and image markdown may suffice.

Acknowledgements

Christian Specht had a great blog post which inspired me to use YAML to define the gallery details. I took a different approach, though: one better suited to my blogging needs. The jekyll-cloudinary plugin is essential, of course. jekyll-mdl was a starting point for my site’s theme, but I found it needed some modifications to be usable.

-vkm

Who’s Varun?

I most recently was the founder of an HR tech startup, Disqovery. I have worn many hats, and I like making things. I also like talking business. You can reach me at smartperson@gmail.com, @smartperson, Github, and LinkedIn.