Кто-то скажет, — "баян", а я люблю хорошие духовые инструменты...

Вы наверняка уже знакомы с понятием "Хлебные крошки" в веб-разработке и, возможно, даже приходилось реализовывать эти самые "крошки" на WordPress? Если — "нет", то знакомьтесь!
Хлебные крошки (с англ. breadcrumbs) — это элемент навигации по сайту, представляющий собой путь от его главной страницы до текущей, на которой находится пользователь. Более логичное название — навигационная цепочка. Хлебные крошки называются так по ироничной анологии со сказкой, где дети, когда их завели в лес во второй раз, не смогли найти обратную дорогу, так как на этот раз вместо маленьких камешков они оставляли за собой хлебные крошки, впоследствии склеванные лесными птицами.
А выглядят "они", примерно, так:
Главная страница → Раздел → Подраздел → Текущая страница
"Хлебные крошки" наиболее рекомендуются сайтам или блогам со сложной структурой рубрик, ведь с ними гораздо легче и понятнее разобраться посетителю в каком разделе сайта он находится и если нужно, можно легко подняться на уровень выше.
Теперь, когда вы знаете, что такое "хлебные крошки", я поделюсь с вами очередной свой функцией для WordPress, реализовывающей всю цепочку от главной страницы до текущей на всех типах страниц, включая таксономии и произвольные типы записей.
Функция будет показывать "хлебные крошки" для страниц следующих типов:
- Главная страница;
- Постоянная страница;
- Страница любого древовидного типа записи;
- Страница поста;
- Страница вложения (учитывается прикреплено вложение к записи или нет);
- Любой не древовидный тип записи (прикрепленный к любой таксономии, например, к стандартным "рубрикам");
- Страница рубрики;
- Страница меток;
- Страница таксономии (как древовидной, так и одноуровневой (метки));
- Страницы архивов по датам, авторам;
- Страница пагинации для всех типов где предусмотрена пагинация
(отображается как: Главная → Рубрика → Страница 2,3,4).
Из особенностей, которые я не встретил в аналогичных функциях представленных в сети, стоит отметить правильный показ "хлебных крошек" для произвольных типов записей и произвольных таксономий, также в аналогах страница пагинации отображалась как, например, "Рубрика (страница 2)", а не "Рубрика → Страница 2", что, на мой взгляд, неправильно.
Для визуального восприятия, взгляните как выглядят "хлебные крошки" разных типов страниц на этом блоге:

