Хлібні крихти для WordPress (breadcrumbs)

Ви напевно вже знайомі з поняттям «Хлібні крихти» у веб-розробці і можливо навіть доводилося реалізовувати ці «крихти» на WordPress.

Хлібні крихти (з англ. breadcrumbs) – це елемент навігації по сайту, що виглядає як шлях від головної сторінки до поточної, на якій знаходиться користувач. Більш логічна назва – навігаційний ланцюжок . Хлібні крихти називаються так за іронічною аналогією з казкою, в якій діти, коли їх завели до лісу вдруге, не змогли знайти дорогу назад, оскільки цього разу замість маленьких камінців вони залишали за собою хлібні крихти, згодом скльовані лісовими птахами.

Цей код я більше не підтримую, місцями він працює не так, як потрібно. За стабільною та розширеною версією цього коду переходьте за посиланням:

Дивитись платну версію Kama Breadcrumbs

Виглядають «хлібні крихти» так:

Головна » Розділ » Підрозділ » Поточна сторінка

«Хлібні крихти» найбільше рекомендуються сайтам зі складною структурою розділів (рубрик), адже з ними набагато легше і зрозуміліше розібратися відвідувачу в якому розділі сайту він знаходиться і якщо потрібно, можна легко піднятися на рівень вище та оглянути гілку цілком.

Тепер, після короткого лікнепу, ділитимуся черговою функцією для WordPress, що реалізовує весь ланцюжок від головної сторінки до поточної на всіх типах сторінок, включаючи таксономії та довільні типи записів.

Функція показуватиме «хлібні крихти» для сторінок таких типів:
  • Головна сторінка;
  • Постійна сторінка;
  • Сторінка будь-якого деревоподібного типу запису;
  • Сторінка посту;
  • Сторінка вкладення (враховується прикріплене вкладення до запису чи ні);
  • Будь-який не деревоподібний тип запису (прикріплений до будь-якої таксономії, наприклад, до стандартних “рубрик”);
  • Сторінка рубрики;
  • Сторінка міток;
  • Сторінка таксономії (як деревоподібної, так і однорівневої (мітки));
  • Сторінки архівів за датами, авторами;
  • Сторінка пагінації для всіх типів, де передбачена пагінація
    (відображається як: Головна » Рубрика » Сторінка 2,3,4).
  • Підтримує мікророзмітку. Інструменти для перевірки: для Яндекса та для Google .

З особливостей, які я не зустрів в аналогічних функціях представлених у мережі, варто відзначити правильний показ “хлібних крихт” для довільних типів записів та довільних таксономій, також в аналогах сторінка пагінації відображалася як, наприклад, “Рубрика (сторінка 2)”, а не ” Рубрика > Сторінка 2″, що, як на мене, неправильно.

Для візуального сприйняття, погляньте як виглядають «хлібні крихти» різних типів:

Також, я намагався написати якнайменше ненажерливий варіант функції.

Що стосується плагіна Breadcrumb NavXT , який повсюдно рекомендується для виведення “хлібних крихт” – він мені не сподобався через свою громіздкість. Моя функція не гірша, а в чомусь навіть краща: за рахунок функціональності, компактності та місцями швидкодії!

Також функція підтримує мікророзмітки: schema.org або RDF, дивіться параметр markup.


Функція «хлібних крихт» для WordPress

<?php

/**
 * Хлібні крихти для WordPress (breadcrumbs)
 *
 * @param string [$ sep = ''] Розділювач. За замовчуванням ' " '
 * @param array [$l10n = array()] Для локалізації. Див. змінну $default_l10n.
 * @param array [$args = array()] Опції. Див. змінну $def_args
 * @return string Виводить на екран HTML код
 *
 * version 3.3.2
 */
function kama_breadcrumbs( $sep = ' » ', $l10n = array(), $args = array() ){
	$kb = новий Kama_Breadcrumbs;
	echo $kb->get_crumbs( $sep, $l10n, $args );
}

class Kama_Breadcrumbs {

	public $arg;

