posts order by title second word

This is a common question, i haven’t been able to find a straightforward answer to.
I want to generate a list of a custom post type titles. im using 'orderby' => 'title' to have them display alphabetically. The titles are names and last names and i want to sort by the last name. I know i could create meta fields with seperated first and last names and order by the last name field. But i’d really like to see if there is no good method to explode the 'title' and pass the second word in to `orderby’.

This is the basic code:

<?php
// Get the 'Actors' post type

$args = array(
'post_type' => 'actors',
'orderby' => 'title',
'order' => 'ASC',
'nopaging' => true,
'cache_results' => false,
'update_post_meta_cache' => false
);
$loop = new WP_Query($args);

while($loop->have_posts()): $loop->the_post();
echo '<li><img src="' . get_post_meta(get_the_ID(),'_dtm_small_image', [0]) . '"><span>' . get_the_title() . '</span></li>';
endwhile;
wp_reset_query();
?> 

Iv’e tried to:

$gettitle = get_the_title();
$lastname = explode(" ", $gettitle);

and then change to 'orderby' => $lastname[1], . but it doesnt work.
Is there no GOOD way to use the second word in the title to sort posts?

1 Answer
1

The simplest method may be to just save titles as last name / first name, then they will naturally sort. You can then reverse the title when you output it in the template.

Your attempt to modify the orderby query var is fundamentally flawed. Order is created by MySQL, which doesn’t understand PHP, and can’t be modified after the query has happened.

If the results are ever to be paginated, the order has to be done via the query, which will require modification of the raw SQL sent to the database via filters.

If the results are not paginated, you can sort the posts manually with PHP’s usort:

$loop = new WP_Query( array(
    'posts_per_page' => -1,
    'post_type' => 'actors'
) );

// sort function
function wpd_last_name_sort( $a, $b ) {
    $a_last = end(explode(' ', $a->post_title));
    $b_last = end(explode(' ', $b->post_title));
    return strcasecmp( $a_last, $b_last );
}

// sort posts
usort( $loop->posts, 'wpd_last_name_sort' );

// set post object to first post in sorted list
$loop->post = $loop->posts[0];

// run the loop...

You probably also want to consider the case where names are more than just two words. I would personally make the titles last name, first name and let MySQL do the work.

Leave a Comment