Как сделать хлебные крошки

Для тех, кто не знает, хлебные крошки — это способ навигации, который показывает ваше текущее расположение на сайте (кстати, они используются не только на сайтах) и путь, по которому к нему можно попасть, начиная с главной страницы.

Для того, чтобы добавить хлебные крошки на сайт на WordPress вам не нужен специальный плагин «хлебные крошки», не нужно самому долго и мучительно придумывать как «сделать» хлебные крошки на сайте, не нужно долго мучить поисковики различными мудрёными фразами, а достаточно скопировать и вставить эту строчку в то место в шаблоне, куда вам нужно.

<?php the_breadcrumb() ?>

Теперь распишем саму функцию, сразу говорю, готовьтесь, что будет много кода.

Дело в том, что я выкладываю полностью законченный и 100% рабочий вариант. Здесь учтены все типы страниц, которые только могут быть на WordPress: посты, страницы, вложенные страницы(поддерживается любое количество уровней вложенности), рубрики, подрубрики (неограниченное количество вложений), теги, архивы, страницы поиска, страницы с записями какого-либо одного автора.

Также отображается номер текущей страницы, что тоже довольно полезно.

Давайте сначала начнём с относительно несложного варианта хлебных крошек, и чуть ниже в этом же уроке я вам расскажу, как их модифицировать под какую-то свою определённую задачу. Для начала добавьте этот код functions.php:

function the_breadcrumb(){
 
	// получаем номер текущей страницы
	$pageNum = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
 
	$separator = ' &raquo; '; //  »
 
	// если главная страница сайта
	if( is_front_page() ){
 
		if( $pageNum > 1 ) {
			echo '<a href="' . site_url() . '">Главная</a>' . $separator . $pageNum . '-я страница';
		} else {
			echo 'Вы находитесь на главной странице';
		}
 
	} else { // не главная
 
		echo '<a href="' . site_url() . '">Главная</a>' . $separator;
 
 
		if( is_single() ){ // записи
 
			the_category(', '); echo $separator; the_title();
 
		} elseif ( is_page() ){ // страницы WordPress 
 
			the_title();
 
		} elseif ( is_category() ) {
 
			single_cat_title();
 
		} elseif( is_tag() ) {
 
			single_tag_title();
 
		} elseif ( is_day() ) { // архивы (по дням)
 
			echo '<a href="' . get_year_link(get_the_time('Y')) . '">' . get_the_time('Y') . '</a>' . $separator;
			echo '<a href="' . get_month_link(get_the_time('Y'),get_the_time('m')) . '">' . get_the_time('F') . '</a>' . $separator;
			echo get_the_time('d');
 
		} elseif ( is_month() ) { // архивы (по месяцам)
 
			echo '<a href="' . get_year_link(get_the_time('Y')) . '">' . get_the_time('Y') . '</a>' . $separator;
			echo get_the_time('F');
 
		} elseif ( is_year() ) { // архивы (по годам)
 
			echo get_the_time('Y');
 
		} elseif ( is_author() ) { // архивы по авторам
 
			global $author;
			$userdata = get_userdata($author);
			echo 'Опубликовал(а) ' . $userdata->display_name;
 
		} elseif ( is_404() ) { // если страницы не существует
 
			echo 'Ошибка 404';
 
		}
 
		if ( $pageNum > 1 ) { // номер текущей страницы
			echo ' (' . $pageNum . '-я страница)';
		}
 
	}
 
}
  • 4 – при помощи get_query_var() мы определяем, находимся ли мы на странице постраничной навигации, знаю, что это можно сделать при помощи is_paged(), но нам же ведь ещё и номер страницы понадобится.
  • 6 – разделитесь между ссылками в хлебных я решил записать в переменную, вы можете использовать что угодно, например стрелки → , запись его в переменную позволит нам быстро его поменять, если захотим.
  • 9 – функция, а точнее условный тег is_front_page() возвращает true, если мы находимся на главной странице, вне зависимости от того, какую роль она выполняет.
  • 12, 19 – функция site_url() динамически возвращает ссылку на главную страницу сайта.
  • is_single(), is_page(), is_category(), is_tag(), is_day(), is_month(), is_year(), is_author(), is_404() – различные условные теги, позволяющие легко определить, на каком типе страницы мы в данный момент находимся.
  • 25 – я использовал функцию the_category(), для вывода списка рубрик для текущей записи через запятую. Обратите внимание, что эта функция не распределяет рубрики в зависимости от их иерархии. О том, как вывести их с соблюдением порядка иерархии, читайте ниже.
  • 25, 29 – функция the_title() отлично подходит для того, чтобы вывести заголовок текущей записи, страницы или записи произвольного типа.
  • single_cat_title() и single_tag_title() – для вывода название текущей рубрики или метки соответственно.