	// Локалізація
	static $l10n = array(
		'home' => 'Головна',
		'paged' => 'Сторінка %d',
		'_404' => 'Помилка 404',
		'search' => 'Результати пошуку на запит - <b>%s</b>',
		'author' => 'Архів автора: <b>%s</b>',
		'year' => 'Архів за <b>%d</b> рік',
		'month' => 'Архів за: <b>%s</b>',
		'day' => '',
		'attachment' => 'Медіа: %s',
		'tag' => 'Записи по мітці: <b>%s</b>',
		'tax_tag' => '%1$s з "%2$s" за тегом: <b>%3$s</b>',
		// tax_tag виведе: 'тип_запису з "назва_такси" за тегом: имя_терміна'.
		// Якщо потрібні окремі холдери, наприклад, тільки ім'я терміна, пишемо так: 'записи за тегом: %3$s'
	);

	// Параметри за замовчуванням
	static $args = array(
		'on_front_page' => true, // виводити крихти на головній сторінці
		'show_post_title' => true, // чи показувати назву запису наприкінці (останній елемент). Для записів, сторінок, вкладень
		'show_term_title' => true, // чи показувати назву елемента таксономії в кінці (останній елемент). Для міток, рубрик та інших такс
		'title_patt' => '<span class="kb_title">%s</span>', // шаблон для останнього заголовка. Якщо увімкнено: show_post_title або show_term_title
		'last_sep' => true, // показувати останній роздільник, коли заголовок наприкінці не відображається
		'markup' => 'schema.org', // 'markup' - мікророзмітка. Можливо: 'rdf.data-vocabulary.org', 'schema.org', '' - без мікророзмітки
										   // або можна вказати свій масив розмітки:
										   // array( 'wrappatt'=>'<div class="kama_breadcrumbs">%s</div>', 'linkpatt'=>'<a href="%s">%s</a>', ' sep_after'=>'', )
		'priority_tax' => array('category'), // пріоритетні таксономії, потрібно коли запис у кількох таксах
		'priority_terms' => array(), // 'priority_terms' - пріоритетні елементи таксономії, коли запис знаходиться в декількох елементах однієї такси одночасно.
									  // Наприклад: array( 'category'=>array(45,'term_name'), 'tax_name'=>array(1,2,'name') )
									  // 'category' - такса для якої вказуються пріор. елементи: 45 - ID терміна та 'term_name' - ярлик.
									  // порядок 45 і 'term_name' має значення: що раніше, тим важливіше. Усі зазначені терміни важливіші за невказані...
		'nofollow' => false, // додавати rel=nofollow до посилань?

		// службові
		'sep' => '',
		'linkpatt' => '',
		'pg_end' => '',
	);

