amitabhaghosh197
11/17/2014 - 9:17 AM

Breadcrumbs for Wordpress Templates

Breadcrumbs for Wordpress Templates

<?php
/**
 * Generates a breadcrumb for WordPress
 *
 * This function will generate a very customizable breadcrumb
 * for WordPress. It supports all kind of content (pages, posts,
 * archives, CPT...).
 *
 * @author 		Julien Liabeuf <julien@liabeuf.fr> 
 * @copyright 	2013 ThemeAvenue
 * @package 	ThemeAvenue Framework
 * @param 		(array) $args Breadcrumb parameters
 * @since 		3.0
 */
function tav_breadcrumbs( $args = array() ) {

	global $post, $wp_query;
	
	/* Prepare default arguments */
	$defaults = array(
		'front_page_label' 			=> __( 'Home', 'tav' ),
		'home_page_label' 			=> __( 'Blog', 'tav' ),
		'search_results_label' 		=> __( 'Search', 'tav' ),
		'page_404_label' 			=> __( 'Not Found', 'tav' ),
		'show_current_page' 		=> true,
		'link_current_page' 		=> false,
		'show_on_front' 			=> false,
		'show_on_home' 				=> true,
		'link_on_home' 				=> true,
		'container' 				=> 'div',
		'container_id' 				=> '',
		'container_class' 			=> '',
		'container_attr' 			=> '',
		'home_url'					=> home_url(),
		'item_before'				=> '',
		'item_after' 				=> '',
		'home_before'				=> false,	// If false, item_before will be used instead
		'home_after' 				=> false,	// If false, item_after will be used instead
		'link_attr' 				=> '',
		'delimiter' 				=> ' / '
	);

	/**
	 * Let's merge the default settings
	 * with the user defined ones and return
	 * each option in a variable.
	 */
	extract(
		shortcode_atts(
			$defaults,
			$args
		)
	);

	$open 	= '';		// Breadcrumb opening tag
	$close 	= ''; 		// Breadcrumb closing tag
	$items 	= array(); 	// We will store the items to be imploded later
	$first 	= '';		// First item label
	$home_before = !$home_before ? $item_before : $home_before;
	$home_after  = !$home_after ? $item_after : $home_after;

	/**
	 * We identify which is the homepage.
	 */
	$home = get_option( 'page_on_front', false );

	/**
	 * If the current page is the front page
	 * and breadcrumb is hidden on this page,
	 * we return nothing.
	 */
	if( is_front_page() && !$show_on_front ) {
		return;
	}

	if( is_home() && !$show_on_home ) {
		return;
	}

	/* Open the breadcrumbs container */
	$open .= '<' . $container;

	/* Add the container ID if defined */
	if( '' != $container_id ) {
		$open .= ' id="' . $container_id . '"';
	}

	/* Add the container class if defined */
	if( '' != $container_class ) {
		$open .= ' class="' . $container_class . '"';
	}

	/* Then we close the opening tag */
	$open .= '>';

	/* Preapare the closing tag. Easy! */
	$close .= '</' . $container . '>';

	/**
	 * Now we need to prepare the first
	 * item which will depend on the page on front
	 * we identified earlier as $home
	 */
	$first = ( $home ) ? $front_page_label : $home_page_label;
	
	/* If the link must be displayed on the first item we add it now */
	if( $link_on_home ) {
		$first = '<a href="' . $home_url . '" class="home" ' . $link_attr . '>' . $first . '</a>';
	}

	/* Add the before and after elements to first item */
	$first = $home_before . $first . $home_after;

	/* The first item is now ready, it's time to add it to the items list */
	array_push( $items, $first );

	/**
	 * Let's go through the items now...
	 */
	if( is_archive() ) {

		if( is_tax() ) {

			if( isset( $wp_query->queried_object ) ) {

				$item = $wp_query->queried_object->name;
				$slug = $wp_query->queried_object->slug;

				/* Get item label to display */
				$label = apply_filters( "tav_bc_label_$slug", $wp_query->queried_object->name );

				if( $link_current_page ) {
					$item = '<a href="' . get_term_link( $wp_query->queried_object ) . '" ' . $link_attr . '>' . $label . '</a>';
				}

				$parent_tax   = $wp_query->queried_object->parent; 		// Get parent ID
				$taxonomy     = $wp_query->queried_object->taxonomy; 	// Get taxonomy
				$parent_label = array(); 								// Prepare parents array

				/* Iterate through parent terms */
				for( $ptax = $parent_tax; $ptax != 0; $ptax = $parent_tax ) {

					$parent_object  = get_term( $parent_tax, $taxonomy );
					$parent_slug 	= $parent_object->slug;
					$label			= apply_filters( "tav_bc_label_$parent_slug", $parent_object->name );
					$parent_tax 	= $parent_object->parent;
					$parent_label[]	= array( 'object' => $parent_object, 'label' => $label );

				}		

			}

		} elseif( is_post_type_archive() ) {

			if( isset( $wp_query->queried_object ) ) {

				$item  = $wp_query->queried_object->label;
				$slug  = $wp_query->queried_object->name;
				$label = apply_filters( "tav_bc_label_$slug", $wp_query->queried_object->label );

				if( $link_current_page ) {
					$item = '<a href="' . get_post_type_archive_link( $wp_query->queried_object->name ) . '" ' . $link_attr . '>' . $label . '</a>';
				}

			}

		}

	} elseif( is_single() ) {

		$item 		= esc_html( $post->post_title );
		$cats 		= get_the_category( $post->ID );
		$family 	= array();
		$highest 	= 0;
		$keep 		= false;

		/* If this post has categorie(s) */
		if( !empty( $cats ) ) {

			foreach( $cats as $key => $cat ) {

				$tax     = $cat->taxonomy;
				$curr_id = $cat->term_id;
				$parents = array();

				while ( $cat->parent != 0 ) {
					$cat       = get_term( $cat->parent, $tax );
					$parents[] = $cat;
				}

				// $parents = array_reverse( $parents );

				$family[$curr_id] = $parents;
			}

			if( is_array( $family ) && !empty( $family ) ) {
			
				foreach( $family as $ct => $dat ) {

					$count = count( $dat );

					if( $count > $highest ) {
						$highest 	= $count;
						$keep 		= $ct;
					}
				}

			}

			if( is_array( $family[$keep] ) && !empty( $family[$keep] ) ) {

				foreach( $family[$keep] as $categorie => $object ) {

					$slug 			= $object->slug;
					$label 			= apply_filters( "tav_bc_label_$slug", $object->name );
					$parent_label[] = array( 'object' => $object, 'label' => $label );

				}

			}

		}

		/* Now let's check if the post is a custom post type */
		if( !in_array( $post->post_type, array( 'post', 'page' ) ) ) {

			$pt 	= get_post_type_object( $post->post_type );
			$link 	= apply_filters( 'tav_bc_link_parent_' . $post->post_type, get_post_type_archive_link( $post->post_type ) );

			$parent_label = '<a href="' . $link . '">' . $pt->label . '</a>';

		}

	} elseif( is_page() ) {

		/* Ok, we have the page name, easy... */
		$item = $post->post_title;

		/* Current page is the first children */
		$upper = $post->post_parent;

		/* Now let's find all possible parent pages */
		for( $i = 0; $upper != 0; $i++ ) {

			$new_page = get_post( $upper );

			$parent_label[] = array( 'id' => $new_page->ID, 'label' => $new_page->post_title );

			$upper = $new_page->post_parent;

		}

	} elseif( is_404() ) {

		/* 404 is a very easy case, isn't it? */
		$item = $page_404_label;

	} else {

	}

	$item = $item_before . $item . $item_after;

	/* If there's a parent item let's handle it */
	if( isset( $parent_label ) && $parent_label ) {

		/* In case we have multiple parents, let's add them all */
		if( is_array( $parent_label ) ) {

			/* Normally it goes from children to parents. We want the reverse order. */
			$parent_label = array_reverse( $parent_label );

			foreach( $parent_label as $key => $parent ) {

				if( is_single() || is_tax() ) {
					$link = apply_filters( "tav_bc_link_cat_", get_term_link( $parent['object'] ) );
				} elseif( is_page() ) {
					$link = get_permalink( $parent['id'] );
				} else {
					$link = '#';
				}

				$parent_tmp = $item_before . '<a href="' . $link . '" ' . $link_attr . '>' . $parent['label'] . '</a>' . $item_after;

				/* Add it to the list */
				array_push( $items, $parent_tmp );

			}

		} else {

			/* Finalize the item */
			$parent_label = $item_before . $parent_label . $item_after;

			/* Add it to the list */
			array_push( $items, $parent_label );

		}

		/* Reset parent */
		$parent_label = false;
	}

	/* Now we can add the (child) item */
	array_push( $items, $item );

	/**
	 * Now that all items are ready, it's time
	 * to merge them all and add the delimiter
	 * between all of them.
	 */
	$items = implode( $delimiter, $items );

	/**
	 * SHOW TIME!
	 * We now echo all the markup. First the opening tag
	 * we prepared at the begining of the function, then
	 * the items we just imploded, and finally
	 * the closing tag.
	 */
	echo $open . $items . $close;

}