Breadcrumbs

HIT

14.06.2015

2093

Breadcrumbs (хлебные крошки) — это удобный инструмент навигации, без которого не обходится ни один современный сайт.

На данный момент есть несколько альтернативных вариантов крошек от разных разработчиков, помимо нескольких десятков плагинов.
Любое из выбранных решений добавляем в functions.php, либо делаем свой плагин.

Kama Breadcrumbs

function kama_breadcrumbs( $sep = '', $l10n = array(), $args = array() ){
global $post, $wp_query, $wp_post_types;

// Локализация
$default_l10n = array(
'home' => '<i class="fa fa-home"></i>',
'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'
);

// Параметры по умолчанию
$default_args = array(
'on_front_page' => true, // выводить крошки на главной странице
'show_post_title' => true, // показывать ли название записи в конце (последний элемент). Для записей, страниц, вложений
// можно указать строку вида <span>%s</span>, когда нужно обернуть заголовок в html
'sep' => ' / ', // разделитель
'markup' => 'schema.org',
// 'markup' - микроразметка. Может быть: 'rdf.data-vocabulary.org', 'schema.org', '' - без микроразметки
// или можно указать свой массив разметки:
// array( 'wrap'=>'<div class="kama_breadcrumbs">', 'wrap_close'=>'</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 к ссылкам?
);

// Фильтрует аргументы по умолчанию
$default_args = apply_filters('kama_breadcrumbs_default_args', $default_args );

$loc = (object) array_merge( $default_l10n, $l10n );
$args = (object) array_merge( $default_args, $args );

if( ! $sep ) $sep = $args->sep;

// микроразметка ---
if(1){
$mrk = & $args->markup;

// Разметка по умолчанию default
if( ! $mrk ){
$mrk = array(
'wrap' => '<div class="kama_breadcrumbs">',
'wrap_close' => '</div>',
'linkpatt' => '<a href="%s">%s</a>',
'sep_after' => '',
);
}
if( $mrk == 'rdf.data-vocabulary.org' ){
$mrk = array(
'wrap' => '<div class="kama_breadcrumbs" prefix="v: http://rdf.data-vocabulary.org/#">',
'wrap_close' => '</div>',
'linkpatt' => '<span typeof="v:Breadcrumb"><a href="%s" rel="v:url" property="v:title">%s</a>',
'sep_after' => '</span>', // закрываем span после разделителя!
);
}
// schema.org
elseif( $mrk == 'schema.org' ){
$mrk = array(
'wrap' => '<div class="kama_breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">',
'wrap_close' => '</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' => '', // закрываем span после разделителя!
);
}
elseif( ! is_array($mrk) )
die( __FUNCTION__ .': "markup" parameter must be array...');

$wrap = $mrk['wrap']."\n";
$wrap_close = $mrk['wrap_close']."\n";
$linkpatt = $args->nofollow ? str_replace('<a ','<a rel="nofollow"', $mrk['linkpatt']) : $mrk['linkpatt'];
$sep .= $mrk['sep_after']."\n";
}

$ptype = & $wp_post_types[ $post->post_type ];

// paged
$pg_end = '';
if( $paged_num = $wp_query->query_vars['paged'] ){
$pg_end = /*'</a>'.*/ $sep . sprintf( $loc->paged, (int) $paged_num );
}

// OUT
$out = '<span class="current"></span>';

// front page
if( is_front_page() ){
return $args->on_front_page ? ( print $wrap .( $paged_num ? sprintf($linkpatt, get_home_url(), $loc->home) . $pg_end : $loc->home ). $wrap_close ) : '';
}
elseif( is_404() ){
$out = $loc->_404;
}
elseif( is_search() ){
$out = sprintf( $loc->search, esc_html( $GLOBALS['s'] ) );
}
elseif( is_author() ){
$q_obj = &$wp_query->queried_object;
$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 = __hierarchical_posts( $args, $sep, $linkpatt, $post );
}

// Таксы, вложения и не древовидные записи
else {
$term = false;
// set term (attachments too)
if( is_singular() ){
// Чтобы определить термин для вложения
if( is_attachment() && $post->post_parent ){
$save_post = $post;
$post = get_post( $post->post_parent );

if( is_post_type_hierarchical( $post->post_type ) ){
$hierarchical_post_attach_out = __hierarchical_posts( $args, $sep, $linkpatt, $post );
}
}

// учитывает если вложения прикрепляются к таксам древовидным - все бывает :)

$taxonomies = get_object_taxonomies( $post->post_type );
// оставим только древовидные и публичные, мало ли...
$taxonomies = array_intersect( $taxonomies, get_taxonomies( array('hierarchical' => true, 'public' => true) ) );

// не делаем лишнего...
if( $taxonomies ){
// пробуем найти приоритетные
$priority_tax = array_intersect( $taxonomies, $args->priority_tax );
// получаем название таксы
$taxonomy = $priority_tax ? array_shift( $priority_tax ) : array_shift( $taxonomies );

if( $terms = get_the_terms( $post->ID, $taxonomy ) ){
$term = array_shift( $terms );

// проверим приоритетные термины для таксы
$prior_terms = & $args->priority_terms[ $taxonomy ];
if( $prior_terms && count($terms) > 1 ){
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;
}
}
}
}
}

if( isset($save_post) ) $post = $save_post; // вернем обратно (для вложений)
}
// term for tax page
else
$term = get_queried_object();

