[caption id="attachment_340" align="alignright" width="1000" caption="Bookshelf is a means to manage and display books that I've read and would recommend."]Book Image[/caption]I'm happy to announce the launch of Bookshelf. Bookshelf is a means to manage and display books that I've read and would recommend. It is two things: a website front to display the books and a custom CMS to manage the data for these books. As a personal project, a large part of it was getting a better grasp on PHP. I started working on it in March of this year, then I got busy with work and wasn't able to get back to it until about a month ago.[foot]It's been on the back burner for a while now, so I repeat that I'm happy to announce its launch.[/foot] If you're interested in some of the geekier aspects of the project, keep reading. Otherwise, head on over and take a look.

The Website

Minimal Images

While the content itself is rather image heavy[foot]Each book has an image of its cover.[/foot], the site design only uses two images: one is the background texture, and the other is the background texture with a radial gradient. Everything else uses CSS. This keeps the page size small for fast loading and rendering.[foot]The size of a page, not counting book covers, is a mere 196kb un-gzipped.[/foot]

Adaptive Design

The site was designed before I got my hands dirty with true responsive design, so the layout is static, adjusting at certain breakpoints. An interesting challenge with this was how to handle the fixed positioning changes between the breakpoints. The design concept is that scrolling the screen just scrolls the bookshelves and everything else stays the same. This just isn't practical at some screen sizes, so I had to decide at what points things needed to change, what elements needed to change and how they needed to change. My basic solution for handling smaller vertical sizes was to switch the fixed elements to absolute positioning, allowing the entire screen to scroll. As the width diminishes, the bookshelf filtering and sorting get moved to drop-downs within the bookshelf, while the book information element remains fixed. The next breakpoint loses the fixed positioning concept and moves the book information above the bookshelf.


Seeing as the site is rather simple, consisting of a single template, I wanted to leverage AJAX for the content loading. For users with javascript enabled, the only page load is for the about/home pages. All book navigation is loaded asynchronously, without page loads.

Creating Shelves

[caption id="attachment_344" align="alignleft" width="485" caption=""Orphaned" books got a short shelf."]Screenshot of an orphaned book[/caption]The shelves for each row are created by aligned multiple bottom borders on each book.[foot]Using the technique described by Necolas.[/foot] This provided a lot of flexibility for the number of books needed on a row, row heights, and other dimensional factors of the shelf, allowing me to adjust the number of books on a row for smaller screen sizes as needed. The downside was orphan books were on a short shelf. For the main design, there are three books per shelf. If the number of books wasn't divisible by three, there would be leftover books on the last shelf. To fix this, I used a combination of :last-child and :nth-of-type to style as needed:[foot]Browser compatibility: modern browsers, IE9+[/foot]
/* Books that are the last 
and single on a row */
.books li:last-child:nth-of-type(3n+1) {
  width: 100%;
  padding-right: 4px;

/* Books that are last and are with 
one other book on a row */
.books li:last-child:nth-of-type(3n+2) {
  width: 66%;
  padding-right: 4px;

iPhone Icons

Apple Touch Icon for BookshelfI spent a good amount of time working on the iPhone icons for this site. These are the icons that show if you add the website to your home screen. I don't expect anyone to actually do that, but it's nice to have just in case.

The Back End

[caption id="attachment_348" align="alignright" width="1422" caption="The Back End"]Screenshot of the Bookshelf Admin Area[/caption]The back end is rather bare bones. It has the default styles of the HTML5 Boilerplate.[foot]Well, the default styles as of March of this year. I believe they have changed some since then.[/foot] I tried to create modular system in which I could add or remove functionality as it may be desired. Currently there is a "users" module and a "bookshelf" module. The "users" module provides user creation and management functionality, while the bookshelf module provides the functionality for managing the book data as well as giving hooks to echo the data within a front-end template.

Amazon Integration

At the suggestion of Garrett Kuk, I integrated Amazon's API into the backend, allowing for book addition by ASIN. This turned out to be a brilliant idea. It pulls all the information and then allows me to adjust and modify the details as I see fit. If for nothing other than automating the book cover image retrieval, resizing, and saving process, it's genius. Thanks, Garrett.

Known Issues

Of course, even at launch there are things that I would like to be different:
Truly responsive design
Responsive design is easiest to implement from the beginning of a project. I didn't want to scratch everything I had done in March to do so, but someday.[foot]The proverbial someday.[/foot]
Cleaner back end infrastructure
I already have ideas to improve the back end of the system. I believe the fact that I have a product that works and I know how to make it better proves a successful personal project. I can apply these lessons to the next project that comes my way.[foot]Or that aforementioned someday.[/foot]
High resolution book covers
Book covers uploaded prior to my iPhone 4 testing are the exact sizes needed for the space. This means that on the iPhone's retina display, they have artifacts. I have already adjusted the code to save double resolution images, but I haven't done anything for the previously uploaded images. The ideal solution would be to implement a "refetch and resize" functionality to the back end to do them automatically all at once or individually, as desired.
Lack of Internet Explorer Support
I try not to waste too much time in IE for my personal projects, but I did take a quick look at IE9, and it works. IE currently does not support history.pushState, so I have left the browser history untouched for IE. IE users will have a harder time linking directly to a specific book. Many of the more advanced CSS doesn't work in IE8 and older, and the :last-child:nth-of-type() trick is probably ignored in IE8 or older.
iPhone Icon Corners
I'm using "precomposed" icons for the iPhone, meaning I'm telling the phone not to add the rounded corners and reflection. I'm pretty sure that the corners did not maintain consistency as I scaled the image. It's just another thing that would take a bit of time to confirm and fix.
Book Comments
I did not spend much time on my comments on the books. Some, though I highly recommend and really enjoyed, I could not remember well enough to write a decent description. Others got lost in the bulk adding of books. I hope to be able to better craft comments as I add books as I read them.
Back End Efficiency
I'm still very fresh with back end programming, but there are so many things that could improve the Bookshelf platform. It is still far too coupled with my site design.
I'm sure there are other issues unknown. I hope you enjoy it. If you have thoughts on the project, I may be interested in hearing them.