diff --git a/blog/_posts/2014-04-08-photo-galleries-for-jekyll.md b/blog/_posts/2014-04-08-photo-galleries-for-jekyll.md new file mode 100644 index 0000000..bfb6e2a --- /dev/null +++ b/blog/_posts/2014-04-08-photo-galleries-for-jekyll.md @@ -0,0 +1,180 @@ +--- +title: Photo Galleries for Jekyll +layout: post +tags: blog gallery iphoto jekyll jekyllrb photo ruby +description: Easily exporting my iPhoto album to this Jekyll-based site. +--- + +I had a trip to London and Iceland several weeks ago, and I wanted to share some of those photos with people. In the +past I've put those sorts of photo galleries on Facebook, but some friends don't have accounts there and I figured I +could/should just keep my photos with my other personal stuff here. + +Unlike [WordPress][1], [Jekyll][2] doesn't really have a concept of photo galleries, and since Jekyll is a static site +generator it makes things a little more difficult. I looked through [several][3] [other][4] [posts][5] discussing Jekyll +photo galleries, but they all seemed a bit more primitive than what I wanted. I wanted to: + + * stick with existing Jekyll paradigms (e.g. [markdown][8] file to static page), + * retain metadata about my photos (e.g. location data, camera EXIF data), + * support multiple views about my galleries (e.g. photo list, map, slideshow), + * ensure photos can have landing pages and be easily navigated, and + * avoid committing images to my git repository. + +After giving it some thought, I realized this was going to be a multi-step process. + + 0. Script the process of exporting my existing photos to Jekyll-friendly structures. + 0. Find a Jekyll/[Liquid][7] plugin to enumerate directories/files and use the results. + 0. Create templates and pages for my gallery and its photos. + 0. Publish the site! + + +## Step 1: Export existing photo galleries (iPhoto) + +I take pretty much all my photos with my phone and those photos then get synced up with iPhoto. At the end of my trip, I +browse through the photos and create an album of interesting ones. Normally I don't go through and give every photo a +title and description, but if I'm planning on sharing them I add brief notes within iPhoto. + +I knew my iPhoto metadata was stored in `AlbumData.xml`, but I've always had poor performance with massive XML data +files. I decided to start with a different approach: [AppleScript][9]. The following snippet gets me the file paths of +all the photos (in order) from whatever album I ask for: + +{% highlight applescript %}{% raw %} +on run argv + set output to "" + + tell application "iPhoto" + set vAlbum to first item of (get every album whose name is (item 1 of argv)) + set vPhotos to get every photo in vAlbum + + repeat with vPhoto in vPhotos + set output to output & original path of vPhoto & " +" + end repeat + end tell + + return output +end run +{% endraw %}{% endhighlight %} + +So, to get the photos in my album named "London-Iceland Trip" I can do: + +{% highlight console %}{% raw %} +$ osascript export-iphoto-album.applescript 'London-Iceland Trip' +~/Pictures/iPhoto Library.photolibrary/Masters/2014/03/13/20140313-154842/IMG_0303.JPG +~/Pictures/iPhoto Library.photolibrary/Masters/2014/03/13/20140313-154842/IMG_0308.JPG +...snip... +{% endraw %}{% endhighlight %} + +With some tweaks I can get more than just the path to a photo: + +{% highlight console %}{% raw %} +$ osascript export-iphoto-album.applescript 'London-Iceland Trip' +altitude: 16 +latitude: 51.50038 +longitude: -0.12786667 +name: A Classic View +date: Thursday, March 6, 2014 at 4:44:12 PM +path: ~/Pictures/iPhoto Library.photolibrary/Masters/2014/03/13/20140313-154842/IMG_0303.JPG +title: A Classic View +------ +QCon was held at The Queen Elizabeth II Conference Centre and this was the view out one of the common areas. +------------ +...snip... +{% endraw %}{% endhighlight %} + +The next piece is to write something which will clean up the output, resize the photos, and write out all the different +Jekyll files. For that I created a [PHP][10] script since it was going to be easiest for me. Once complete, I then just +pipe the export results to the script and specify the image sizes I want: + +{% highlight console %}{% raw %} +$ osascript ../jekyll-gallery/export-iphoto.applescript 'London-Iceland Trip' | \ + php ../jekyll-gallery/convert.php 2014-london-iceland-trip \ + --export 96x96 --export 200x200 --export 640 --export 1280 +df5150c-a-classic-view...96x96...200x200...640...1280...mdown...done +7cf02b5-night...96x96...200x200...640...1280...mdown...done +...snip... +{% endraw %}{% endhighlight %} + +Once complete, all the resized images are in `asset/gallery/2014-london-iceland-trip` and my markdown files with the +photo details are in `gallery/2014-london-iceland-trip` and they're easily [readable][15]. + + +## Step 2: Jekyll plugin + +At a minimum, I wanted to have a listing of all the photos in a gallery index page. After some searches, I found +[two][11] [scripts][12] which became the inspiration for my final plugin. My [final plugin][16] looks like: + + Tag: + loopdir + Attributes: + match: a pattern to match files within the path (e.g. "*.md") + parse: whether to load the file and parse for YAML front matter + path: a directory, relative to the site root, to find files + sort: a property to search by (e.g. "path") + Result: + An "item" object is exposed to the template with a "page"-like structure. + If parsing is enabled, the YAML properties are available as "item.title". + +Which means I can easily compose a simple photo list with: + +{% highlight jinja %}{% raw %} +{% loopdir path:"gallery/2014-london-iceland-trip" match:"*.md" sort:"ordering" %} + + Photo: {{ item.title }} + +{% endloopdir %} +{% endraw %}{% endhighlight %} + +I reuse this plugin elsewhere for regular directory listings. + + +## Step 3: Create templates + +I've started out with two reusable templates in my `_includes` directory: + + 0. [Gallery List][13] - a simple listing of thumbnails from all the photos in the gallery + 0. [Interactive Map][14] - an interactive map showing where all the photos were taken + +I can pass arguments (like the gallery name) to the include which makes it easy to embed a gallery in any page: + +{% highlight jinja %}{% raw %} +{% include gallery_list.html gallery='2014-london-iceland-trip' %} +{% endraw %}{% endhighlight %} + + +## Step 4: Publish + +After generating everything locally, I just have to do a couple steps: + + 0. Commit all the new `gallery/2014-london-iceland-trip` files (and new templates) + 0. Run `_build/aws/publish-asset.sh $AWS_S3CMD_CONFIG gallery/2014-london-iceland-trip` to upload all the exported JPGs + 0. Run `_build/aws/build.sh _build/aws/publish.sh $AWS_S3CMD_CONFIG` to upload any modifications from the rest of the + site + +To make things easier for myself and, possibly, others I put the conversion scripts in my [jekyll-gallery][17] repo. + +Now I'm able to refer people to the [gallery](/gallery/2014-london-iceland-trip/) or embed the gallery somewhere +useful... + +
+ {% loopdir path:"gallery/2014-london-iceland-trip" match:"*.md" sort:"ordering" %}Photo: {{ item.title }}{% endloopdir %} +
+ + + + [1]: http://wordpress.org/ + [2]: http://jekyllrb.com/ + [3]: https://github.com/ggreer/jekyll-gallery-generator + [4]: http://www.mgratzer.com/from-wordpress-to-jekyll/ + [5]: https://github.com/tsmango/jekyll_flickr_set_tag + [6]: https://help.github.com/articles/what-are-github-pages + [7]: http://liquidmarkup.org/ + [8]: http://daringfireball.net/projects/markdown/ + [9]: https://developer.apple.com/library/mac/documentation/applescript/Conceptual/AppleScriptX/AppleScriptX.html + [10]: http://www.php.net/ + [11]: https://gist.github.com/jgatjens/8925165 + [12]: http://simon.heimlicher.com/articles/2012/02/01/jekyll-directory-listing + [13]: https://github.com/dpb587/dpb587.me/blob/master/_includes/gallery_list.html + [14]: https://github.com/dpb587/dpb587.me/blob/master/_includes/gallery_map.html + [15]: https://github.com/dpb587/dpb587.me/blob/master/gallery/2014-london-iceland-trip/df5150c-a-classic-view.md + [16]: https://github.com/dpb587/dpb587.me/blob/master/_plugins/loopdir.rb + [17]: https://github.com/dpb587/jekyll-gallery