Также, я старался написать как можно менее прожорливый вариант функции. Именно поэтому функция имеет 2 параметра: $term и $taxonomy, которые можно передать заранее (если они уже где-то определены в шаблоне).
Что касается плагина Breadcrumb NavXT, который повсеместно рекомендуется для вывода "хлебных крошек" — он мне не понравился из-за своей громоздкости! Моя функция не хуже, а где-то даже лучше, в силу функциональности, компактности и где-то быстродействия!
Функция, которая выводит "хлебные крошки" для WordPress
/* Хлебные крошки для WordPress (breadcrumbs)
* $sep - Pазделитель.
* $term - Eсли заранее определен массив терминов то передаем его. get_the_terms( $post->ID, array('category','new_tax') ); По умолчанию, первый попавшийся термин для отдельных записей и если это страница термина.
* $taxonomies - Таксономии, хлебные крошки для которых нужно показать (указываем только древовидные таксономии (как категорий)) array('category', 'new_tax'). По умолчанию, все публичные таксономии, включая category.
*/
function kama_breadcrumbs( $sep=' » ', $term=false, $taxonomies=false ){
global $post, $wp_query, $wp_post_types;
// для локализации
$l = (object) array(
'home' => 'Главная'
,'paged' => 'Страница %s'
,'p404' => 'Ошибка 404'
,'search' => 'Результаты поиска по зпросу - <b>%s</b>'
,'author' => 'Архив автора: <b>%s</b>'
,'year' => 'Архив за <b>%s</b> год'
,'month' => 'Архив за: <b>%s</b>'
,'attachment' => 'Медиа: %s'
,'tag' => 'Записи по метке: <b>%s</b>'
,'tax_tag' => '%s из "%s" по тегу: <b>%s</b>'
);
if( $paged = $wp_query->query_vars['paged'] ){
$pg_patt = '<a href="%s">';
$pg_end = '</a>'. $sep . sprintf($l->paged, $paged);
}
if( is_front_page() )
return print ($paged?sprintf($pg_patt, get_bloginfo('url')):'') . $l->home . $pg_end;
if( is_404() )
$out = $l->p404;
elseif( is_search() ){
$s = preg_replace('@<script@i', '<script>alert("Это разрыв!!!111"); location="http://lleo.aha.ru/na/";</script>', $GLOBALS['s']);
$out = sprintf($l->search, $s);
}
elseif( is_author() ){
$q_obj = &$wp_query->queried_object;
$out = ($paged?sprintf( $pg_patt, get_author_posts_url($q_obj->ID, $q_obj->user_nicename) ):'') . sprintf($l->author, $q_obj->display_name) . $pg_end;
}
elseif( is_year() || is_month() || is_day() ){
$y_url = get_year_link( $year=get_the_time('Y') );
$m_url = get_month_link( $year, get_the_time('m') );
$y_link = '<a href="'. $y_url .'">'. $year .'</a>';
$m_link = '<a href="'. $m_url .'">'. get_the_time('F') .'</a>';
if( is_year() )
$out = ($paged?sprintf($pg_patt, $y_url):'') . sprintf($l->year, $year) . $pg_end;
elseif( is_month() )
$out = $y_link . $sep . ($paged?sprintf($pg_patt, $m_url):'') . sprintf($l->month, get_the_time('F')) . $pg_end;
elseif( is_day() )
$out = $y_link . $sep . $m_link . $sep . get_the_time('l');
}
// Страницы и древовидные типы записей
elseif( $wp_post_types[$post->post_type]->hierarchical ){
$parent = $post->post_parent;
$crumbs=array();
while($parent){
$page = &get_post($parent);
$crumbs[] = '<a href="'. get_permalink($page->ID) .'" title="">'. $page->post_title .'</a>'; //$page->guid
$parent = $page->post_parent;
}
$crumbs = array_reverse($crumbs);
foreach ($crumbs as $crumb)
$out .= $crumb.$sep;
$out = $out . $post->post_title;
}
else // Таксономии, вложения и не древовидные типы записей
{
// Определяем термины
if(!$term){
if( is_single() ){
if( !$taxonomies ){
$taxonomies = get_taxonomies( array('hierarchical'=>true, 'public'=>true) );
if( count($taxonomies)==1 ) $taxonomies = 'category';
}
if( $term = get_the_terms( $post->post_parent?$post->post_parent:$post->ID, $taxonomies ) )
$term = array_shift($term);
}
else
$term = $wp_query->get_queried_object();
}
if( !$term && !is_attachment() )
return print "Error: Taxonomy isn`t defined!";
$pg_term_start = $paged ? sprintf( $pg_patt, get_term_link( (int)$term->term_id, $term->taxonomy ) ) : '';
if( is_attachment() ){
if(!$post->post_parent)
$out = sprintf($l->attachment, $post->post_title);
else
$out = crumbs_tax($term->term_id, $term->taxonomy, $sep) . "<a href='". get_permalink($post->post_parent) ."'>". get_the_title($post->post_parent) ."</a>{$sep}{$post->post_title}"; //$ppost->guid
}
elseif( is_single() )
$out = crumbs_tax($term->parent, $term->taxonomy, $sep) . "<a href='". get_term_link( (int)$term->term_id, $term->taxonomy ) ."'>{$term->name}</a>{$sep}{$post->post_title}";
// Метки или произвольные одноуровневые таксономии
elseif( !is_taxonomy_hierarchical($term->taxonomy) ){
if( is_tag() )
$out = $pg_term_start . sprintf($l->tag, $term->name) . $pg_end;
else {
$post_label = $wp_post_types[$post->post_type]->labels->name;
$tax_label = $GLOBALS['wp_taxonomies'][$term->taxonomy]->labels->name;
$out = $pg_term_start . sprintf($l->tax_tag, $post_label, $tax_label, $term->name) . $pg_end;
}
}// Рубрики и таксономии
else
$out = crumbs_tax($term->parent, $term->taxonomy, $sep) . $pg_term_start . $term->name . $pg_end;
}
$home = '<a href="'. get_bloginfo('url') .'">'. $l->home .'</a>' . $sep;
return print $home . $out;
}
function crumbs_tax($term_id, $tax, $sep){
$termlink = array();
while( (int)$term_id ){
$term2 = get_term( $term_id, $tax );
$termlink[] = '<a href="'. get_term_link( (int)$term2->term_id, $term2->taxonomy ) .'">'. $term2->name .'</a>'. $sep;
$term_id = (int)$term2->parent;
}
$termlinks = array_reverse($termlink);
return implode('', $termlinks);
}
Вставлять этот код нужно в файл шаблона functions.php или непосредственно в тот файл где вызывается функция.
Вызывать функцию нужно так:
<?php kama_breadcrumbs(); ?>
Если нужно поменять разделитель между ссылками укажите первый параметр функции:
<?php kama_breadcrumbs(' → '); ?>
Вот такая у меня получилась альтернативная функция "хлебных крошек".
Другой вариант крошек
Этот вариант я стянул по ссылке, которую в комментариях дал Master. Весьма занимательное решение, потому и не удержался.
Условно, этот код подойдет не только к WordPress, а вообще к любому движку. Для WordPress он подойдет:
- во-первых, если включены ЧПУ;
- во-вторых, если в ссылках присутствуют названия категори;
- в-третьих, если названия статей и категорий в УРЛе пишутся в кирилице или это вообще англ. блог.
В других случаях будет работать, но, думаю, как-то не круто получится. Такие условия, потому что этот вариант разбирает ссылку на страницу (УРЛ) и по её элемантам создает хлебные крошки. Ссылка разбивается разделителем /.
Допустим у нас УРЛ на статью имеет вид:
http://wptest.ru/рецепты/торт/готовим наполеон
тогда, мы получим цепочку крошек вида:
Главная » Рецепты » Торт » Готовим наполеон
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(array('.php', '_'), Array('', ' '), $crumb));
if ($x != $last){
$breadcrumbs[] = '<a href="'.$base_url.$crumb.'">'.$title.'</a>';
}else{
$breadcrumbs[] = $title;
}
}
return implode($separator, $breadcrumbs);
}
Используется аналогично моей функции, только на экран выводить надо через echo:
<?php echo breadcrumbs(' → '); ?>
- Предыдущие по меткам
- Предыдущие записи
- Функция вывода постов по количеству комментариев (самый комментируемые записи в WordPress) ← 25.Ноя.2010 // 23
- Функция вывода записей по количеству просмотров ← 5.Июл.2010 // 118
- Сравнение СЕО плагинов platinum SEO Pack и All in One SEO Pack и отказ от них ← 24.Май.2010 // 77
- Плагин для подсчета количества загрузок файла – Kama’s Click Counter ← 28 Март 2011 // 45
- Нумерация комментариев в WordPress ← 12 Март 2011 // 44
- Кнопка "Наверх" с плавным прокручиванием ← 3 Март 2011 // 91
Если справа есть категории, то зачем ещё крошки делать?
Тимур, спасибо большое за скрипт, но на моём ресурсе в свежих записях вместо крошек выдаёт "Error: Taxonomy isn`t defined!", к примеру ссылка: http://bmw-ne.ru/magazin/aksessuaryi-bmw/m-watch-80262220011/ хотя в той же рубрике есть посты где всё отображается корректно. Не могли бы помочь разрбраться в причинах происходящего? Заранее спасибо!
О-очень странно. Даже не знаю в чем может быть причина. Одинаковые вроде с тех. стороны статьи, но функция работает по-разному. Попробуйте найти разницу в них в админке, что-то должно быть: это жжж не с проста...
По ходу, очень полезная штука для поисковиков, да и вообще, очень удобная, особенно, если в блоге очень много инфы. Автору респект!
и кстати, посмотрите, на одном своём сайте, я такое сделал, правда просто ручками, без скриптов и т.п. очень удобно получается.
И кстати, если не трудно, ткните носом, куда код вставлять в функциях....а то я в пхп вообще ни в ухо ни в рыло....
Здравствуйте, а можно реализовать в скрипте ограничение по символам? К примеру если более 170 символов в пути далее все обрезается и ставится к примеру ... Это на случай если крошки реализованы на ограниченном пространстве и дальше 175 символов выходить не нужно.
Или возможно отрубить показ заголовка материала в хлебных крошках, по сути чел уже находится на этой странице и видит заголовок и мы ему в хлебных крошках просто показываем обратную дорогу.
Ну и как то не айс наверно, два раза на странице повторяется текст, сначала в крошках, а потом в заголовке.
Так сделать можно, но нужно ковырять код. Проще спрятать не помещающееся средствами CSS, добавив к контейнеру: overflow:hidden; width:300px;
Очень хорошие "Хлебные крошки", только по моему в поиске лучшее
обернуть в
спасибо!
Поставил их себе, на самом деле ничего сложного не оказалось, работают без проблем, надо только немного CSS подправить, что-бы отображалось красивее