0

I have several Custom Post Types and several Categories. Within my pre_get_posts hook (in functions.php), I'm changing the chronological order for very specific Custom Post Type archive pages.

function get_custom_posts( $query ) {
    if ( ! is_admin() && $query->is_main_query() && empty($query->query_vars['suppress_filters']) ) { 
        if ( ($query->get('order') == '') && (in_array($query->get('post_type'), array( 'books', 'foo' ))) ) {
            $query->set('order','ASC');  // ascending order
        }
        if ( is_home() ) {
            return $query->set( 'post_type', array( 'post', 'books', 'foo', 'bar' ) );
        } else if ( is_search() ) {
            return $query->set( 'post_type', array( 'post', 'page', 'books', 'foo', 'bar' ) );
        } else if ( is_category() ) {
            return $query->set( 'post_type', array( 'post', 'books', 'foo', 'bar' ) );
        }   
    } 
}       
add_action( 'pre_get_posts', 'get_custom_posts' );
  • I am developing a child theme of Twenty Thirteen.

  • For Category archives, it's properly using the parent template, category.php.

  • For Custom Post Type archives, it's properly using custom templates in the child theme, archive-books.php, archive-foo.php, etc.

Questions/Issues:

1) My code is working for the Custom Post Type archive pages... they load in ascending order like I want. However, I also need ascending chronological order on Category archive pages, but only if they contain one or more posts from my specified Custom Post Types. How can I do this? I'd only like to call out the Custom Post Types in my code... I prefer not to call out specific Categories as these may occasionally change, and these category archives may contain posts from multiple Post Types.

2) When I reverse the chronological order, as in my code above, the default pagination is labeled incorrectly. i.e., the oldest post is on the top of the first page and when I scroll to the bottom, the link is labeled "Older posts" but this link really takes you to the newer posts. When chronology is changed, I was expecting the pagination to automatically follow; did I miss something simple in my code?

2 Answers 2

0

1) "need ascending chronological order on Category archive pages, but only if they contain one or more posts from my specified Custom Post Types"

I don't think this is possible; at least not practical. However, since posting the question I've setup custom taxonomies for my Custom Post Types which negates the need for this. The Custom Post Type archive pages are already sorted the way I want so since the Categories no longer contain Custom Post Types, their sorting can be handled by a simple Category sorting plugin.


2) "default pagination is labeled incorrectly. i.e., the oldest post is on the top of the first page and when I scroll to the bottom, the link is labeled 'Older posts' but this link really takes you to the newer posts."

This is handled by the theme and quite goofy IMO. See notes below*.

Twenty Thirteen uses the twentythirteen_paging_nav() function (contained in functions.php) to setup these pagination links...

function twentythirteen_paging_nav() {
    global $wp_query;

    // Don't print empty markup if there's only one page.
    if ( $wp_query->max_num_pages < 2 )
        return;
    ?>
    <nav class="navigation paging-navigation" role="navigation">
        <h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'twentythirteen' ); ?></h1>
        <div class="nav-links">

            <?php if ( get_next_posts_link() ) : ?>
            <div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">&larr;</span> Older posts', 'twentythirteen' ) ); ?></div>
            <?php endif; ?>

            <?php if ( get_previous_posts_link() ) : ?>
            <div class="nav-next"><?php previous_posts_link( __( 'Newer posts <span class="meta-nav">&rarr;</span>', 'twentythirteen' ) ); ?></div>
            <?php endif; ?>

        </div><!-- .nav-links -->
    </nav><!-- .navigation -->
    <?php
}

Look very carefully at the code above and ignore the "older/newer" labels. Within the conditional logic for the "next" link, you have the next_posts_link() function wrapped inside HTML that is labeled nav-previous. Vice-versa for the other link... the previous_posts_link() function wrapped inside nav-next. Like I said before... goofy.

My fix was simple. I copied this entire function into my child theme's functions.php file. Since the original is wrapped inside if ( ! function_exists( 'twentythirteen_paging_nav' ) ), the copy in the child theme will take precedence. Then I rearranged the function so that the next_posts_link() appears inside the .nav-next div and re-labeled to "Next page", and did the same for the previous_posts_link() function.

function twentythirteen_paging_nav() {
    global $wp_query;

    // Don't print empty markup if there's only one page.
    if ( $wp_query->max_num_pages < 2 )
        return;
    ?>
    <nav class="navigation paging-navigation" role="navigation">
        <h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'twentythirteen' ); ?></h1>
        <div class="nav-links">

            <?php if ( get_next_posts_link() ) : ?>
                  <div class="nav-next">
                     <?php next_posts_link( __( 'Next page <span class="meta-nav">&rarr;</span>', 'twentythirteen' ) ); ?>
                 </div>
            <?php endif; ?>

            <?php if ( get_previous_posts_link() ) : ?>
                <div class="nav-previous">
                    <?php previous_posts_link( __( '<span class="meta-nav">&larr;</span> Previous page', 'twentythirteen' ) ); ?>
                </div>
            <?php endif; ?>

        </div><!-- .nav-links -->
    </nav><!-- .navigation -->
    <?php
}

The final step is to tweak the CSS as Twenty Thirteen makes the "previous" link in the lower-left corner (formally called "Older posts") about 60% larger than other. I think their idea was to make the button going to the "next" page larger. Since the positions and labels are flipped, you must adjust the CSS sizes.


*Notes: In the context of the newest post being on top, the "next" page would be "older" posts. In this theme, the link to the "next" page is labeled "older posts" and it's pointing to the left signifying "back". I call it "goofy" because it will totally break down when posts are sorted in any other fashion. When oldest posts are on top, when they're sorted alphabetically, etc., the "older" label is rendered meaningless. Since it, technically, goes to the next page of the results query, it should be labeled "next" and indeed the next_posts_link() function is how it's created. However, simply re-labeling it as "next" is not good enough as it's in the lower-left corner and pointing backwards towards the left. Wrapping it with the appropriate CSS class nav-next fixes this as described in my answer above.

-1

Pagination won't work correctly, unless you set the 'paged' query var appropriately: adding the paged parameter

2
  • Thanks. Any ideas about the first part of the question?
    – Sparky
    Commented Jan 17, 2014 at 21:00
  • In the Twenty Thirteen theme, the pagination I'm talking about is handled by a function in the theme called twentythirteen_paging_nav().
    – Sparky
    Commented Feb 2, 2014 at 17:10

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.