Typically self-congratulatory blog posts about all the cool visual things that will make you–the reader–better off accompany website launches such as this one. One of my colleagues may yet write that post. I am not.

I am writing a blog post about all the cool stuff that you don’t necessarily see. Or the stuff that powers the stuff that you see. It’s kinda geeky that way.

The Server

GeekyLibrary runs on an Nginx VPS pseudo-managed by DreamHost, but soon to be moved to Linode. Why Linode? Because it is cheap (inexpensive) because it’s unmanaged. I can probably manage. Why Nginx? For a bunch of reasons:

Nginx is the new hotness in webservers. It’s fast, which is good, but more important is that it scales consistently. My Apache VPS (from a typical LAMP stack) would be all over the place in terms of server usage where my Nginx server stays constant. This is awesome and it means less 500-series server errors.

Apache VPS running just one, small site. Note how the server resources constantly spike and trough. I’ve since moved most of my sites to Nginx
Server usage on my Nginx VPS. Yeah, the resources are higher but that’s because there are a bunch of sites running. More importantly, the usage is relatively flat.


WordPress. Making WordPress websites is my full-time job but it also happens to be the best CMS out there.

Specifically, GeekyLibrary is running on a multi-site or network installation of WordPress with a domain mapping plugin. Speaking of plugins, we’re also using Simple Local Avatars, Edit Flow, a custom plugin I wrote to capture emails to Mailchimp, and Posts 2 Posts used to link authors to books, oh yeah, and Jetpack…

The Library

The heart of GeekyLibrary is a plugin I wrote to handle the book reviews we call our library. I’m going to talk a little WordPress here, so forgive me if you don’t speak that dialect of geek yet.

Each library book is a custom post type with a pretty significant UI overhaul (more on that in a second). It’s linked to the Authors custom post type by way of Posts 2 Posts. We’ve also added a book genres custom taxonomy. There’s some more admin UI work that could be done here in the future.

Library Book Admin UI

The UI for the book custom post type removes the post_content wp_editor. We use post_content, but it’s never edited directly. Instead we have several custom wp_editors loaded right after the title thanks to the new WP 3.5 action hook “edit_form_after_editorThanks Helenyhou!

Each wp_editor that we’re adding relates to a specific part of a review. We have the intro/hook, explanation of our rating, and why the book is on our bookshelf. When the post/book is saved, those editors are concatenated and inserted into post_content. They’re also saved separately as post meta giving us several different ways to display posts.

At the bottom of the post editor is a custom metabox for the few questions at the bottom of the post (e.g. “Read this book: …”). It also has a slot for the isbn…

The WordPress Admin UI our reviews are currently using. More refinements to come

The Powells.com API

The ISBN is then used to query the Powells.com API. The ease of querying the Powells API is awesome. It’s a simple RESTful API accessed via GET requests. Super simple. The only trick is that data isn’t necessarily available via all ISBNs a book might have. So we query twice: once with the ISBN input, then again with the UPC that Powells has on file. The latter ensure we can get a proper affiliate link and book review info. We cache that information as post meta and refresh it rarely.

Multiple Book Reviews

We’ve built-in the ability for multiple book reviews on the site. For example, I could go back and write a book review for The Hitchhiker’s Guide to the Galaxy, because I feel three stars is a disservice. We want to only present one review in the Library: a canonical review. So, the first person to write a review wins out and every other person reviewing a book writes it as a child post of the original. Those secondary reviews won’t show up in the library, but will be given some linkage from the canonical review. There’s also a link from the secondary review back to the main one. In order to get the library to show the correct books and the reviews to show sibling and parent reviews took some query manipulation, which was fun.


No website is created in a vacuum. Well, maybe, but it’d be difficult to work near the rollers, especially if it was turned on. GeekyLibrary was created with a bunch of different tools.

    • PHPStorm: This is my preferred IDE at the moment and all of GeekyLibrary was and is written in it. xDebug integration served it’s purpose a few, frustrating times here
    • Bitbucket: The GeekyLibrary theme and the custom library plugin are both in their own private git repo thanks to Bitbucket. Right now it’s a manual deploy process by SSHing into the server and git fetch/merge from the Bitbucket remote.
    • BrowserStack: Cross browser testing sucks, BrowserStack makes it easier and faster
    • Feedback Army: During beta, we ran a bunch of users through the site and collected some early feedback. We’re on a small budget, and Feedback Army gets us some valuable insight for not a huge investment
    • Optimizely: We’re testing Optimizely to test GeekyLibrary
    • MailChimp: Awesome API, easy email campaigns, own your data
    • Google Analytics: hooked up, will be invaluable
    • Photoshop: It’s where the geekylibrary header, apple-touch-icon, Twitter avatar, Facebook avatar, etcetera were born.
    • MacBook Pro 15″ Retina

It’s my office for both work and hobbies such as this (Geeks talk about hardware, what can I say).

If you have any questions about how or why we did something on the site, or if you find something broken, sound off in the comments (or get in contact)