Zero Configuration Web Galleries
Posted onTagged as computing, js, applescript and acrylamid
Background
Having migrated to static web generation, a full-featured web gallery system just isn't an option. I don't want or need an RDBMS to store meta-data, and there's certainly no reason to install an entire CMS framework just to pubish some pictures. However, having a four-year-old and a family that doesn't actually live in my back yard makes some kind of web gallery a necessity.
Yes, there are many picture sharing social media venues. All of them:
- have terms of service that can change with little notice and no consent
- have some kind of profit motive, mostly undisclosed
- are conflicted between security and accessibility
So we're on our own.
Problem Domain
Our household is firmly planted in the Apple Computer ecosystem. (No, that's not part of the problem!) This means that we have iDevices, and that we use iPhoto and Aperture to deal with the deluge of "kid pictures."
Aperture is fine photo management software, and it is capable of creating "web galleries". That is, it has built-in templates that can be used to export self-contained, nicely-themed, chunks of web space that one can upload to their own server. Unfortunately, Apple doesn't make it readily apparent how to create your own templates. Also the system to generate the galleries is IMHO more complex than required by the level of flexibiity allowed.
I knew that I wanted a cool Lightbox-style slide show, but I also wanted something that would "just work" if I uploaded a bunch of pictures into a directory. Again, trying to avoid any actual processing on the server.
Solution Landscape
Lightbox Software
I eventually settled on Fancybox for two reasons:
- It has user-definable callbacks for many events. I was hoping that some of these could be used by other software to pull captions (and other information) from the EXIF data in the pictures and display them.
- It's based on jQuery, and the Javascript EXIF parser that I found also had a jQuery version. Sharing code is good.
I also looked at other implementations:
- Lightbox2, which is the rightious sucessor to the original Lightbox.
- Lytebox, because there was already a project to make use of EXIF data.
Meta-data Extraction
Part of the original problem specification was to get a "caption" out of "the EXIF data." This goal is mal-formed.
EXIF doesn't really have a place for a "caption" -- there is an exntirely different standard for shoving meta-data into digital photographs called IPTC - which was created by journalists.
Of course Aperture does "the right thing" and puts the caption in the IPTC payload, not the EXIF payload. I had found a Javascript implementation of an EXIF parser, not an IPTC parser. Yeah... so auto-captions will have to wait for another day.
Aperture Export
Most Lightbox software requires two images - a full-size version and a thumbail. In my case, I also needed a manifest of the images in order to have Javascript dynamically insert the appropriate elements into the DOM.
I created three presets in Aperture:
- export settings for the full-size images
- export settings for the thumbnail images
- a directory export setting that put the output in "thumbs" under the target directory
Next, it was straight forward to build AppleScript that would export the current selection using those presets. It took a little fiddling to get the file names out of the list of version objects, but I evntually made it happen.
Solution
Gallery Export AppleScript
This is the AppleScript that exports the current selection into a selected folder in such a way that the Javascript can build the Lightbox:
tell application "Finder"
set destination to choose folder
end tell
tell application "Aperture"
set lightbox to first export setting whose name is "Gallery Lightbox"
set thumbnails to first export setting whose name is "Gallery Thumbnail"
set dirPolicy to first folder naming policy whose name is "Project Name"
set thumbDirPolicy to first folder naming policy whose name is "Gallery Thumbnails"
set oVers to selection as list
if oVers is {} then
error "Please select some images to export!"
else
-- need to exclude versions with referenced, missing master
set verList to export oVers using lightbox to destination naming folders with dirPolicy
set thumbList to export oVers using thumbnails to destination naming folders with thumbDirPolicy
-- Write one file name per line to MANIFEST
try
set projDir to value of other tag "MasterLocation" of the first item in oVers
set default_delimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
set manifest to open for access file ((destination as string) & (projDir as string) & ":MANIFEST") with write permission
repeat with ver in verList
write text item -1 of (ver as rich text) to manifest as rich text
write (ASCII character 10) to manifest
end repeat
set AppleScript's text item delimiters to default_delimiters
close access manifest
on error
try
set AppleScript's text item delimiters to default_delimiters
close access manifest
return false
end try
end try
display dialog "Export to " & destination & "complete."
end if
end tell
Dynamic Gallery Javascript
This is the Jacascript that will build a Lightbox, given an export arranged by the preceeding AppleScript:
$(document).ready(function() {
$.get("MANIFEST", function(data) {
var lines = data.split('\n'); // one pic per line
var gallery = $('#gallery-container');
lines = $.grep(lines, function(n){ return(n) }); // remove empty elements
$.each(lines, function(lineNo, line) {
$("<a />", {
"class": "fancybox",
"data-fancybox-group": "gallery2",
"href": line,
"html": $("<img />", {
"src": "thumbs/" + line
})
}).appendTo(gallery);
}); // each
}); // get MANIFEST
/*
* Simple image gallery. Uses default settings.
*/
$('.fancybox').fancybox({
afterLoad: function() {
}, // afterLoad
beforeShow: function() {
} // beforeShow
}); // fancybox
}); // ready
Apache Configuration
In my web space, each gallery is a sub-folder of /pics. In order to avoid special set-up for each new gallery, we to do the following:
- let mod_index create the list of galleries, prepending a header and appending a footer generated for the web site theme -- this is the only server-side "processing"
- for any subdiretory of /pics, use gallery.html as the index file (for the index.html document or just the gallery location URL)
This .htaccess fragment accomplishes that:
Options +FollowSymlinks
IndexOptions NameWidth=*
IndexIgnore FOOTER* gallery.html
HeaderName HEADER.HTML
ReadmeName FOOTER.HTML
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteBase /pics
RewriteRule ^.+/$ /pics/gallery.html [L]
RewriteRule ^.+/index.html$ /pics/gallery.html [L]
Summary
It's not trivial, but all of the components are pretty simple. At least now I can spend my gallery management time curating pictures.