	function get_crumbs( $sep, $l10n, $args ){
		Global $post, $wp_query, $wp_post_types;

		self::$args['sep'] = $sep;

		// Фільтрує дефолти та зливає
		$loc = (object) array_merge( apply_filters('kama_breadcrumbs_default_loc', self::$l10n ), $l10n );
		$arg = (object) array_merge( apply_filters('kama_breadcrumbs_default_args', self::$args ), $args );

		$arg->sep = '<span class="kb_sep">'. $arg->sep .'</span>'; // доповнимо

		// спростимо
		$sep = & $arg->sep;
		$this->arg = & $arg;

		// мікророзмітка ---
		if(1){
			$mark = & $arg->markup;

			// Розмітка за замовчуванням
			if( ! $mark ) $mark = array(
				'wrappatt' => '<div class="kama_breadcrumbs">%s</div>',
				'linkpatt' => '<a href="%s">%s</a>',
				'sep_after' => '',
			);
			// rdf
			elseif( $mark === 'rdf.data-vocabulary.org' ) $mark = array(
				'wrappatt' => '<div class="kama_breadcrumbs" prefix="v: http://rdf.data-vocabulary.org/#">%s</div>',
				'linkpatt' => '<span typeof="v:Breadcrumb"><a href="%s" rel="v:url" property="v:title">%s</a>',
				'sep_after' => '</span>', // закриваємо span після роздільника!
			);
			// schema.org
			elseif( $mark === 'schema.org' ) $mark = array(
				'wrappatt' => '<div class="kama_breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">%s</div>',
				'linkpatt' => '<span itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="%s" itemprop="item"><span itemprop="name"> %s</span></a></span>',
				'sep_after' => '',
			);

			elseif( ! is_array($mark) )
				die( __CLASS__ .': "markup" parameter must be array...');

			$wrappatt = $mark['wrappatt'];
			$arg->linkpatt = $arg->nofollow ? str_replace('<a ','<a rel="nofollow"', $mark['linkpatt']) : $mark['linkpatt'];
			$arg->sep .= $mark['sep_after']."n";
		}

		$linkpatt = $arg->linkpatt; // спростимо

		$q_obj = get_queried_object();

		// може це архів порожньої такси?
		$ ptype = null;
		if( empty($post) ){
			if( isset($q_obj->taxonomy) )
				$ptype = & $wp_post_types[ get_taxonomy($q_obj->taxonomy)->object_type[0] ];
		}
		else $ptype = & $wp_post_types[ $post->post_type ];

		// paged
		$arg->pg_end = '';
		if( ($paged_num = get_query_var('paged')) || ($paged_num = get_query_var('page')) )
			$arg->pg_end = $sep . sprintf($loc->paged, (int) $paged_num);

		$pg_end = $arg->pg_end; // спростимо

		$out = '';

		if( is_front_page() ){
			return $arg->on_front_page ? sprintf( $wrappatt, ( $paged_num ? sprintf($linkpatt, get_home_url(), $loc->home) . $pg_end : $loc->home ) ) : '';
		}
		//Сторінка записів, коли для головної встановлено окрему сторінку.
		elseif( is_home() ) {
			$out = $paged_num? ( sprintf( $linkpatt, get_permalink($q_obj), esc_html($q_obj->post_title) ) . $pg_end ) : esc_html($q_obj->post_title);
		}
		elseif( is_404() ){
			$out = $loc->_404;
		}
		elseif( is_search() ){
			$out = sprintf( $loc->search, esc_html( $GLOBALS['s'] ) );
		}
		elseif( is_author() ){
			$tit = sprintf( $loc->author, esc_html($q_obj->display_name) );
			$out = ( $paged_num ? sprintf( $linkpatt, get_author_posts_url( $q_obj->ID, $q_obj->user_nicename ) . $pg_end, $tit ) : $tit );
		}
		elseif( is_year() || is_month() || is_day() ){
			$y_url = get_year_link( $year = get_the_time('Y') );

			if( is_year() ){
				$tit = sprintf( $loc->year, $year );
				$out = ( $paged_num ? sprintf($linkpatt, $y_url, $tit) . $pg_end : $tit );
			}
			// month day
			else {
				$ y_link = sprintf ($ linkpatt, $ y_url, $ year);
				$m_url = get_month_link( $year, get_the_time('m') );

				if( is_month() ){
					$tit = sprintf( $loc->month, get_the_time('F') );
					$out = $y_link. $ sep . ( $paged_num ? sprintf( $linkpatt, $m_url, $tit ) . $pg_end : $tit );
				}
				elseif( is_day() ){
					$m_link = sprintf($linkpatt, $m_url, get_the_time('F'));
					$out = $y_link. $ sep . $m_link. $ sep . get_the_time('l');
				}
			}
		}
		// Деревоподібні записи
		elseif( is_singular() && $ptype->hierarchical ){
			$out = $this->_add_title( $this->_page_crumbs($post), $post );
		}
		// Такси, плоскі записи та вкладення
		else {
			$term = $q_obj; // таксономії

			// Визначаємо термін для записів (включаючи вкладення attachments)
			if( is_singular() ){
				// Змінимо $post, щоб визначити термін батька вкладення
				if( is_attachment() && $post->post_parent ){
					$save_post = $post; // збережемо
					$post = get_post($post->post_parent);
				}

				// враховує якщо вкладення прикріплюються до деревоподібних - все буває :)
				$taxonomies = get_object_taxonomies( $post->post_type );
				// залишимо лише деревоподібні та публічні, чи мало...
				$taxonomies = array_intersect( $taxonomies, get_taxonomies( array('hierarchical' => true, 'public' => true) ) );

				if( $taxonomies ){
					// сортуємо за пріоритетом
					if( ! empty($arg->priority_tax) ){
						usort( $taxonomies, function($a,$b)use($arg){
							$a_index = array_search($a, $arg->priority_tax);
							if( $a_index === false ) $a_index = 9999999;

							$b_index = array_search($b, $arg->priority_tax);
							if( $b_index === false ) $b_index = 9999999;

							return ($b_index === $a_index)? 0 : ( $ b_index < $ a_index ? 1 : -1 ); // менший індекс - вище
						} );
					}

					// пробуємо отримати терміни, у порядку пріоритету такс
					foreach( $taxonomies as $taxname ){
						if( $terms = get_the_terms( $post->ID, $taxname ) ){
							// Перевіримо пріоритетні терміни для такси
							$prior_terms = & $arg->priority_terms[ $taxname ];
							if( $prior_terms && count($terms) > 2 ){
								foreach( (array) $prior_terms as $term_id ){
									$filter_field = is_numeric($term_id)? 'term_id' : 'slug';
									$_terms = wp_list_filter( $terms, array($filter_field=>$term_id) );

									if( $_terms ){
										$term = array_shift($_terms);
										break;
									}
								}
							}
							else
								$ term = array_shift ($ terms);

							break;
						}
					}
				}

				if( isset($save_post) ) $post = $save_post; // Повернемо назад (для вкладень)
			}

			// Висновок

			// Усі види записів з термінами чи терміни
			if( $term && isset($term->term_id) ){
				$term = apply_filters('kama_breadcrumbs_term', $term);

				// attachment
				if( is_attachment() ){
					if( ! $post->post_parent )
						$out = sprintf( $loc->attachment, esc_html($post->post_title) );
					else {
						if( ! $out = apply_filters('attachment_tax_crumbs', '', $term, $this ) ){
							$_crumbs = $this->_tax_crumbs( $term, 'self' );
							$parent_tit = sprintf( $linkpatt, get_permalink($post->post_parent), get_the_title($post->post_parent) );
							$_out = implode( $sep, array($_crumbs, $parent_tit) );
							$out = $this->_add_title( $_out, $post );
						}
					}
				}
				// single
				elseif( is_single() ){
					if( ! $out = apply_filters('post_tax_crumbs', '', $term, $this ) ){
						$_crumbs = $this->_tax_crumbs( $term, 'self' );
						$out = $this->_add_title( $_crumbs, $post );
					}
				}
				// не деревоподібна такса (мітки)
				elseif( ! is_taxonomy_hierarchical($term->taxonomy) ){
					// Мітка
					if( is_tag() )
						$out = $this->_add_title('', $term, sprintf( $loc->tag, esc_html($term->name) ) );
					// такса
					elseif( is_tax() ){
						$post_label = $ptype->labels->name;
						$tax_label = $GLOBALS['wp_taxonomies'][ $term->taxonomy ]->labels->name;
						$out = $this->_add_title('', $term, sprintf( $loc->tax_tag, $post_label, $tax_label, esc_html($term->name) ) );
					}
				}
				// Деревоподібна такса (рибрики)
				else {
					if( ! $out = apply_filters('term_tax_crumbs', '', $term, $this ) ){
						$_crumbs = $this->_tax_crumbs( $term, 'parent' );
						$out = $this->_add_title( $_crumbs, $term, esc_html($term->name) );
					}
				}
			}
			// Вкладення від запису без термінів
			elseif( is_attachment() ){
				$parent = get_post($post->post_parent);
				$parent_link = sprintf($linkpatt, get_permalink($parent), esc_html($parent->post_title));
				$_out = $parent_link;

				// Вкладення від запису деревоподібного типу запису
				if( is_post_type_hierarchical($parent->post_type) ){
					$parent_crumbs = $this->_page_crumbs($parent);
					$_out = implode( $sep, array( $parent_crumbs, $parent_link ) );
				}

				$out = $this->_add_title( $_out, $post );
			}
			// записи без термінів
			elseif( is_singular() ){
				$out = $this->_add_title( '', $post );
			}
		}

		// Заміна посилання на архівну сторінку для типу запису
		$home_after = apply_filters('kama_breadcrumbs_home_after', '', $linkpatt, $sep, $ptype );

		if( '' === $home_after ){
			// Посилання архівну сторінку типу записи для: окремих сторінок цього; архівів цього; таксономій пов'язаних із цим типом.
			if( $ptype && $ptype->has_archive && ! in_array( $ptype->name, array('post','page','attachment') )
				&& ( is_post_type_archive() || is_singular() || (is_tax() && in_array($term->taxonomy, $ptype->taxonomies)) )
			) {
				$pt_title = $ptype->labels->name;

				// перша сторінка архіву типу запису
				if( is_post_type_archive() && ! $paged_num )
					$home_after = sprintf( $this->arg->title_patt, $pt_title );
				// singular, paged post_type_archive, tax
				else {
					$home_after = sprintf( $linkpatt, get_post_type_archive_link($ptype->name), $pt_title );

					$home_after .= ( ($paged_num && ! is_tax()) ? $pg_end : $sep ); // пагінація
				}
			}
		}

		$before_out = sprintf( $linkpatt, home_url(), $loc->home ) . ( $home_after ? $sep.$home_after : ($out ? $sep : '') );

		$out = apply_filters('kama_breadcrumbs_pre_out', $out, $sep, $loc, $arg);

		$out = sprintf( $wrappatt, $before_out . $out );

		return apply_filters('kama_breadcrumbs', $out, $sep, $loc, $arg);
	}

