WordPress - Making Yoast Breadcrumbs Behave Like A Good Boy

Submitted by Kenny on Sun, 04/04/2010 - 00:38
Category

I mentioned in a recent post (okay, very recent) that Yoast Breadcrumbs needed some tweaking to get it to behave the way I wanted it to. This post will outline the changes that I made to my theme to get Yoast Breadcrumbs to cooperate.

First, check to see if the plugin is installed and enabled. If it is, let's get the output from the plugin:

<?php
    if(function_exists('yoast_breadcrumb'))
    {
        $breadcrumbs = yoast_breadcrumb("", "", false);
        ...
    } // end if test
?>

The first issue that I ran into is that even though I had Separator between breadcrumbs in the configuration set to &amp;raquo;, it was still throwing out » (rather than the HTML entity). To force that, I added this line:

$breadcrumbs = str_replace("»", "&raquo;", $breadcrumbs);

Since I was using a static page as my homepage and since I had all my breadcrumbs prefaced with a hyperlink to KennyCarlile.com (linked to root), I didn't want it to appear as KennyCarlile.com » About. That would just be silly. But, I wanted that root link to preface all my other pages, so I just wanted to hide the » About part.

        if(is_front_page())
        {
            echo '<a href="/">' . $breadcrumbs .
                '</a> &raquo; ' .
                '<strong>About</strong>';
        } // end if test

Now we get into the real voodoo and black magic. All other cases should be for pages where we want to display the full breadcrumb. For some reason, it was adding multiple links on occasion, depending on where it was in the site hierarchy. To handle that, I split the breadcrumb into an array, then looked at each position in the array and compared it to the next one to see if they are the same. If they are different, add it to a new array. If they are the same, ignore it and continue on.

        else
        {
            // split breadcrumb string into array
            $linksArr = split('&raquo;', $breadcrumbs);
            $newLinksArr = array(); // new links array
            $lastIndex = count($linksArr) - 1;

            // look through the links
            for($i = 0; $i <= $lastIndex; $i++)
            {
                // if 2 in a row are NOT the same...
                if(trim($linksArr[$i]) != trim($linksArr[$i + 1]))
                {
                    // ...add to the new array
                    $newLinksArr[] = $linksArr[$i];
                } // end if test
            } // end for loop

Okay, no more duplicate breadcrumb links, but now it's still linking the final breadcrumb. I want to display the page that I'm on in the breadcrumb, but it doesn't need to be a link. Why link to yourself, right? Here's some real voodoo. This is your cue to take off running if you hate regular expressions. :)

            // get the new array size
            $lastIndex = count($newLinksArr) - 1;

            // looking to extract the text from a hyperlink,
            // replace it with the same word in bold
            $pattern = '/(.*>)([^<]*)(<.*)/';
            $replace = '<strong>$2</strong>';
            $newLinksArr[$lastIndex] = preg_replace($pattern,
                                            $replace,
                                            $newLinksArr[$lastIndex]);

Cool, no more link for the page that we are on. Now we just need to turn that array back into a string and print that string to the output stream and we're done!

            // return links array to string
            $breadcrumbs = implode(" &raquo; ", $newLinksArr);    

            echo $breadcrumbs;
        } // end else test
    } // end if test
?>

That's how I solved the limitations of the Yoast Breadcrumbs plugin. I should say that I'm very impressed by what Yoast was able to do, but it just wasn't quite what I needed. I'm sure there are plenty of other ways to do this, possibly easier ones too, but this is my solution.

Here's the full code that I added to my theme to handle the breadcrumbs correctly:

<?php
    if(function_exists('yoast_breadcrumb'))
    {
        $breadcrumbs = yoast_breadcrumb("", "", false);
        $breadcrumbs = str_replace("»", "&raquo;", $breadcrumbs);

        if(is_front_page())
        {
            echo '<a href="/">' . $breadcrumbs .
                '</a> &raquo; ' .
                '<strong>About</strong>';
        } // end if test
        else
        {
            // split breadcrumb string into array
            $linksArr = split('&raquo;', $breadcrumbs);
            $newLinksArr = array(); // new links array
            $lastIndex = count($linksArr) - 1;

            // look through the links
            for($i = 0; $i <= $lastIndex; $i++)
            {
                // if 2 in a row are NOT the same...
                if(trim($linksArr[$i]) != trim($linksArr[$i + 1]))
                {
                    // ...add to the new array
                    $newLinksArr[] = $linksArr[$i];
                } // end if test
            } // end for loop

            // get the new array size
            $lastIndex = count($newLinksArr) - 1;

            // looking to extract the text from a hyperlink,
            // replace it with the same word in bold
            $pattern = '/(.*>)([^<]*)(<.*)/';
            $replace = '<strong>$2</strong>';
            $newLinksArr[$lastIndex] = preg_replace($pattern,
                                            $replace,
                                            $newLinksArr[$lastIndex]);

            // return links array to string
            $breadcrumbs = implode(" &raquo; ", $newLinksArr);    

            echo $breadcrumbs;
        } // end else test
    } // end if test
?>