//if( ! $term && ! is_attachment() ) return print "Error: Taxonomy is not defined!";
//var_dump($term);
// вложение древовидного типа записи
if( isset($hierarchical_post_attach_out) ){
$out = $hierarchical_post_attach_out . sprintf( $linkpatt, get_permalink( $post->post_parent ), get_the_title( $post->post_parent ) ) . $sep . __show_post_title( $args->show_post_title, $post->post_title );
}
// если есть термин
elseif( $term ){
$term = apply_filters('kama_breadcrumbs_term', $term );

$term_tit_patt = '';
if( $term->term_id )
$term_tit_patt = $paged_num ? sprintf( $linkpatt, get_term_link($term->term_id, $term->taxonomy), '{title}' ) . $pg_end : '{title}';

// attachment
if( is_attachment() ){
if( ! $post->post_parent )
$out = sprintf( $loc->attachment, esc_html($post->post_title) );
else{
$tit = sprintf( $linkpatt, get_permalink($post->post_parent), get_the_title($post->post_parent) ) . $sep . __show_post_title( $args->show_post_title, $post->post_title );
$out = __crumbs_tax( $term->term_id, $term->taxonomy, $sep, $linkpatt ) . $tit;
}
}
// single
elseif( is_single() ){
$out = __crumbs_tax( $term->parent, $term->taxonomy, $sep, $linkpatt ) . sprintf( $linkpatt, get_term_link( $term->term_id, $term->taxonomy ), $term->name ). $sep . __show_post_title( $args->show_post_title, $post->post_title );
// Метки, архивная страница типа записи, произвольные одноуровневые таксономии
}
// taxonomy не древовидная
elseif( ! is_taxonomy_hierarchical( $term->taxonomy ) ){
// метка
if( is_tag() )
$out = str_replace('{title}', sprintf( $loc->tag, $term->name ), $term_tit_patt );
// таксономия
elseif( is_tax() ){
$post_label = $ptype->labels->name;
$tax_label = $GLOBALS['wp_taxonomies'][ $term->taxonomy ]->labels->name;
$out = str_replace('{title}', sprintf( $loc->tax_tag, $post_label, $tax_label, $term->name ), $term_tit_patt );
}
}
// Рубрики и таксономии
else{
//die( $term->taxonomy );
$out = __crumbs_tax( $term->parent, $term->taxonomy, $sep, $linkpatt ) . str_replace('{title}', $term->name, $term_tit_patt );
}
}
}

$home_after = '';

// замена ссылки на архивную страницу для типа записи
$home_after = apply_filters('kama_breadcrumbs_home_after', false, $linkpatt, $sep );

// Ссылка на архивную страницу произвольно типа поста. Ссылку можно заменить с помощью хука 'kama_breadcrumbs_home_after'
if( ! $home_after && $ptype->has_archive && (is_post_type_archive() || is_singular()) && ! in_array( $post->post_type, array('post','page','attachment') ) ){
$pt_name = $ptype->labels->name;

if( is_post_type_archive() && ! $paged_num )
$home_after = $pt_name;
else
$home_after = sprintf( $linkpatt, get_post_type_archive_link( $post->post_type ), $pt_name ) . ($pg_end ? $pg_end : $sep);
}

$home = sprintf( $linkpatt, home_url(), $loc->home ). $sep . $home_after;

$out = apply_filters('kama_breadcrumbs_pre_out', $out );

$out = $wrap. $home . $out .$wrap_close;