	function _page_crumbs( $post ){
		$parent = $post->post_parent;

		$crumbs = array();
		while($parent) {
			$ page = get_post ($ parent);
			$crumbs[] = sprintf( $this->arg->linkpatt, get_permalink($page), esc_html($page->post_title) );
			$parent = $page->post_parent;
		}

		return implode( $this->arg->sep, array_reverse($crumbs) );
	}

	function _tax_crumbs( $term, $start_from = 'self' ){
		$termlinks = array();
		$term_id = ($start_from === 'parent') ? $term->parent : $term->term_id;
		while( $term_id ){
			$ term = get_term ($ term_id, $ term->taxonomy);
			$termlinks[] = sprintf( $this->arg->linkpatt, get_term_link($term), esc_html($term->name) );
			$term_id = $term->parent;
		}

		if( $termlinks )
			return implode( $this->arg->sep, array_reverse($termlinks) ) /*. $this->arg->sep*/;
		return '';
	}

	// додає заголовок до переданого тексту, з урахуванням усіх опцій. Додає роздільник на початок, якщо треба.
	function _add_title( $add_to, $obj, $term_title = '' ){
		$arg = & $this->arg; // спростимо...
		$title = $term_title? $term_title : esc_html($obj->post_title); // $term_title чиститися окремо, теги можуть бути...
		$show_title = $term_title? $arg->show_term_title : $arg->show_post_title;

		// пагінація
		if( $arg->pg_end ){
			$link = $term_title? get_term_link($obj) : get_permalink($obj);
			$add_to .= ($add_to ? $arg->sep : '') . sprintf($arg->linkpatt, $link, $title). $arg->pg_end;
		}
		// доповнюємо - ставимо sep
		elseif( $add_to ){
			if( $show_title )
				$add_to .= $arg->sep . sprintf($arg->title_patt, $title);
			elseif( $arg->last_sep )
				$add_to .= $arg->sep;
		}
		// sep буде потім...
		elseif( $show_title )
			$add_to = sprintf($arg->title_patt, $title);

		return $add_to;
	}

}

