0

I need to order posts within a category alphabetically based on the last word in the title. I have seen a few suggestions online but none fit correctly.

I am using a custom layout for the category based on its id e.g. file named category-3.php with below code to show posts.

<?php query_posts($query_string . '&orderby=title&order=ASC');?>


            <?php 
                    if ( have_posts() ) : while ( have_posts() ) : the_post();

                        get_template_part( 'content-clients', get_post_format() );

                    endwhile; 

                     endif; ?>

So I need to organise the posts on this page alphabetically by the last word in the title.

2 Answers 2

1

I would use a wp_query.

Place this in your functions.php:

/**
 * Order posts by the last word in the post_title.
 * Activated when orderby is 'wpse_last_word'
 */
add_filter('posts_orderby', function($orderby_sql, \WP_Query $q) {
  $orderbys = $q->get('orderby');
  if (!$orderbys) {
    return;
  }
  if ($orderby_sql) {
    $orderby_sql_array = [$orderby_sql];
  }
  else {
    $orderby_sql_array = [];
  }
  if (!is_array($orderbys)) {
    $words = explode(' ', $orderbys);
    $orderbys = [];
    foreach ($words as $word) {
      $orderbys[$word] = $q->get('order');
    }
  }
  global $wpdb;
  foreach ($orderbys as $orderby => $direction) {
    if ($orderby == 'wpse_last_word') {
      if (!$direction || !in_array(strtoupper($direction), ['ASC', 'DESC'])) {
        $direction = 'DESC';
      }
      $orderby_sql_array[] = "SUBSTRING_INDEX({$wpdb->posts}.post_title, ' ', -1) $direction";
    }
  }
  return implode(', ', $orderby_sql_array);
}, 100, 2);

now you MAY be able to do this in your category-3.php ( didn't test it):

<?php query_posts($query_string . '&orderby=wpse_last_word&order=ASC');?>

        <?php 
                if ( have_posts() ) : while ( have_posts() ) : the_post();

                    get_template_part( 'content-clients', get_post_format() );

                endwhile; 

                 endif; ?>

but you could definitely use a wp_query and use these as your args: (add other args if needed)

$args = [
    'posts_per_page'   => 10,
    'post_type'        => 'post',
    'orderby'          => 'wpse_last_word',
    'order'            => 'ASC'
];

$the_query = new WP_Query( $args );
5
  • The pre_get_posts filter would be preferable to query_posts(). Commented Nov 12, 2018 at 15:52
  • thanks, I have tried with the code on category-3.php without success. Can you advise how to do this using a wp_query? I am new to wordpress.
    – ds2018
    Commented Nov 12, 2018 at 16:21
  • I don't have enough information to show the best way... Are you only doing this for posts in category 3 or will it be for all posts? Why are you using query_posts() instead of the regular query?
    – rudtek
    Commented Nov 12, 2018 at 17:18
  • It can be set to work on all pages throughout the website, it is not just restricted to the category 3 pages. No reason for using query_posts(), this is what I had initially used for the sort order but can change that.
    – ds2018
    Commented Nov 13, 2018 at 9:10
  • Do you want / need it to be loading on it's own page or would you rather it be running simply as a part of a page (as in a shortcode)?
    – rudtek
    Commented Nov 13, 2018 at 15:50
0

If you are using a custom post type perhaps this can work for you:

function my_movies_posts_orderby( $orderby, $query ) {
    if ( $query->is_main_query() && $query->is_post_type_archive( 'my-movie' ) ) {
        $orderby = "SUBSTRING_INDEX(post_title, ' ', -1)";
    }
    return $orderby;
}
add_filter( 'posts_orderby', 'my_movies_posts_orderby', 10, 2 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.