Как в хлебные крошки добавить родительские страницы?

Возможно вы заметили, что Страницы WordPress – это иерархичный тип записи, другими словами – Страница может иметь дочерние страницы, причем несколько штук и нескольких уровней.

Это можно хорошо наблюдать в метабоксе Атрибуты страницы:

Выбор родительской страницы в WordPress

Если вы планируете отображать в своих хлебных крошках родительские страницы тоже, то вам нужно немного модифицировать соответствующие строчки в коде выше:

global $post;
// если у текущей страницы существует родительская
if ( $post->post_parent ) {
 
	$parent_id  = $post->post_parent; // присвоим в переменную
	$breadcrumbs = array(); 
 
	while ( $parent_id ) {
		$page = get_page( $parent_id );
		$breadcrumbs[] = '<a href="' . get_permalink( $page->ID ) . '">' . get_the_title( $page->ID ) . '</a>';
		$parent_id = $page->post_parent;
	}
 
	echo join( $separator, array_reverse( $breadcrumbs ) ) . $separator;
 
}

То есть вставляете этот код на 27-й строчке ничего не удаляя из первоначального кода.

Как отображать родительские рубрики?

В архивах рубрик

Тут ситуация похожа на ситуацию со страницами, но проще, так как существует функция get_category_parents().

$current_cat = get_queried_object();
// если родительская рубрика существует
if( $current_cat->parent ) {
	echo get_category_parents( $current_cat->parent, true, $separator ) . $separator;
}

На страницах записей

Как я уже написал выше, наша функция the_category() не справляется с тем, чтобы вывести рубрики с учетом их иерархичности. Давайте попробуем разобраться, что с этим можно поделать.

Тут есть некоторые тонкости, но смотрите, есть очень классный способ, как можно это всё разрулить!

Прежде всего, обратите внимание, как вы добавляете пост в категории.

Нам подходит:

Добавляем только дочернюю рубрику при редактировании записи

Не подходит:

добавление и дочерней и родительской рубрики при редактировании записи

После этого можно спокойно использовать функцию get_category_parents():

$post_categories = get_the_category();
 
// это и будет наша единственная рубрика, присвоенная к посту
if( !empty( $post_categories[0]->cat_ID ) ) {
	echo get_category_parents( $post_categories[0]->cat_ID, true, $separator ) . $separator;
}
the_title();

Что делать с произвольными типами постов и таксономиями?

На самом деле тут всё максимально похоже на код, который мы использовали для рубрик/меток и записей/страниц.

Хлебные крошки для архивов таксономии

Если без иерархии:

if( is_tax( $taxonomy_name ) ) {
	single_term_title();
}

С иерархией:

if( is_tax( $taxonomy_name ) ) {
	$current_term = get_queried_object();
	// если родительский элемент таксономии существует
	if( $current_term->parent ) {
		echo get_term_parents_list( $current_term->parent, $taxonomy_name, array( 'separator' => $separator ) ) . $separator;
	}
	single_term_title();
}

Хлебные крошки для произвольный типов постов

Если мы вообще не хотим отображать никаких таксономий, то наш пример становится очень похож на пример с обычными Страницами:

