Sort Posts by Last Name Using Nate Olsen’s WP Snap Plugin for WordPress
Thursday, August 20th 2009I’ve used Nateomedia.com’s WP Snap plugin for quite awhile now, whether it was to sort through encyclopedia entries, organize archives of contributor bios, or simulate a dictionary in WordPress. On Nathan Olsen’s website, one commenter mentioned how he had managed to make WP Snap organize an archive of bios, but sorted by last, middle, and then first name. Unfortunately, the sample code the commenter provided got mangled by Nate’s comments sanitizer, so I decided to muck through the plugin myself and hack together a solution. This is a screenshot of what Nate’s plugin can do, from his website:
WP Snap Demo
I first used WP Snap on Redivider, the literary journal for Emerson College. But for Fringe Magazine, I needed to organize contributor bios by last name. And at Harvard Common Press, I needed to do the same thing with author bios and the publisher’s title list. So the first thing I did was cordon off Nate’s original WP Snap function in the plugin, so that I could still sort posts as the plugin normally does:
On line 168, change:
$nav = new wp_snap_core();
To:
if ($snapqueryarray['ordertype'] == "names") {
$nav = new wp_snap_core_names();
} else {
$nav = new wp_snap_core();
}
This allows us to make two different calls to the plugin:
// and if we want to sort posts by last, middle, and then first name
<?php if (function_exists('wp_snap')) { echo wp_snap('&ordertype=names); } ?>
// if we want to sort posts by the title normally:
<?php if (function_exists('wp_snap')) { echo wp_snap(); } ?>
Now all we need to do is install the section wp_snap_core_names() function into the plugin. Search for “$all_posts = $wpdb->get_results($request);” and insert the following code on the line below it:
for ($i=0; $i < count($all_posts); $i++) {
$name_set[$i] = preg_replace('/^(' . $exclude[1] . ')+((' . $exclude[2] . ')[\s]+)*|^(' . $exclude[2] . ')[\s]+/i', '', wp_snap_core::accents($all_posts[$i]->post_title));
}
for ($k=0; $k < count($name_set); $k++) {
$word_parts = explode(" ", $name_set[$k]);
$number_of_names = count($word_parts);
$the_name = "";
for ($x=$number_of_names; $x>=0; $x--) {
$the_name .= $word_parts[$x].' ';
}
unset($name_set[$k]);
$name_set[$k] = trim($the_name);
}
What we’re doing here is going through the array of post titles and reversing each word in the string, so that the order is last name, first name, and then middle name. This should work for any number of words in the post title.
Now search for this preg_replace, which is just below the above code:
$word_results[$i] = preg_replace('/^(' . $exclude[1] . ')+((' . $exclude[2] . ')[\s]+)*|^(' . $exclude[2] . ')[\s]+/i', '', wp_snap_core::accents($all_posts[$i]->post_title));
Replace this with:
$word_results[$i] = $name_set[$i];
Finally, search for “// Resorts $wp_snap_posttitles, taking excluded words into account” and add the following code just above that line:
for ($i=0; $i<count($all_posts); $i++) {
$word_parts = explode(" ", $all_posts[$i]->post_title);
$number_of_names = count($word_parts);
$the_name = "";
for ($x=$number_of_names; $x>=0; $x--) {
$the_name .= $word_parts[$x].' ';
}
unset($all_posts[$i]->post_title);
$all_posts[$i]->post_title = trim($the_name);
}
Okay, now the plugin is all set to display these posts sorted by last name first. When you call <?php if (function_exists('wp_snap')) { echo wp_snap('&ordertype=names); } ?> in your template (following <a>Nate’s regular instructions for using the plugin</a>), you’ll notice that when you click on a letter, you’ll only get posts where the last name begins with that letter:
C Callaway William Chau François Cullen Peter Cummings R. Brian
Great, this means the posts are actually being sorted by last name first. The only problem now is that because we altered the post titles in the loop, the names are being displayed last name first, which we don’t want. So we add a bit of code to our template to rearrange the post title back to the original order of the words in the string, so that they display first name first:
<?php if (function_exists('wp_snap')) { echo wp_snap('cat=4'); } ?>
<?php $wp_query->is_archive = true; ?>
<?php while (have_posts()) : the_post(); ?>
<?php $author_name = get_the_title(); ?>
<a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>">
<?php // we need to put the names back in the correct order
$word_parts = explode(" ", get_the_title());
$the_name = "";
$number_of_names = count($word_parts);
for ($x=$number_of_names; $x>=0; $x--) {
$the_name .= $word_parts[$x].' ';
}
echo trim($the_name); ?>
</a>
And that’s it. Now our names should display normally: William Callaway, François Chau, Peter Cullen, Brian R. Cummings.
For the sake of posterity (and laziness), you can download version 0.8.6 of WP Snap (the one I tweaked) as well as my modified plugin file below:
Original WP Snap Plugin, version 0.8.6: wp-snap.zip
Modified WP Snap Plugin: wp-snap-dquinn.zip
Enjoy.

I don't see any reason why this functionality couldn't be included in the plugin. Would you mind if I used your code? I'll include a contributor credit, of course.
Sure thing! I'm sure there are improvements to my code you could make too - I'm not a very good programmer, so feel free to hack this up so it works best for the plugin.