/**
 * Зміни:
 * 3.3 - нові хуки: attachment_tax_crumbs, post_tax_crumbs, term_tax_crumbs. Дозволяють доповнити крихти таксономій.
 * 3.2 - баг з роздільником, з відключеним 'show_term_title'. Стабілізував логіку.
 * 3.1 - баг з esc_html() для заголовка термінів - з тегами виходило криво...
 * 3.0 - Обернув до класу. Додав опції: 'title_patt', 'last_sep'. Доопрацював код. Додав пагінацію для постів.
 * 2.5 - ADD: Опція 'show_term_title'
 * 2.4 - Дрібні правки коду
 * 2.3 - ADD: Сторінка записів, коли для головної встановлено окрему сторінку.
 * 2.2 - ADD: Link to post type archive on taxonomies page
 * 2.1 - ADD: $sep, $loc, $args params to hooks
 * 2.0 - ADD: до фільтра 'kama_breadcrumbs_home_after' доданий четвертий аргумент $ptype
 * 1.9 - ADD: фільтр 'kama_breadcrumbs_default_loc' для зміни локалізації за умовчанням
 * 1.8 - FIX: нотатки, коли в рубриці немає записів
 * 1.7 - Поліпшено роботу з пріоритетними таксономіями.
 */

Вставляти цей код потрібно у файл шаблону functions.php або безпосередньо в той файл, де викликається функція.

