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 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>';
}
share|improve this question
    
To clarify, you're referring specifically to hierarchical page breadcrumb display? –  Chip Bennett Apr 5 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 Apr 6 at 11:17
add comment

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer
    
I adjusted it slightly to fit my formatting, but this did the trick in combination with my existing code. Thanks! –  Malou Apr 6 at 11:30
    
It would be helpful if you added an explanation for what the code is doing. –  Chip Bennett Apr 6 at 14:07
2  
@ChipBennett done, thanks. Hope it's enough. –  G. M. Apr 6 at 14:47
    
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 Apr 10 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... –  G. M. Apr 10 at 18:46
add comment

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.

share|improve this answer
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.