if( is_singular( $post_type_name ) ) {
	the_title();
}

В случае, если нам нужно также добавить какую-то произвольную таксономию:

if( is_singular( $post_type_name ) ) {
	$post_terms = get_the_terms( get_the_ID(), $taxonomy_name );
 
	if( !empty( $post_terms[0]->term_id ) ) {
		echo get_term_parents_list( $post_terms->term_id, $taxonomy_name, array( 'separator' => $separator ) ) . $separator;
	}
	the_title();
}

Кстати, видел на других блогах функцию хлебных крошек длиной в 5-10 строк 🙂 Люди копипастят даже не задумываясь, понятно, что у них очень урезанные варианты.

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии 43

  • Алекс 1 ноября 2011 #

    реально, это самая полная версия крошек из всех, которые я видел на других сайтах! Спасибо 🙂

  • Ксана 10 июня 2012 #

    Михаил, прочитала ваш блог "от корки до корки".

    У вас не только талант в программировании, но и явный преподавательский талант.

    Все, даже сложные вещи, вы описываете просто и понятно.

    Я читала и восторгалась - не верится, что вам всего 20 лет.
    Какой вы умница!

    Нашла на вашем блоге несколько полезных рецептов.

    Спасибо!

    • Миша 10 июня 2012 #

      Спасибо) приятно)

  • serj 13 ноября 2012 #

    Миша, предлагаю тему для статьи в категорию Юзабилити:

    Как выводить похожие записи в сайдбар по заголовку с миниатюрами без плагина(вообще сможете такое реализовать?).

    Имхо многим пригодится.

    • Миша 14 ноября 2012 #

      хорошо, буду иметь ввиду)

      • serj 14 ноября 2012 #

        и еще имейте ввиду) хотелось бы увидеть побольше статей о похожих записях(чтобы были статические они).

        Вам же надо наполнять кат. "Юзабилити" 🙂

        С нетерпением жду. Спасибо

        п.с. когда заглянуть?

      • Миша 15 ноября 2012 #

        кат юзабилити скоро удалю на самом деле)
        загляни в течение недели)

  • serj 15 ноября 2012 #

    куда тогда(заглянуть в кат. WordPress)?
    Очень бы хотелось, увидеть статью с оригинальным выводом "похожих записей"(видно что можешь:))

    • Миша 16 ноября 2012 #

      если ты подписался на обновления, то её не пропустишь)

  • Роман 12 сентября 2013 #

    Доброе время суток!
    Все отлично, но по этим ссылкам из хлебных крошек, вес уходит со страницы. Не подскажите, как ссылки закрыть в нофолов, чтобы вес не терялся, а все крошки в ноиндекс, чтобы не было переспама, так как в крошках идет повторение текста заголовка записи?

    • Миша 12 сентября 2013 #

      Добрый день,
      ajax

      • dezm021 11 мая 2014 #

        здравствуйте, хорошая работа, спасибо,

        подскажите, пжл как можно подгрузить хлебные крошки через ajax - как делаю, добавил ваш код в functions.php и создал новый файл и создал новую страницу где применил этот шаблон, но получилось что я через аякс просто на просто подтягиваю те хлебные крошки к которым относится созданный шаблон, то есть на всех страницах у меня получаются хлебные крошки

        Главная -> Ajax - the_breadcrumb

        • Миша 11 мая 2014 #

          Добрый день!
          про ajax в WorPress можно почитать здесь truemisha.ru/blog/wordpress/admin-ajax.html

          если всё равно ничего не будет получаться, обращайтесь.

        • Виктор 4 августа 2014 #

          удалось реализовать?

  • Ольга 2 января 2014 #

    Вот я и "доросла" до "хлебных крошек"... Установила себе их на сайт твоим, Миша, способом. Перепробовала всё, но хотела без плагина и попроще в настройках. Твой вариант действительно РАБОТАЕТ на 100%. Спасибо тебе, огромное. Только вот хотела спросить: твой сайт в поиске Гугл выводится так: сайт > блог > категория. А у меня тоже так будет? Просто я проверила у меня выводится одна ссылка, не видно "крошек". Может просто должно пройти время, чтобы Гугл это заметил?

    • Миша 2 января 2014 #

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

      • Ольга 2 января 2014 #

        Буду с нетерпением ждать такой "обновки"!!! Читаю все новые статьи и возвращаюсь к прежним. Хотя многого ещё не понимаю... (((

        • Миша 3 января 2014 #

          Со временем обязательно во всём разберётесь 🙂 Желаю удачи!
          Отпишусь после обновления поста.

  • Виктор 4 августа 2014 #

    Автору большое спасибо. Но опять возникает вопрос по скрытию через АЯКС - вывод работает, но страница определяется совершенно неправильно 🙁
    Если комуто удалось решить эту проблему буду премного благодарен

  • Алексей 14 августа 2015 #

    Почему то возникла проблема , не работает, отображает так:
    Главная » Ремонт ПК » Ремонт компьютера

    Вместо стрелочек отображает

     »
    • Миша 14 августа 2015 #

      Вероятно у вас заменилось

      »

      на

      &raquo;
  • Александр 13 января 2020 #

    Я извиняюсь, а в чем смысл echo у the_title() на 22 строчке ?

    • Миша 13 января 2020 #

      😁😁😁
      Первоначальная дата публикации поста – 2011-й год, надо будет полностью обновить его

      • Александр 13 января 2020 #

        Спасибо за рабочий код)!
        И за твой проект!

      • Миша 13 января 2020 #

        Пожалуйста! 🙃

  • Анна 16 января 2020 #

    Спасибо за рабочий код!
    у меня возник вопрос: сайт на вордпресс. структура рубрик идет гл.рубрика - подкатегория 1ур- подкатегория А 2 ур и подкатегория В 2 ур. И я имею ситуацию что у товара1 хлебные крошки собираются в правильном порядке: гл.рубрика - подкатегория 1ур- подкатегория А 2 ур, а у товара2 в неверном: гл.рубрика - подкатегория В 2 ур - подкатегория 1 ур.
    С помощью плагина я изменила иерархию рубрик, но проблема не решилась. в чем проблема? возможно поможете с решением?

    • Миша 16 января 2020 #

      Пожалуйста!

      Та функция, которую мы здесь используем для вывода категорий – the_category() – не умеет определять, какая рубрики главная, а какая нет 🙂

      • Анна 16 января 2020 #

        Подскажите какая функция мне поможет решить проблему, буду очень благодарна Вам!

      • Миша 16 января 2020 #

        Кастомная к сожалению. Я немного допилю на этой неделе этот пост про хлебные крошки.
        Если вам удобно подождать пару дней 🙃

        • Анна 16 января 2020 #

          О, подожду) Было бы просто замечательно!

        • Миша 16 января 2020 #

          Ну супер тогда! 🙂

        • Миша 18 января 2020 #

          Обновил!

          • Анна 19 января 2020 #

            Спасибо за обновление! К сожалению моя проблема с функцией the_category() так и осталась актуальной, и используется именно несколько категорий и подкатегорий у записей, т.е. путь по иерархии категорий полный

            вот моя жалкая попытка переписать код..

            	the_category(', ',$parents); echo $separator; the_title();
            global $category;
            // если у текущей страницы существует родительская
            if ( $category->category_parent ) {
             
            	$parent_id  = $category->category_parent; // присвоим в переменную
            	$breadcrumbs = array(); 
             
            	while ( $parent_id ) {
            		$category = get_category( $parent_id );
            		$breadcrumbs[] = '<a href="' . get_permalink( $page->ID ) . '">' . get_cat_title( $category->ID ) . '</a>';
            		$parent_id = $category->category_parent;
            	}
             
            	echo join( $separator, array_reverse( $breadcrumbs ) ) . $separator;
          • Миша 20 января 2020 #

            А так вы сделайте, чтобы была отмечена только подкатегория 🙃

            • Анна 20 января 2020 #

              к сожалению, так не подходит :((

            • Миша 20 января 2020 #

              Тогда вам нужно получить все категории через get_the_category(), определить через цикл, какая из них сааамая дочерняя, и потом можно использовать мой код. Это самый несложный вариант мне кажется.

              Другой вариант – несколько раз прогонять результат через массив с разными проверками.

              • Анна 20 января 2020 #

                ох, не выходит у меня совсем( уже сегодня и вчера весь день.
                результаты: могу вывести гл.рубрику+подрубрику1уровня+название, а надо гл.рубрика+подрубрика1уровня+подрубрика2уровня+название.
                по вашему коду неверно по иерархии попадают рубрики: гл.рубрика+подрубрика2уровня+подрубрика1уровня+название

                спасите пожалуйста

              • Миша 20 января 2020 #

                Аня, очень вам сочувствую! ... Тоже через это проходил..

                Пожалуйста, не сдавайтесь, и я гарантирую, у вас всё получится! Это самое главное в такие моменты. 💪

                Попробуйте сходить в душ или, если есть возможность, в басик, это кстати реально освежает моск.

                Добавлю также, что вы очень многим людям поможете, если скинете свой получившийся рабочий код в комментарии. Ну а я постараюсь подкорректировать, если в нём что-то будет не так.

                • Анна 4 февраля 2020 #

                  Благодарю за поддержку, все таки удалось разобраться.

                  Суть проблемы - нарушена иерархия рубрик в хлебных крошках.

                  Иерархия выставляется по параметру term_order, а мы множество раз тасовали иерархию рубрик, и они все намешались, а параметр принадлежности иерархии term_order как был присвоен при создании 0-1-2-3-4.. 8.. и тп, так и остается. Ни один из плагинов настройки иерархии эту проблему не смог решить.

                  Решение: в файлах базы данных выставить правильно параметр term_order у рубрик. Думаю если намешана иерархия у таксономий - это также поможет.

                  чем дело с кодом закончилось? вот что остается у нас:

                     $categories = get_the_category();
                        usort($categories, 'sortTermOrder');
                        if($categories){
                          echo '<ul>';
                          array($categories);
                          foreach($categories as $category) {
                            echo '<a href="'. get_category_link($category->term_id) . '" > ' . $category->cat_name . '</a>'; echo $separator;
                          }
                          '</ul>';
                        }
                • Миша 5 февраля 2020 #

                  Спасибо большое за ваш комментарий! 🙏

  • Zoya 2 марта 2020 #

    Спасибо огромное за полезную информацию. Пригодилось для работы

    • Zoya 2 марта 2020 #

      Может Вы бы подсказали , как присвоить классы ссылкам, которые формируются при добавлении "хлебных крошек"? На странице несколько тегов , в том числе и "хлебные крошки", когда хочешь изменить стиль одной меняются все. Заранее благодарю.

  • Василий 6 марта 2020 #

    Огромное спасибо за код! Есть вопрос. В последнем примере кода (стр.28) в первом аргументе get_term_parents_list наверное надо добавить [0] к $post_terms (то есть $post_terms[0]->term_id). Верно? Потому что у меня этот фикс убрал ошибку для бредкрамба сингл поста кастомного типа со своей таксономией.

    $post_type_name = 'products';
            $taxonomy_name = 'product_cat';
    if( is_singular( $post_type_name ) ) {
     
                $post_terms = get_the_terms( get_the_ID(), $taxonomy_name );
     
                if( !empty( $post_terms[0]->term_id ) ) {
                    echo get_term_parents_list( $post_terms[0]->term_id, $taxonomy_name, array( 'separator' => $separator ) );
                }
                the_title();
     
            }

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, в случае несоблюдения этого условия в 99% случаях ваш коммент будет удалён, а автор заблокирован. Печалька.