return print apply_filters('kama_breadcrumbs', $out, $sep );
}
function __hierarchical_posts( $args, $sep, $linkpatt, $post ){
$parent = $post->post_parent;

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

$out = '';
foreach( $crumbs as $crumb )
$out .= $crumb . $sep;

return $out . __show_post_title( $args->show_post_title, $post->post_title );
}
function __show_post_title( $is_show, $title ){
return $is_show ? ( is_string($is_show) ? sprintf( $is_show, esc_html($title) ) : esc_html($title) ) : '';
}
function __crumbs_tax( $term_id, $tax, $sep, $linkpatt ){
$termlink = array();
while( $term_id ){
$term2 = get_term( $term_id, $tax );
$termlink[] = sprintf( $linkpatt, get_term_link( $term2->term_id, $term2->taxonomy ), esc_html($term2->name) ). $sep;
$term_id = $term2->parent;
}

$termlinks = array_reverse( $termlink );

return implode('', $termlinks );
}

Крошки от kama неправильно работают с произвольными типами записей

Выводятся крошки так:

<div id="path"><?php if( function_exists('dimox_breadcrumbs') ) dimox_breadcrumbs(); ?></div>

Dimox Breadcrumbs

// поддержка хлебных крошек
function dimox_breadcrumbs() {

 /* === ОПЦИИ === */
 $text['home'] = 'Главная'; // текст ссылки "Главная"
 $text['category'] = '%s'; // текст для страницы рубрики
 $text['tax'] = '%s'; // текст для страницы таксономии
 $text['search'] = 'Результаты поиска по запросу "%s"'; // текст для страницы с результатами поиска
 $text['tag'] = '%s'; // текст для страницы метки
 $text['author'] = '%s'; // текст для страницы автора
 $text['404'] = 'Ошибка 404'; // текст для страницы 404
 
 $showCurrent = 1; // 1 - 1 - показывать название текущей статьи/страницы/рубрики, 0 - не показывать
 $showOnHome = 0; // 1 - показывать "хлебные крошки" на главной странице, 0 - не показывать
 $show_home_link = 1; // 1 - показывать ссылку "Главная", 0 - не показывать
 $show_title = 1; // 1 - показывать подсказку (title) для ссылок, 0 - не показывать
 $delimiter = ' / '; // разделить между "крошками"
 $before = '<span class="current">'; // тег перед текущей "крошкой"
 $after = '</span>'; // тег после текущей "крошки"
 /* === КОНЕЦ ОПЦИЙ === */ 

 global $post;
 $homeLink = get_bloginfo('url') . '/';
 $linkBefore = '<span typeof="v:Breadcrumb">';
 $linkAfter = '</span>';
 $linkAttr = ' rel="v:url" property="v:title"';
 $link = $linkBefore . '<a' . $linkAttr . ' href="%1$s">%2$s</a>' . $linkAfter;
 
 
 if (is_home() || is_front_page()) {
 if ($showOnHome == 1) echo '<div id="crumbs"><a href="' . $homeLink . '">' . $text['home'] . '</a></div>';
 } else {
 echo '<div id="crumbs" xmlns:v="http://rdf.data-vocabulary.org/#">' . sprintf($link, $homeLink, $text['home']) . $delimiter;
 
 
 if ( is_category() ) {
 $thisCat = get_category(get_query_var('cat'), false);
 if ($thisCat->parent != 0) {
 $cats = get_category_parents($thisCat->parent, TRUE, $delimiter);
 $cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
 $cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
 echo $cats;
 }
 echo $before . sprintf($text['category'], single_cat_title('', false)) . $after;
 
 
 } elseif( is_tax() ){
 $thisCat = get_category(get_query_var('cat'), false);
 if ($thisCat->parent != 0) {
 $cats = get_category_parents($thisCat->parent, TRUE, $delimiter);
 $cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
 $cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
 echo $cats;
 }
 echo $before . sprintf($text['tax'], single_cat_title('', false)) . $after;
 
 
 }elseif ( is_search() ) {
 echo $before . sprintf($text['search'], get_search_query()) . $after;
 
 
 } elseif ( is_day() ) {
 echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y')) . $delimiter;
 echo sprintf($link, get_month_link(get_the_time('Y'),get_the_time('m')), get_the_time('F')) . $delimiter;
 echo $before . get_the_time('d') . $after;
 
 
 } elseif ( is_month() ) {
 echo sprintf($link, get_year_link(get_the_time('Y')), get_the_time('Y')) . $delimiter;
 echo $before . get_the_time('F') . $after;
 
 
 } elseif ( is_year() ) {
 echo $before . get_the_time('Y') . $after;
 
 
 } elseif ( is_single() && !is_attachment() ) {
 if ( get_post_type() != 'post' ) {
 $post_type = get_post_type_object(get_post_type());
 $slug = $post_type->rewrite;
 printf($link, $homeLink . '/' . $slug['slug'] . '/', $post_type->labels->name);
 if ($showCurrent == 1) echo $delimiter . $before . get_the_title() . $after;
 } else {
 $cat = get_the_category(); $cat = $cat[0];
 $cats = get_category_parents($cat, TRUE, $delimiter);
 if ($showCurrent == 0) $cats = preg_replace("#^(.+)$delimiter$#", "$1", $cats);
 $cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
 $cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
 echo $cats;
 if ($showCurrent == 1) echo $before . get_the_title() . $after;
 }
 
 
 } elseif ( !is_single() && !is_page() && get_post_type() != 'post' && !is_404() ) {
 $post_type = get_post_type_object(get_post_type());
 echo $before . $post_type->labels->name . $after;
 
 
 } elseif ( is_attachment() ) {
 $parent = get_post($post->post_parent);
 $cat = get_the_category($parent->ID); $cat = $cat[0];
 $cats = get_category_parents($cat, TRUE, $delimiter);
 $cats = str_replace('<a', $linkBefore . '<a' . $linkAttr, $cats);
 $cats = str_replace('</a>', '</a>' . $linkAfter, $cats);
 echo $cats;
 printf($link, get_permalink($parent), $parent->post_title);
 if ($showCurrent == 1) echo $delimiter . $before . get_the_title() . $after;
 
 
 } elseif ( is_page() && !$post->post_parent ) {
 if ($showCurrent == 1) echo $before . get_the_title() . $after;
 
 
 } elseif ( is_page() && $post->post_parent ) {
 $parent_id = $post->post_parent;
 $breadcrumbs = array();
 while ($parent_id) {
 $page = get_page($parent_id);
 $breadcrumbs[] = sprintf($link, get_permalink($page->ID), get_the_title($page->ID));
 $parent_id = $page->post_parent;
 }
 $breadcrumbs = array_reverse($breadcrumbs);
 for ($i = 0; $i < count($breadcrumbs); $i++) {
 echo $breadcrumbs[$i];
 if ($i != count($breadcrumbs)-1) echo $delimiter;
 }
 if ($showCurrent == 1) echo $delimiter . $before . get_the_title() . $after;
 
 
 } elseif ( is_tag() ) {
 echo $before . sprintf($text['tag'], single_tag_title('', false)) . $after;
 
 
 } elseif ( is_author() ) {
 global $author;
 $userdata = get_userdata($author);
 echo $before . sprintf($text['author'], $userdata->display_name) . $after;
 
 
 } elseif ( is_404() ) {
 echo $before . $text['404'] . $after;
 }
 
 
 if ( get_query_var('paged') ) {
 if ( is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author() ) echo ' (';
 echo __('Страница') . ' ' . get_query_var('paged');
 if ( is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author() ) echo ')';
 }
 echo '</div>';
 }
} // end dimox_breadcrumbs()

! разделитель между «крошками» — можно поставить путь к изображению

 

Вызов в шаблоне:

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

В данных крошках пользовательские типы записей реализованы правильно

Произвольные типы записей в произвольной таксономии

Иногда бывают ситуации, когда созданы произвольные типы записей и для них создана специальная таксономия.

Реализовать нормальные ХК для пользовательской таксономии с пользовательскими записями

Тэги:

Поделится информацией с друзьями

  • Похожие записи
  • Комментарии
  • Вложения
Русифицированная дата на сайте (месяцы, дни недели)

Русифицированная дата на сайте (месяцы, дни недели)

Добавляем на сайт функцию, которая приводит вывод даты (месяцы, дни недели) в человеческий вид. Помещаем в файл functions function dateToRussian($date) { $month = array("january"=>"января", "february"=>"февраля", "march"=>"марта", "april"=>"апреля", "may"=>"мая", "june"=>"июня", "july"=>"июля", Читать далее »

Хуки для woocommerce

Хуки для woocommerce

Здесь собраны наиболее востребованные хуки woocommerce, которые могут пригодится при настройке любого интернет-магазина. С другими полезными хуками можно ознакомиться здесь Необходимые части кода вставляем в файл functions (лучше использовать отдельный Читать далее »

/
Переменный стиль

Переменный стиль

Если нужно сделать для четных и нечетных элементов разные классы. Поместить в funсtions.php function cycle(&$arr) { $arr[] = array_shift($arr); return end($arr); } $oddEven = array('even', 'odd'); В блоке изменяемого стиля Читать далее »

Добавить комментарий

Пока нет комментариев. Будь первым!

Breadcrumbs
Кнопки Share без плагинов и сервисов
Рекомендации для васКнопки Share без плагинов и сервисовOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.