User-submitted photo galleries

It was what you’d call a “hard-and-fast” deadline: Our contract with Caspio for database and data services was changing on July 1. On that day, our account — which to that point had been averaging something like 17GB transferred per month — would have to use no more than 5GB of data per month, or else we’d pay to the tune of $50/GB.

Our biggest data ab/user by far was our user-submitted photo galleries. A popular feature among our readers, it allowed them to both upload photos for us (at print quality) to use in the paper as well as see them online instanteously. Caspio stored and displayed them as a database: Here’s a page of a bunch of photos, click one to get the larger version.

We had to come up with something to replace it — and, as ever, without incurring m/any charges, because we don’t have any money to spend.



There are a number of image hosts out there, of course, but the terms of use on their accounts vary wildly. The two main hosts we looked into were Flickr and Photobucket. Photobucket had the advantage of being Not Yahoo, which was a plus in my eyes, but their variable pricing structure (not conducive to multiple accounts, difficult to budget for the future) and lack of apparent developer support (the page you’re directed toward to set up an account no longer exists) made that seem unwise.

Flickr offers 1 TB of storage for reasonable pricing, but a hard request limit (3600/hour) and reasonable usage request (“You shall not use Flickr APIs for any application that replicates or attempts to replace the essential user experience of”) kind of limited its appeal to use a gallery host. Well, there went that idea. Then we started looking at resources we already had.

A few years ago, Digital First Media provided its news organizations with the nifty MediaCenter installations developed at the Denver Post. MediaCenter is an SEO-friendly, easy-to-use WordPress theme/plugin combo that stores its data in SmugMug, another photo storage site we’d looked at but abandoned based on price. But, you see, we already had an account. An in. (A cheap in, to the delight of my editor.) Once we clarified that we were free to use the API access, we decided to do what the pros do: Build what you need, and partner for the rest. Rather than build out the gallery functionality, we’d just create SmugMug galleries and MediaCenter posts, and direct uploaded photos there.


The official SmugMug API is comprehensive, though … somewhat lacking in terms of ease of use. Luckily, someone created a PHP wrapper (PHPSmug), which works, more or less. (There are a few pitfalls, in terms of values not corresponding and some weirdness involving the OAuth procedure, but it’s all work-through-able.)

The whole point of user-generated photos is that you want to have the content live forever on the web, but keeping 400 “Fourth of July”-esque-specific categories around in the upload list is going to frustrate the user. We decided to treat categories in two ways: Active and Inactive. Once you create a gallery, it never goes away (so it can live on in search), but you can hide it so it doesn’t necessarily jump in the user’s face all the time.

Print workflow was especially important to us, as one of the major goals of the system was to not create additional work. Due to circumstances out of my control, the server we have to work with does not have email functionality. Using a combination of Google Scripts (linked below) and some PHP, we weaseled around that limitation and email the original uploaded photo to our normal inbox for photo submissions, thus not forcing the print workflow to require using the web interface.

Allowing uploads from mobile devices is almost a cinch since both Android and the later flavors of iOS support in-browser uploads. The whole thing was built off responsive Bootstrap, so that was the easiest part of the whole project.

One of the biggest reasons we have a photo uploader and web gallery in the first place is to reassure people that when they submit a photo to us, we received it. This helps to prevent a deluge of phone calls or emails inquiring whether we in fact received the photo and when we plan to run it. Having the web gallery gives the user instant notification/gratification, and allows us to remind them gently that we don't have the space to print every photo we receive — but you can certainly view them online.


On the backend, we have one database containing three cross-indexed tables — one to hold authentication info (per property), one for the category info and one for the photos themselves. Because we're using SmugMug as the storage system, there's no need to hold the actual photo ourselves (which helps with data usage from both a storage and transfer perspective). All the photo storage table has to hold is the information for retrieving it from SmugMug.

The user navigates to a specific property's upload form, fills it out and uploads the photo. The component parts of the form are stored separately as well as combined into our standard user-caption format. The caption is used when we send the photo to SmugMug, but we also store it locally so we can sync them up if changes need to be made. The photos are directed to the gallery specified by the user.

After a certain amount of time (about 5 minutes on SmugMug's end, and anywhere from 15-30 minutes on our gallery's end because of the massive caching it was designed with), the photo automatically appears on our photo gallery site. From the backend, users are able to create or retire categories, edit photo caption information and delete photos.

There's hope that we'll be able to do things like move photos around or create archive galleries, but that's down the road, if we have the time.


You can view the final product here, here, here or here (spoiler alert: They’re almost exactly the same). There are still features we’d like to add, but there were more fires to put out and we had to move on. Hopefully we can come back to it when things settle down.