Wordpress: previous_post_link / next_post_link by alphabetical order?
Asked Answered
R

2

6

I'm developing a wordpress website with custom posts which are ordered alphabetically in the loop.

<!-- THE ARGS -->
<?php global $query_string;
$args = wp_parse_args($query_string);
$args = array(
    'post_type' => 'custom_post',
    'orderby' => 'title',
    'order' => 'ASC',
    'posts_per_page' => -1,
    ); ?>

<!--  THE LOOP -->
<?php $wp_query = new WP_Query( $args ); ?>
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>

Nothing fancy there, just a normal loop.

When I open a post, in its page I have the usual previous_post_link and next_post_link so I can navigate through posts. However, this is done by chronological order of the posts, and I wish to do so by the same alphabetical order as I used in the loop, of course. Any help on this matter would be very appreciated. Thanks in advance!

Roslynrosmarin answered 29/3, 2012 at 12:11 Comment(1)
That plugin hasn't been updated in years, not sure if it still works. In case it doesn't, [I came up with a solution][1] that can be added to your functions.php. Hope it helps! [1]: wordpress.stackexchange.com/questions/166932/…Grantland
E
6

It looks like this plug-in does what you're after, e.g.:

<ul class="pager">
        <?php previous_post_link_plus( array('order_by' => 'post_title') ); ?>
        <?php next_post_link_plus( array('order_by' => 'post_title') ); ?>
</ul>
Eject answered 15/6, 2012 at 19:59 Comment(1)
This plugin hasn't been updated in a couple of years, but it still works great!!! Someone should just test it again so it can go back to the install-able options in the wp admin. I had to re-upload it from the wp site.Greenbelt
C
5

You can do this by using filters in the get_adjacent_post function.

In your functions.php file, add:

function mytheme_previous_post_orderby_name($orderby){
    return "ORDER BY p.post_title DESC LIMIT 1";
}
function mytheme_previous_post_where_name(){
    global $post, $wpdb;
    return $wpdb->prepare( "WHERE p.post_title < %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}
function mytheme_next_post_orderby_name($orderby){
    return "ORDER BY p.post_title ASC LIMIT 1";
}
function mytheme_next_post_where_name(){
    global $post, $wpdb;
    return $wpdb->prepare( "WHERE p.post_title > %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}

Then in your single.php page add the filters before you call the previous/next posts link functions:

add_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10, 1);
add_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10, 1);

add_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
add_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);

the_post_navigation();

remove_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10);
remove_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10);
remove_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
remove_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);

If you want to check for your specific post_type, you can add an if around the adding filter section:

if($post->post_type == 'my_custom_post_type'){
    add_filter(...);
    the_post_navigation();
    remove_filter(...);
}

or, you can just use a post_type specific single.php file!

This worked great for me, but there may be some limitations if you are planning on combining this with posts in the same term...

Craigie answered 18/9, 2015 at 14:19 Comment(4)
Danbrellis's answer has a missing apostrophe. I can't comment as this is my first account and don't have enough rep to comment. remove_filter('get_previous_post_sort', mytheme_previous_post_orderby_name', 10); Should be remove_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10); (however even with that fix, I can't get this working)Electroencephalograph
plumbinator- thanks for catching that. are you getting close? I'm happy to take a look if you've got some sample code.Craigie
the OR p.post_status = 'private' should only apply to logged in users, no?Andromeda
This doesn't allow for excluded terms.Catamount

© 2022 - 2024 — McMap. All rights reserved.