Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm working on a Custom Post Type sorted on a Custom Field. No problem when I list out the posts. But when I go to the single post page for one of these, I want the Prev and Next navigation links to take us to the prev/next posts in the sort order dictated by the Custom Field. By default, WP orders them by post date.

Code for sorting list:

    // shortcodes
    // lor_list of letters: Lists all letters of reference in a table format
    add_shortcode('lor_list', 'aaaConsultant_shortcode_lor_list');

    function aaaConsultant_shortcode_lor_list() {
        global $wp_query;

        $oWP = new wp_query(array(
            'post_type' => 'letters_of_ref'
            , 'orderby' => 'meta_value'
            , 'meta_key' => 'aaaConsultant_dateofletter'
        ));

        $out = '<div id="lor_list_container">' . "\n";
        if (!$oWP->found_posts) {
            $out .= '<p>d\'Oh! We don\'t have any Letters of Reference yet.</p>' . "\n";
        } else {
            while ($oWP->have_posts()) {
                $oWP->the_post();
                $out .= '<a href="' . get_permalink() . '">' . get_the_title( $oWP->post->ID ) . '</a>' . "<br>\n";
            }
        }
        $out .= '</div> <!-- END #lor_list_container -->' . "\n";

        wp_reset_postdata();
        return $out;
    }

How do I do that?

Thanks for your help.

share|improve this question
    
Please post your code both for sorting and for generating the navigation links. –  s_ha_dum Apr 21 '13 at 17:16
    
@s_ha_dum I've added the list sort code. The prev/next code on the template, at this point, isn't worth posting: just a call to previous_posts_link(). –  NotoriousWebmaster Apr 21 '13 at 17:41
    
Found this Q/A with some interesting info I haven't quite figured out yet because it's not a full function: Question and Answer –  NotoriousWebmaster Apr 21 '13 at 17:48
add comment

1 Answer

up vote 1 down vote accepted

For previous and next post links to work, you need to hook on to the get_*_post_* filters and modify the query to actually sort the posts using your custom field. I hope the code below will work for you.

For Previous post link

add_filter('get_previous_post_join', 'wpse96670_get_previous_post_join_custom_sort');
add_filter('get_previous_post_where', 'wpse96670_get_previous_post_where_custom_sort');
add_filter('get_previous_post_sort', 'wpse96670_get_previous_post_sort_custom_sort');
function wpse96670_get_previous_post_join_custom_sort($join) {
    global $wpdb;
    return "INNER JOIN {$wpdb->prefix}postmeta ON (p.ID = {$wpdb->prefix}postmeta.post_id)";
}
function wpse96670_get_previous_post_where_custom_sort($where) {
    global $wpdb, $post;
    $meta_value = get_post_meta($post->ID, 'aaaConsultant_dateofletter', true);
    return "WHERE 1=1  AND p.post_type = 'letters_of_ref' AND p.post_status = 'publish' AND {$wpdb->prefix}postmeta.meta_key = 'aaaConsultant_dateofletter' AND {$wpdb->prefix}postmeta.meta_value < '{$meta_value}'";
}
function wpse96670_get_previous_post_sort_custom_sort($sort) {
    global $wpdb;
    return "ORDER BY {$wpdb->prefix}postmeta.meta_value DESC LIMIT 1";
}

For next post link

add_filter('get_next_post_join', 'wpse96670_get_next_post_join_custom_sort');
add_filter('get_next_post_where', 'wpse96670_get_next_post_where_custom_sort');
add_filter('get_next_post_sort', 'wpse96670_get_next_post_sort_custom_sort');
function wpse96670_get_next_post_join_custom_sort($join) {
    global $wpdb;
    return "INNER JOIN {$wpdb->prefix}postmeta ON (p.ID = {$wpdb->prefix}postmeta.post_id)";
}
function wpse96670_get_next_post_where_custom_sort($where) {
    global $wpdb, $post;
    $meta_value = get_post_meta($post->ID, 'aaaConsultant_dateofletter', true);
    return "WHERE 1=1  AND p.post_type = 'letters_of_ref' AND p.post_status = 'publish' AND {$wpdb->prefix}postmeta.meta_key = 'aaaConsultant_dateofletter' AND {$wpdb->prefix}postmeta.meta_value > '{$meta_value}'";
}
function wpse96670_get_next_post_sort_custom_sort($sort) {
    global $wpdb;
    return "ORDER BY {$wpdb->prefix}postmeta.meta_value ASC LIMIT 1";
}

Then you need some code in the template:

    <?php 
        $oNext = get_adjacent_post(false, '', true);
        $oPrev = get_adjacent_post(false, '', false);

        if ($oPrev || $oNext) {
            echo '<div id="lor_nav">' . "\n";
        }
        if ($oPrev) {
            echo '<div class="prevlink"><a href="' . get_permalink($oPrev->ID) . '"> &laquo; ' . $oPrev->post_title . '</a></div>' . "\n";
        }
        if ($oNext) {
            echo '<div class="nextlink"><a href="' . get_permalink($oNext->ID) . '">' . $oNext->post_title . ' &raquo;</a></div>' . "\n";
        }
        if ($oPrev || $oNext) {
            echo '</div><div class="clear"></div>' . "\n";
        }
?>

Let me know if you need any clarification.

share|improve this answer
    
Thank you. This makes it a lot clearer to me. It looks like a lot of moving parts. Perhaps it would be easier to make call directly myself, without the intervening filters. (Whoa. Just realized you coded this for my plugin. Mighty neighbourly of you.) I'm going to try this right away. –  NotoriousWebmaster Apr 22 '13 at 2:30
    
Thanks @HameedullahKhan. It needed a couple of tweaks (quotes around the date comparison, which I've added here), but it worked like a charm. Also, needed to show the template part, so I put that in too. Feel free to edit as needed. Thanks again. This was weighing heavily on me. –  NotoriousWebmaster Apr 22 '13 at 3:17
    
Glad you could use it for your work. :) –  Hameedullah Khan Apr 22 '13 at 8:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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