Викликати функцію потрібно в шаблоні, в тому місці, де повинні виводитись крихти, так:

<?php if( function_exists('kama_breadcrumbs') ) kama_breadcrumbs(); ?>

Якщо потрібно змінити роздільник між посиланнями, вкажіть перший параметр:

<?php if( function_exists('kama_breadcrumbs') ) kama_breadcrumbs(' » '); ?>


Приклади використання фільтрів

#1 Встановлення параметрів через фільтр

Зміни дефолтні параметри через фільтр

add_filter('kama_breadcrumbs_default_args', function($args){
	$args['on_front_page'] = 0;
	$args['show_post_title'] = '';
	$args['priority_tax'] = array('mytax');
	return $args;
} );

Якщо встановити параметри під час виклику функції в третьому аргументі функції, вони переб’ють параметри вказані у фільтрі…

#3 Приклад перекладу крихт на англійську

Ці приклади показують як перекласти крихти на потрібну мову або просто змінити дефолтні значення:

Варіант 1

При виклику функції потрібно вказати рядки локалізації так:

// Локалізація
if( function_exists('kama_breadcrumbs') ){

	$ myl10n = array (
		'home' => 'Front page',
		'paged' => 'Page %d',
		'_404' => 'Error 404',
		'search' => 'Search results by query - <b>%s</b>',
		'author' => 'Author archve: <b>%s</b>',
		'year' => 'Archive by <b>%d</b> рік',
		'month' => 'Archive by: <b>%s</b>',
		'day' => '',
		'attachment' => 'Media: %s',
		'tag' => 'Posts by tag: <b>%s</b>',
		'tax_tag' => '%1$s від "%2$s" до tag: <b>%3$s</b>',
		// tax_tag виведе: 'тип_запису з "назва_такси" за тегом: имя_терміна'.
		// Якщо потрібні окремі холдери, наприклад, тільки ім'я терміна, пишемо так: 'записи за тегом: %3$s'
	);

	kama_breadcrumbs(' » ', $myl10n );

}
Варіант 2

З версії 1.9. Можна використовувати хук kama_breadcrumbs_default_locдля кожного виклику одне і теж не вказувати. Для цього поряд з вихідним кодом крихт додайте такий хук:

add_filter('kama_breadcrumbs_default_loc', function($l10n){
	// Локалізація
	return array(
		'home' => 'Front page',
		'paged' => 'Page %d',
		'_404' => 'Error 404',
		'search' => 'Search results by query - <b>%s</b>',
		'author' => 'Author archve: <b>%s</b>',
		'year' => 'Archive by <b>%d</b> рік',
		'month' => 'Archive by: <b>%s</b>',
		'day' => '',
		'attachment' => 'Media: %s',
		'tag' => 'Posts by tag: <b>%s</b>',
		'tax_tag' => '%1$s від "%2$s" до tag: <b>%3$s</b>',
		// tax_tag виведе: 'тип_запису з "назва_такси" за тегом: имя_терміна'.
		// Якщо потрібні окремі холдери, наприклад, тільки ім'я терміна, пишемо так: 'записи за тегом: %3$s'
	);
});

Далі, використовуйте виклик у шаблоні як завжди, крихти будуть переведені на англ.

function_exists('kama_breadcrumbs') && kama_breadcrumbs();

Установки через хук мають менший пріоритет, ніж через виклик функції варіанта 1. Це означає, що якщо вказати локалізацію через хук, то через виклик можна перебити локалізацію окремих рядків.

#3 Додавання довільного посилання на початок крихт

Допустимо нам потрібно додати після пункту “Головна” посилання на сторінку 7, якщо зараз ми перебуваємо в категорії 5 або в її дочірній категорії (враховується один рівень вкладеності).

Для цього додайте такий хук поруч із кодом крихт:

