Anyone have an idea why this happens, or how to fix it?
Theme in use is a child of XRAY v1.4.3 in WordPress 4.1. The only new file is a copy of category.php which has been edited to make only one pass for The Loop then show the previous_post_link(). The modified code is shown at the bottom of this article.
In the WordPress Codex Function Reference for previous_post_link() it says that previous_post_link() is called to provide a link to the prior post (chronologically). It says that the search can be limited to only posts in the same category as the present post by specifying TRUE for $in_same_term and the part of the taxonomy to keep the same in $taxonomy, which defaults to ‘category’.
<?php previous_post_link( $format, $link, $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ); ?>
In other words, if you are searching for posts in the category “The Great Pudding Explosion”, and after it presents the first post (the most chronologically recent post), then the link returned by
<?php previous_post_link( '«-- %link',' Prior ',TRUE); ?>
will be restricted to the same category as the first post returned, and be the next most recent post — the post chronologically immediately before the post being displayed and in the same category.
I do not see how what I have is different from what is shown as the example in the Codex:
Text As Link, Without Post Title, Within Same Category[edit]
Displays custom text as link to the previous post within the same category as the current post. Post title is not included here. “Previous in category” is the custom text, which can be changed to fit your requirements.
<?php previous_post_link('%link', 'Previous in category', TRUE); ?>
This is all fine in theory but it does not seem to work because it is loosing the proper URL and subsequent posts are no longer restricted to the category “The Great Pudding Explosion”.
If I ask for a post from the archive it properly fetches the most recent post with the requested category: the URL of the page is
http://website.com/category/story/tgpe/
where category “tgpe” is under the parent category “story”. Clicking previous_post_link() does go to the previous post, however the new URL is
http://website.com/tgpe-part-3-big-boom/
Notice that WordPress is no longer caring about category. Clicking the result of previous_post_link() again displays the next most recent post, from any category, considering date only, not restricted to the original category.
The relevant code in category.php in the xray child folder is:
<?php get_header(); ?> <!-- Main Content --> <div class="container" id="main-container"> <div class="row"> <?php get_exray_primary_sidebar(); ?> <?php get_exray_content_html_opening(); ?> <?php Exray::load_breadcrumb(); ?> <div class="content" role="main"> <?php if(have_posts()) : ?> <div class="top-content" style=""> <h5><?php single_cat_title( __('More from: ', 'exray-framework'), true ); ?></h5> <hr class="content-separator"> </div> <?php the_post(); ?> <?php get_template_part( 'content', get_post_format() ); ?> <?php else : ?> <h1><?php _e("No post were Found", "exray-framework") ?></h1> <?php endif; ?> <p><?php previous_post_link( '<span style="font-size:120%;font-weight:bold ;">«-- %link</span>',' Prior ',TRUE); ?> | <?php next_post_link( '<span style="font-size:120%;font-weight:bold;">%link --»</span>',' Next ',TRUE); ?></p> <!-- End nav-below --> </div> <!-- end content --> </div> <!-- end span6 main --> <div id="primary" class="widget-area span3 main-sidebar" role="complementary"> <?php get_sidebar('sidebar'); ?> </div> <!-- end span3 primary left-sidebar --> <?php get_exray_secondary_sidebar(); ?> </div> <!--End row --> </div> <!-- End Container --> <!-- End Main Content --> <?php get_footer(); ?>
Tracking it down, here is the problem.
The call to previous_post_link() eventually calls get_adjacent_post() in /wp-includes/link-template.php.
Going into function get_adjacent_post() the $taxonomy has the correct value, ‘category’, HOWEVER it calls get_adjacent_post_link() to find the next/prior post;
The URL returned does not include the necessary http://website.com/category/….. but looses that /category/ part that is needed in the URL for it to continue to work.
The get_adjacent_post_link() code (debugging comments added):
/** This filter is documented in wp-includes/post-template.php */ $title = apply_filters( 'the_title', $title, $post->ID ); $date = mysql2date( get_option( 'date_format' ), $post->post_date ); $rel = $previous ? 'prev' : 'next'; $string = '<a href="' . get_permalink( $post ) . '" rel="'.$rel.'">'; echo "\n<!--\n inside function get_adjacent_post_link line ".__LINE__."\n\$string='$string'\n-->\n"; $inlink = str_replace( '%title', $title, $link ); $inlink = str_replace( '%date', $date, $inlink ); $inlink = $string . $inlink . '</a>'; echo "\n<!--\n inside function get_adjacent_post_link line ".__LINE__."\n\$inlink='$inlink'\n-->\n"; $output = str_replace( '%link', $inlink, $format ); echo "\n<!--\n inside function get_adjacent_post_link line ".__LINE__."\n\$output='$output'\n-->\n";
Produces html code:
<!-- inside function get_adjacent_post line 1569 $query='SELECT p.ID FROM wp_posts AS p INNER JOIN wp_term_relationships AS tr ON p.ID = tr.object_id INNER JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE p.post_date < '2012-01-09 06:57:40' AND p.post_type = 'post' AND p.post_status = 'publish' AND tt.taxonomy = 'category' AND tt.term_id IN (87) ORDER BY p.post_date DESC LIMIT 1' -->
<!-- inside function get_adjacent_post_link line 1859 $string='<a href="http://jdnash.org/tgpe-part-3-big-boom/" rel="prev">' -->
<!-- inside function get_adjacent_post_link line 1865 $inlink='<a href="http://jdnash.org/tgpe-part-3-big-boom/" rel="prev"> Prior </a>' -->
<!-- inside function get_adjacent_post_link line 1868 $output='<span style="font-size:120%;font-weight:bold;">«-- <a href="http://jdnash.org/tgpe-part-3-big-boom/" rel="prev"> Prior </a></span>' --> <span style="font-size:120%;font-weight:bold;">«-- <a href="http://jdnash.org/tgpe-part-3-big-boom/" rel="prev"> Prior </a></span> |
So after clicking the link to go to the previous post in the same category, the result to make the link the next time looks like
<!-- inside function get_adjacent_post $in_same_term='' $excluded_terms='' $previous='1' $taxonomy='category' -->
<!-- inside function get_adjacent_post line 1525 $adjacent='previous' $op='<' $order='DESC' -->
<!-- inside function get_adjacent_post line 1569 $query='SELECT p.ID FROM wp_posts AS p WHERE p.post_date < '2011-12-18 15:02:24' AND p.post_type = 'post' AND p.post_status = 'publish' ORDER BY p.post_date DESC LIMIT 1' --> <link rel='prev' title='Love' href='http://jdnash.org/love/' />
Which of course is wrong. The post with the slug "love" is not even in the category "The Great Pudding Explosion"