The WordPress plugin I use to manage my reading list is an updated version of the popular Now Reading plugin, called Now Reading Reloaded.
Original NRR book management page.
The original Now Reading plug was developed by Rob Miller who stopped maintaining it at around WP2.5. Luckily, Ben Gunnink at heliologue.com picked up where Rob left off and gave us Now Reading Reloaded (NRR). Unfortunately, it seems that the maintainer has no time to donate to the project and ceased maintaining it.
As one can see, the plugin is a great way to organize and share reading lists. This is exactly what I was looking for when I searched the WP plugin database. Up until then I was tracking my reading lists using simple lists in WP posts and pages. The database back-end of NRR gives it much more potential than one can hope to achieve with simple lists. This is not to say anything of the Amazon search-n-add feature with link and thumbnail of the book cover. All very welcome features.
Limitations
Unfortunately, NRR is far from perfect. One can run into it’s quirks multiple times during a single book update. But, for the price, I can’t complain. None of the issues were too big to annoy me enough to get my hands dirty debugging and patching the code. None, that is, except for a little obvious feature conspicuously missing. By the time I added most of the books I had in my lists and started updating what I read and adding current-reading items, I wished I didn’t have to jump from page to page until I found the book I had just finished to update its status. That is, I wished I could simply sort my library by status, started-reading or finished-reading dates. Even better, I wished by default the library showed me the latest books I started reading, which I was most probably interested in updating.
While open-source programs are great for too many reasons to list here, they all suffer from the same problem. Namely, the freedom to update the code also, by definition, forks and diverges it from the source. This immediately adds the overhead of merging any updates or bug-fixes added to the source to your hand-modified version. However, since it seems that NRR is no longer maintained, I had no reason to fear such a hustle and I still had all the reasons to get sorting functionality in the admin library page, also known as the Manage Books page.
Figuring out the code
First test with new sorting code.
First I had to figure out the wheres and the hows of the code. I wasn’t familiar with NRR, so I had some detective work ahead of me. First, I browsed the page in question: wp-admin/admin.php?page=manage_books. I browsed the pages and noticed how the URL was formed. Apparently, selecting the page to display is chosen by specifying a ‘p’ argument and the index of the page. For example, the second page would be /wp-admin/admin.php?page=manage_books&p=3. Next I had to find the PHP file responsible for generating this page. Since each plugin is stored in its own separate folder, first place to look in was the NRR plugin folder within my WP installation. On my WP3.1 installation, this folder is at /wp-content/plugins/now-reading-reloaded/admin. Within this folder a few PHP files exist with the “admin” prefix. The file “admin-manage.php” seems a reasonable start. I looked for any table construction code that resembles the Manage Books page, and sure enough it’s right there.
Patching
Page sorting works.
(Note: Breaking the PHP files may leave your WP in limbo. Make sure you have backup of your site before you make manual changes, and that you can replace broken files via ssh or ftp.)
The key to adding sorting is to figure out how the database query is generated. This, as it turns out, wasn’t very difficult to find. Within the admin-manage.php file the get_books function contains the complete query
$books = get_books("num=-1&status=all&orderby=status&order=desc{$search}{$pageq}{$reader}");
From this, it’s quite obvious which filter is responsible for what. The ‘orderby’ filter selects the sorting column, ‘order’ decides the direction of sorting and the rest are for searching, pagination etc. Instead of using hard-coded values, we need to get these values from the browser. Let’s add a couple of optional parameters to the page:
if ( empty($_GET['o']) )
$order = 'desc';
else
$order = urlencode($_GET['o']);
if ( empty($_GET['s']) )
$orderby = 'started';
else
$orderby = urlencode($_GET['s']);
So ‘o’ will decide the ‘order’ and ‘s’ the ‘orderby’ value. Before I move on, I have to test that this is working in practice and not just in theory. Manually loading the page with the newly added parameters give the expected results. /wp-admin/admin.php?page=manage_books&s=author&o=asc loads as expected the table of books, sorted by the author name in ascending order. Now, all we have to do is add links to the column headers and we can get a working page.
if ( $order == 'asc' )
$new_order = 'desc';
else
$new_order = 'asc';
$book_link = "{$nr_url->urls['manage']}&p=$page&s=book&o=$new_order";
$author_link = "{$nr_url->urls['manage']}&p=$page&s=author&o=$new_order";
$added_link = "{$nr_url->urls['manage']}&p=$page&s=added&o=$new_order";
$started_link = "{$nr_url->urls['manage']}&p=$page&s=started&o=$new_order";
$finished_link = "{$nr_url->urls['manage']}&p=$page&s=finished&o=$new_order";
$status_link = "{$nr_url->urls['manage']}&p=$page&s=status&o=$new_order";
echo '
<table class="widefat post fixed" cellspacing="0">
<thead>
<tr>
<th></th>
<th class="manage-column column-title"><a class="manage_books" href="'. $book_link .'">Book</a></th>
<th class="manage-column column-author"><a class="manage_books" href="'. $author_link .'">Author</a></th>
<th><a class="manage_books" href="'. $added_link .'">Added</a></th>
<th><a class="manage_books" href="'. $started_link .'">Started</a></th>
<th><a class="manage_books" href="'. $finished_link .'">Finished</a></th>
<th><a class="manage_books" href="'. $status_link .'">Status</a></th>
</tr>
</thead>
<tbody>
';
Notice that I didn’t forget to invert the current sorting order in the link. This is pretty straight forward. Reloaded the page, tested the header links and sure enough all was well. One thing missing is the page selection links – they don’t obey the current sorting. The page selection links had to be patched as well:
$pages .= " <a class='page-numbers prev' href='{$nr_url->urls['manage']}&p=$previous&s=$orderby&o=$order'>«</a>";
$pages .= " <a class='page-numbers' href='{$nr_url->urls['manage']}&p=$i&s=$orderby&o=$order'>$i</a>";
$pages .= " <a class='page-numbers next' href='{$nr_url->urls['manage']}&p=$next&s=$orderby&o=$order'>»</a>";
New default book management page view.
Download
Perfecto! Works great.
One last thing I thought would be useful was to reorder the columns, such that it’s “Book, Author, Status, Started, Finished, Added” instead of the default “Book, Author, Added, Started, Finished, Status”. Because frankly, I don’t care much when I added a book, I care most about its current status and when I started reading it. Once I’m done, I want to set the Finished date and move on to the next. After reordering the columns, I set the default sorting on the Started date and in descending order, as you can see in the screenshot.
Download NRR v5.1.3.2 with the sorting patch.