add_action('kama_breadcrumbs_home_after', 'my_breadcrumbs_home_after', 10, 4);
function my_breadcrumbs_home_after( $false, $linkpatt, $sep, $ptype ){
	// якщо ми в рубриці з ID 5 або в дочірній рубриці,
	// то доповнимо початок крихт посиланням на сторінку з ID 7
	$qo = get_queried_object();
	if( is_category() && ( $qo->term_id == 5 || $qo->parent == 5 ) ){
		$page = get_post(7);
		return sprintf($linkpatt, get_permalink($page), $page->post_title). $ sep;
	}

	return $ false;
}

#4 Додавання ще таксономій у крихти

За умовчанням в крихтах обробляється лише одна таксонома. Але іноді потрібно кілька, для цього у версії 3.3 я вставив хуки: ‘attachment_tax_crumbs’ , ‘post_tax_crumbs’ , ‘term_tax_crumbs’ .

Допустимо, у нас є тип запису realty і 3 такси для нього: country , type_deal , type_realty . Потрібно, щоб сторінка запису в крихтах відображала всі такси в зазначеному порядку. Також потрібно, щоб на кожній сторінці такси вказувалися всі попередні такси та поточна у вказаному порядку: country > type_deal > type_realty

// apply_filters('term_tax_crumbs', '', $term, $that );
add_filter('term_tax_crumbs', 'more_tax_crumbs', 10, 3);
add_filter('post_tax_crumbs', 'more_tax_crumbs', 10, 3);
function more_tax_crumbs( $empty, $term, $that ){
	$is_post_filter = doing_filter('post_tax_crumbs'); // else 'term_tax_crumbs'

	if(( $is_post_filter && is_singular('realty') ) || is_tax('country') ){
		global $post;

		$out = '';

		$out = $that->_tax_crumbs( $term, 'self' ) . $that->arg->sep; // базова такса - country

		// Тип угоди
		$term = get_query_var('type_deal');
		if( $term && ($term = get_term_by('slug', $term, 'type_deal')) )
			$out .= $that->_tax_crumbs( $term, 'self' ) . $that->arg->sep; // Тип угоди

		// Тип нерухомості
		$term = get_query_var('type_realty');
		if( $term && ($term = get_term_by('slug', $term, 'type_realty')) ){
			// запис
			if( $is_post_filter ){
				$_crumbs = $that->_tax_crumbs( $term, 'self');
				$out .= $that->_add_title( $_crumbs, $post );
			}
			// такса
			else {
				$_crumbs = $that->_tax_crumbs( $term, 'parent' );
				$out .= $that->_add_title( $_crumbs, $term, esc_html($term->name) );
			}

		}

		return $out;
	}

	return $empty;
}


Інший варіант крихт

Цей варіант я стягнув за посиланням , яке в коментарях дав Master . Дуже цікаве рішення, тому й не втримався.

Умовно, цей код підійде не тільки до WordPress, а взагалі до будь-якого движка. Для WordPress він підійде:

  • по-перше, якщо включені ЧПУ ;
  • по-друге, якщо в засланнях присутні назви категорії;
  • по-третє, якщо назви статей та категорій в УРЛ пишуться у кирилиці або це взагалі англ. блог.

В інших випадках працюватиме, але, гадаю, якось не круто вийде. Такі умови, тому що цей варіант розбирає посилання на сторінку (УРЛ) і її елементами створює хлібні крихти. Посилання розбивається роздільником /.

Допустимо у нас УРЛ на статтю має вигляд:
http://example.com/рецепты/торт/готовим наполеон
тоді, ми отримаємо ланцюжок крихт виду :
Готуємо наполеон

function breadcrumbs($separator = ' » ', $home = 'Головна') {

	$path = array_filter(explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));
	$base_url = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://'. $_SERVER['HTTP_HOST'] . '/';
	$breadcrumbs = array("<a href="$base_url">$home</a>");

	$last = end(array_keys($path));

	foreach( $path as $x => $crumb ){
		$title = ucwords( str_replace( [ '.php', '_' ], [ '', ' ' ], $crumb ) );
		if( $x != $last ){
			$breadcrumbs[] = '<a href="'. $base_url . $crumb .'">'. $title .'</a>';
		}
		else {
			$breadcrumbs[] = $title;
		}
	}

	return implode( $separator, $breadcrumbs );
}

Використовується аналогічно до моєї функції, тільки на екран виводити треба через echo:

<?php echo breadcrumbs(' » '); ?>

Залишити коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *