Is it possible to get a Previous/Next Taxonomy term archive URL?

I have a custom post type called shows and taxonomy called podcast. Using taxonomy-podcast.php, I having hard time finding a function that will generate next/previous Term URL Archive.

For Example:

URL: url.com/podcast/example-term-2

Example Term 2

post 1,post 2,post 3

Desired output

< Previous Term(url.com/podcast/example-term-1)    .   . . . . | . . . . .     Next Term(url.com/podcast/example-term-3)>

2 Answers
2

It is quite possible to achieve this. What we need to do is

  • Get all the terms sorted by slug (or any other field desired) associated with our taxonomy

  • Get the current term object

  • Determine where in the array our current term is

  • Get the two adjacent terms (if any)

  • Build the links to those term pages

THE FUNCTION

I have written a function to take care of this. It ids always important to keep business logic out of templates. Templates should only know function names and not the entire function. This way, you keep your templates clean and maintainable

The function does require a minimum of PHP 5.4 and covers the basics, it is up to you to adjust it to your needs

function get_tax_navigation( $taxonomy = 'category' ) 
{
    // Make sure we are on a taxonomy term/category/tag archive page, if not, bail
    if ( 'category' === $taxonomy ) {
        if ( !is_category() )
            return false;
    } elseif ( 'post_tag' === $taxonomy ) {
        if ( !is_tag() )
            return false;
    } else {
        if ( !is_tax( $taxonomy ) )
            return false;
    }

    // Make sure the taxonomy is valid and sanitize the taxonomy
    if (    'category' !== $taxonomy 
         || 'post_tag' !== $taxonomy
    ) {
        $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
        if ( !$taxonomy )
            return false;

        if ( !taxonomy_exists( $taxonomy ) )
            return false;
    }

    // Get the current term object
    $current_term = get_term( $GLOBALS['wp_the_query']->get_queried_object() );

    // Get all the terms ordered by slug 
    $terms = get_terms( $taxonomy, ['orderby' => 'slug'] );

    // Make sure we have terms before we continue
    if ( !$terms ) 
        return false;

    // Because empty terms stuffs around with array keys, lets reset them
    $terms = array_values( $terms );

    // Lets get all the term id's from the array of term objects
    $term_ids = wp_list_pluck( $terms, 'term_id' );

    /**
     * We now need to locate the position of the current term amongs the $term_ids array. \
     * This way, we can now know which terms are adjacent to the current one
     */
    $current_term_position = array_search( $current_term->term_id, $term_ids );

    // Set default variables to hold the next and previous terms
    $previous_term = '';
    $next_term     = '';

    // Get the previous term
    if ( 0 !== $current_term_position ) 
        $previous_term = $terms[$current_term_position - 1];

    // Get the next term
    if ( intval( count( $term_ids ) - 1 ) !== $current_term_position ) 
        $next_term = $terms[$current_term_position + 1];

    $link = [];
    // Build the links
    if ( $previous_term ) 
        $link[] = 'Previous Term: <a href="' . esc_url( get_term_link( $previous_term ) ) . '">' . $previous_term->name . '</a>';

    if ( $next_term ) 
        $link[] = 'Next Term: <a href="' . esc_url( get_term_link( $next_term ) ) . '">' . $next_term->name . '</a>';

    return implode( ' ...|... ', $link );
}

USAGE

You can now just use the function where needed as follow:

echo get_tax_navigation( 'podcast' );

EDIT – from comments

Just two questions: (1)When we are at the last term, can we still make the Next Term: (URL to the First term) and vise versa? Basically an infinite term loop. (2)For theming purposes, how can I use this function to output NEXT and PREVIOUS urls individually? (eg. get_tax_navigation( ‘podcast’, ‘previous’ ) and get_tax_navigation( ‘podcast’, ‘next’ )

  1. When we are on the last of first term, all we need to do is either grab the first or last term depending on where we at. Obviously, when we are on the laste term, we will grab the first one, and vica-versa

  2. We can introduce a $direction parameter which accepts three values, an empty string, previous or next

Here is an example of what you can do. You can adjust it from here to suite your needs

function get_tax_navigation( $taxonomy = 'category', $direction = '' ) 
{
    // Make sure we are on a taxonomy term/category/tag archive page, if not, bail
    if ( 'category' === $taxonomy ) {
        if ( !is_category() )
            return false;
    } elseif ( 'post_tag' === $taxonomy ) {
        if ( !is_tag() )
            return false;
    } else {
        if ( !is_tax( $taxonomy ) )
            return false;
    }

    // Make sure the taxonomy is valid and sanitize the taxonomy
    if (    'category' !== $taxonomy 
         || 'post_tag' !== $taxonomy
    ) {
        $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
        if ( !$taxonomy )
            return false;

        if ( !taxonomy_exists( $taxonomy ) )
            return false;
    }

    // Get the current term object
    $current_term = get_term( $GLOBALS['wp_the_query']->get_queried_object() );

    // Get all the terms ordered by slug 
    $terms = get_terms( $taxonomy, ['orderby' => 'slug'] );

    // Make sure we have terms before we continue
    if ( !$terms ) 
        return false;

    // Because empty terms stuffs around with array keys, lets reset them
    $terms = array_values( $terms );

    // Lets get all the term id's from the array of term objects
    $term_ids = wp_list_pluck( $terms, 'term_id' );

    /**
     * We now need to locate the position of the current term amongs the $term_ids array. \
     * This way, we can now know which terms are adjacent to the current one
     */
    $current_term_position = array_search( $current_term->term_id, $term_ids );

    // Set default variables to hold the next and previous terms
    $previous_term = '';
    $next_term     = '';

    // Get the previous term
    if (    'previous' === $direction 
         || !$direction
    ) {
        if ( 0 === $current_term_position ) {
            $previous_term = $terms[intval( count( $term_ids ) - 1 )];
        } else {
            $previous_term = $terms[$current_term_position - 1];
        }
    }

    // Get the next term
    if (    'next' === $direction
         || !$direction
    ) {
        if ( intval( count( $term_ids ) - 1 ) === $current_term_position ) {
            $next_term = $terms[0];
        } else {
            $next_term = $terms[$current_term_position + 1];
        }
    }

    $link = [];
    // Build the links
    if ( $previous_term ) 
        $link[] = 'Previous Term: <a href="' . esc_url( get_term_link( $previous_term ) ) . '">' . $previous_term->name . '</a>';

    if ( $next_term ) 
        $link[] = 'Next Term: <a href="' . esc_url( get_term_link( $next_term ) ) . '">' . $next_term->name . '</a>';

    return implode( ' ...|... ', $link );
}

You can use the code in three different ways

  • echo get_tax_navigation( 'podcast' ); to display next and previous terms

  • echo get_tax_navigation( 'podcast', 'previous' ); to display only the previous term

  • echo get_tax_navigation( 'podcast', 'next' ); to display only the next term

Leave a Comment