0

I'm currently using the code below to display my breadcrumbs. Which works fine up to a point. What I want is:

Home > Level 1 > Level 2 > Level 3

What I get is:

Home > Level 1 > Level 3

It's displaying one parent, so as long as your deepest link is a Level 2 you can't tell the difference. But you know, for complex sites that's just not enough.

Suggestions as to how to adjust this code to include all parents are most welcome.

The code:

function themename_breadcrumb() {
        global $post;

        echo '<ul class="breadcrumbs">';
    if (!is_home()) {
        echo '<li><a href="';
        echo get_option('home');
        echo '">';
        echo 'Home';
        echo "</a></li>";
        if (is_category() || is_single()) {
            echo '<li>';
            the_category(' </li><li> ');
            if (is_single()) {
                echo "</li><li>";
                the_title();
                echo '</li>';
            }
        } elseif (is_page()) {
            if($post->post_parent){
                $anc = get_post_ancestors( $post->ID );
                $anc_link = get_page_link( $post->post_parent );

                foreach ( $anc as $ancestor ) {
                    $output = "<li><a href=" . $anc_link . ">" . get_the_title( $ancestor ) . "</a>";
                }

                echo $output;
                    echo '</li><li> ';
                    echo the_title();
                    echo '</li>';

                } else {
                    echo '</li><li> ';
                    echo the_title();
                    echo '</li>';
                }
            }
    }
    elseif (is_tag()) {single_tag_title();}
    elseif (is_day()) {echo"<li>Archive for "; the_time('F jS, Y'); echo'</li>';}
    elseif (is_month()) {echo"<li>Archive for "; the_time('F, Y'); echo'</li>';}
    elseif (is_year()) {echo"<li>Archive for "; the_time('Y'); echo'</li>';}
    elseif (is_author()) {echo"<li>Author Archive"; echo'</li>';}
    elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {echo "<li>Blog Archives"; echo'</li>';}
    elseif (is_search()) {echo"<li>Search Results"; echo'</li>';}
    echo '</ul>';
}
2
  • To clarify, you're referring specifically to hierarchical page breadcrumb display? Commented Apr 5, 2014 at 17:37
  • Yep, it's currently only looping 1 parent, the highest level parent. I'm taking a look at the way you do it in oenology, which is much more elaborate.
    – Malou
    Commented Apr 6, 2014 at 11:17

2 Answers 2

1

Doing same thing in more concise way:

function breadcrump_page( $post ) {
  $format = '<a href="%s" title="%s">%s</a> &gt;';    
  $anc = array_map( 'get_post', array_reverse( (array) get_post_ancestors( $post ) ) );
  $links = array_map( 'get_permalink', $anc );
  foreach ( $anc as $i => $apost ) {
    $title = apply_filters( 'the_title', $apost->post_title );
    printf( $format, $links[$i], esc_attr($title), esc_html($title) );
  }
  echo apply_filters( 'the_title', $post->post_title );
}

global $post;
if ( $post->post_parent ) breadcrump_page( $post );

WordPress has a core function get_post_ancestors that retrieve all the parent ids for hierarchical post. I called it, reverse the order becuse they are returned form direct parent to highest ancestor, and finally get all post objects and all permalinks using a couple of array_map.

Doing that, is just matter of glue all the pieces and output them.

4
  • I adjusted it slightly to fit my formatting, but this did the trick in combination with my existing code. Thanks!
    – Malou
    Commented Apr 6, 2014 at 11:30
  • It would be helpful if you added an explanation for what the code is doing. Commented Apr 6, 2014 at 14:07
  • I hope I can trouble you for a little more input to add. I haven't quite figured out the exact mechanics of looping through this function yet, so I've been struggling to add is_tax to the code. (My breadcrumbs now show and empty space on custom post types.) Suggestions are much appreciated!
    – Malou
    Commented Apr 10, 2014 at 17:06
  • @Malou the key is get an array of links. I used get_post_ancestors that return an array of post/page ids, but it can't be used for taxonomies... you can use the same mechanism, butt you have to use the proper function...
    – gmazzap
    Commented Apr 10, 2014 at 18:46
0

For hierarchical page breadcrumb navigation, here's what I do:

// Define Parent Page Hierarchy Crumbs for Child Pages
elseif ( ! is_front_page() && is_page() && $post->post_parent ) { 
    $parent_id  = $post->post_parent;
    $breadcrumbs = array();
    while ( $parent_id ) {
        $page = get_page($parent_id);
        $breadcrumbs[] = '<a href="' . get_permalink($page->ID) . '">' . get_the_title($page->ID) . '</a>';
        $parent_id  = $page->post_parent;
    }
    $breadcrumbs = array_reverse( $breadcrumbs );
    foreach ( $breadcrumbs as $crumb ) {
        $hierarchy .= $delimiter . $crumb;
    }
    $hierarchy = $hierarchy . $delimiter;
    // Note: get_the_title() is filtered to output a
    // default title if none is specified
    $currentLocation = get_the_title(); 
} 

Note that I define $delimiter earlier in the function. The meat of what you're looking for is here.

First, get the ID of the current page's parent page:

$parent_id  = $post->post_parent;

Next, set up an array to hold the hierarchical parent page links:

$breadcrumbs = array();

Next, loop through each parent page, until there aren't any more, and add the constructed links to the array:

// Start looping
while ( $parent_id ) {
    // Get the page object
    $page = get_page($parent_id);
    // Build the HTML link
    $breadcrumbs[] = '<a href="' . get_permalink($page->ID) . '">' . get_the_title($page->ID) . '</a>';
    // Set the parent ID to the next parent,
    // to continue the loop.
    // Eventually, this will return 0,
    // at which time, the looping will end
    $parent_id  = $page->post_parent;
}

Finally, put the HTML links in the correct order:

$breadcrumbs = array_reverse( $breadcrumbs );

Now, you can do whatever you want with the $breadcrumbs array.

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.