Files
Fakel-Gym/template-parts/la-components/functions/breadcrumbs.php
GP_DEV 21562852ca full
2025-07-08 14:21:19 +03:00

435 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* хлебные крошки
*/
// Проверяем, не объявлена ли уже функция
if (!function_exists('generate_yandex_breadcrumbs')) {
function generate_yandex_breadcrumbs()
{
$current_region = 'RU';
$home_title = 'Главная';
$home_url = home_url('/');
$texts = array(
'you_are_here' => 'Вы находитесь здесь:',
'search_prefix' => 'Поиск:',
'not_found' => 'Страница не найдена',
'author_prefix' => 'Публикации автора',
'breadcrumb_nav' => 'Навигация по разделам'
);
$clean_title = function ($title) {
return trim(preg_replace('/\s*\([^)]*\)/', '', $title));
};
$separator_svg = '<svg width="7" height="14" viewBox="0 0 7 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 13.9365L4.976 0.0644531H6.352L1.36 13.9365H0Z" fill="#6C6B6B" />
</svg>';
if (get_current_room() === 'gym') {
$home_icon_svg = '<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2307_15997)">
<path d="M0.584984 10.087C0.584984 11.1419 1.4431 12 2.498 12H5.0487C5.40085 12 5.68637 11.7148 5.68637 11.3623V8.81164H6.96172V11.3623C6.96172 11.7148 7.24723 12 7.59938 12H10.1501C11.205 12 12.0631 11.1419 12.0631 10.087V4.06395C12.0631 3.62119 11.8389 3.21704 11.4637 2.98226L7.00004 0.192428C6.58934 -0.0641426 6.05879 -0.0641426 5.64809 0.192428L1.18435 2.98226C0.809164 3.21704 0.584961 3.62119 0.584961 4.06395V10.087H0.584984ZM1.86034 4.06395L6.32405 1.27412L10.7878 4.06395V10.087C10.7878 10.4388 10.502 10.7247 10.1501 10.7247H8.23709V8.17395C8.23709 7.82211 7.95158 7.53629 7.59943 7.53629H5.04873C4.69658 7.53629 4.41106 7.82211 4.41106 8.17395V10.7247H2.498C2.14616 10.7247 1.86034 10.4388 1.86034 10.087V4.06395Z" fill="#F8F8F8" />
</g>
<defs>
<clipPath id="clip0_2307_15997">
<rect width="12" height="12" fill="white" transform="translate(0.324219)" />
</clipPath>
</defs>
</svg>';
} else {
$home_icon_svg = '<svg class="fill-[#222]" width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.584984 10.087C0.584984 11.1419 1.4431 12 2.498 12H5.0487C5.40085 12 5.68637 11.7148 5.68637 11.3623V8.81164H6.96172V11.3623C6.96172 11.7148 7.24723 12 7.59938 12H10.1501C11.205 12 12.0631 11.1419 12.0631 10.087V4.06395C12.0631 3.62119 11.8389 3.21704 11.4637 2.98226L7.00004 0.192428C6.58934 -0.0641426 6.05879 -0.0641426 5.64809 0.192428L1.18435 2.98226C0.809164 3.21704 0.584961 3.62119 0.584961 4.06395V10.087H0.584984ZM1.86034 4.06395L6.32405 1.27412L10.7878 4.06395V10.087C10.7878 10.4388 10.502 10.7247 10.1501 10.7247H8.23709V8.17395C8.23709 7.82211 7.95158 7.53629 7.59943 7.53629H5.04873C4.69658 7.53629 4.41106 7.82211 4.41106 8.17395V10.7247H2.498C2.14616 10.7247 1.86034 10.4388 1.86034 10.087V4.06395Z"
/>
</svg>';
}
// Создаем элемент главной страницы отдельно
$home_breadcrumb = array(
"@type" => "ListItem",
"position" => 1,
"name" => $home_title,
"item" => $home_url
);
// Массив для остальных крошек (без главной)
$breadcrumbs = array();
$position = 2; // Начинаем с позиции 2, так как главная уже позиция 1
if (is_post_type_archive()) {
$post_type = get_queried_object();
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($post_type->labels->name),
"item" => get_post_type_archive_link($post_type->name)
);
// Категории (включая иерархические)
} elseif (is_category()) {
$category = get_queried_object();
// Родительские категории
$parent_cats = array();
$parent_id = $category->parent;
while ($parent_id) {
$parent_cat = get_category($parent_id);
array_unshift($parent_cats, $parent_cat);
$parent_id = $parent_cat->parent;
}
foreach ($parent_cats as $parent_cat) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($parent_cat->name),
"item" => get_category_link($parent_cat->term_id)
);
}
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($category->name),
"item" => get_category_link($category->term_id)
);
// Теги
} elseif (is_tag()) {
$tag = get_queried_object();
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($tag->name),
"item" => get_tag_link($tag->term_id)
);
// Кастомные таксономии
} elseif (is_tax()) {
$term = get_queried_object();
$taxonomy = $term->taxonomy;
// Архив типа поста для этой таксономии
$taxonomy_obj = get_taxonomy($taxonomy);
if (!empty($taxonomy_obj->object_type)) {
$post_type = $taxonomy_obj->object_type[0];
$post_type_obj = get_post_type_object($post_type);
if ($post_type_obj && $post_type_obj->has_archive) {
$archive_link = get_post_type_archive_link($post_type);
if ($archive_link) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($post_type_obj->labels->name),
"item" => $archive_link
);
}
}
}
// Родительские термины для иерархических таксономий
if (is_taxonomy_hierarchical($taxonomy)) {
$parent_terms = array();
$parent_id = $term->parent;
while ($parent_id) {
$parent_term = get_term($parent_id, $taxonomy);
array_unshift($parent_terms, $parent_term);
$parent_id = $parent_term->parent;
}
foreach ($parent_terms as $parent_term) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($parent_term->name),
"item" => get_term_link($parent_term)
);
}
}
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($term->name),
"item" => get_term_link($term)
);
// Отдельные посты
} elseif (is_single()) {
global $post;
$post_type = get_post_type($post);
if ($post_type === 'post') {
// Обычные посты - категории
$categories = get_the_category();
if (!empty($categories)) {
$main_category = $categories[0];
// Родительские категории
$parent_cats = array();
$parent_id = $main_category->parent;
while ($parent_id) {
$parent_cat = get_category($parent_id);
array_unshift($parent_cats, $parent_cat);
$parent_id = $parent_cat->parent;
}
foreach ($parent_cats as $parent_cat) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($parent_cat->name),
"item" => get_category_link($parent_cat->term_id)
);
}
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($main_category->name),
"item" => get_category_link($main_category->term_id)
);
}
} else {
// Кастомные типы постов
$post_type_obj = get_post_type_object($post_type);
// Архив типа поста
if ($post_type_obj && $post_type_obj->has_archive) {
$archive_link = get_post_type_archive_link($post_type);
if ($archive_link) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($post_type_obj->labels->name),
"item" => $archive_link
);
}
}
// Основная таксономия для кастомного типа
$taxonomies = get_object_taxonomies($post_type, 'objects');
$main_taxonomy = null;
// Ищем основную таксономию (hierarchical в приоритете)
foreach ($taxonomies as $taxonomy) {
if ($taxonomy->public && !in_array($taxonomy->name, array('post_tag', 'post_format'))) {
if ($taxonomy->hierarchical) {
$main_taxonomy = $taxonomy->name;
break;
} elseif (!$main_taxonomy) {
$main_taxonomy = $taxonomy->name;
}
}
}
if ($main_taxonomy) {
$terms = get_the_terms($post, $main_taxonomy);
if (!empty($terms) && !is_wp_error($terms)) {
$main_term = $terms[0];
// Родительские термины для иерархических таксономий
if (is_taxonomy_hierarchical($main_taxonomy)) {
$parent_terms = array();
$parent_id = $main_term->parent;
while ($parent_id) {
$parent_term = get_term($parent_id, $main_taxonomy);
array_unshift($parent_terms, $parent_term);
$parent_id = $parent_term->parent;
}
foreach ($parent_terms as $parent_term) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($parent_term->name),
"item" => get_term_link($parent_term)
);
}
}
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title($main_term->name),
"item" => get_term_link($main_term)
);
}
}
}
// Текущий пост
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title(get_the_title()),
"item" => get_permalink()
);
// Страницы
} elseif (is_page()) {
global $post;
$ancestors = get_post_ancestors($post);
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $ancestor_id) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title(get_the_title($ancestor_id)),
"item" => get_permalink($ancestor_id)
);
}
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $clean_title(get_the_title()),
"item" => get_permalink()
);
// Авторы
} elseif (is_author()) {
$author = get_queried_object();
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $texts['author_prefix'] . ' ' . $author->display_name,
"item" => get_author_posts_url($author->ID)
);
// Поиск
} elseif (is_search()) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $texts['search_prefix'] . ' ' . get_search_query(),
"item" => home_url('?s=' . urlencode(get_search_query()))
);
// 404
} elseif (is_404()) {
$breadcrumbs[] = array(
"@type" => "ListItem",
"position" => $position++,
"name" => $texts['not_found'],
"item" => home_url($_SERVER['REQUEST_URI'])
);
}
// Объединяем главную страницу с остальными крошками для JSON-LD
$all_breadcrumbs = array_merge(array($home_breadcrumb), $breadcrumbs);
if (empty($all_breadcrumbs)) {
return false;
}
$yandex_schema = array(
"@context" => "https://schema.org",
"@type" => "BreadcrumbList",
"name" => "Навигация по разделам сайта",
"description" => "Путь навигации к текущей странице",
"areaServed" => array(
"@type" => "Country",
"name" => $current_region
),
"itemListElement" => $all_breadcrumbs
);
?>
<nav class="h-[30px] rounded-[24px] max-w-fit flex items-center bg-[linear-gradient(180deg,_#f2f2f2_69.59%,_#ededed_100%)] dark:bg-none dark:bg-[transparent] px-[12px]"
role="navigation"
aria-label="<?php echo esc_attr($texts['breadcrumb_nav']); ?>"
itemscope
itemtype="https://schema.org/BreadcrumbList"
data-region="<?php echo esc_attr($current_region); ?>">
<span class="absolute !w-[1px] !h-[1px] !p-0 !m-[-1px] overflow-hidden !clip-[rect(0,0,0,0)] !border-0">
<?php echo esc_html($texts['you_are_here']); ?>
</span>
<ol class="[&>li>a]:!no-underline flex items-center gap-[8px] text-[14px] leading-[20px] flex-wrap" role="list">
<!-- Главная -->
<li class="flex items-center"
itemscope
itemprop="itemListElement"
itemtype="https://schema.org/ListItem">
<a href="<?php echo esc_url($home_breadcrumb['item']); ?>"
class="font-[600] text-[14px] leading-[125%] text-[#222] hover:text-[#9d9994] dark:hover:text-[#9d9994] dark:text-[#f8f8f8] flex gap-[6px] items-center"
itemprop="item"
title="<?php echo esc_attr('Перейти на главную страницу'); ?>">
<?php echo $home_icon_svg; ?>
<span itemprop="name"><?php echo esc_html($home_breadcrumb['name']); ?></span>
</a>
<meta itemprop="position" content="<?php echo esc_attr($home_breadcrumb['position']); ?>">
<?php if (!empty($breadcrumbs)): ?>
<span class="select-none ml-[8px] flex items-center" aria-hidden="true">
<?php echo $separator_svg; ?>
</span>
<?php endif; ?>
</li>
<?php foreach ($breadcrumbs as $index => $crumb):
$is_last = ($index === count($breadcrumbs) - 1);
?>
<li class="flex items-center"
itemscope
itemprop="itemListElement"
itemtype="https://schema.org/ListItem">
<?php if (!$is_last): ?>
<a href="<?php echo esc_url($crumb['item']); ?>"
class="hover:text-[#222] text-[#6c6b6b] dark:text-[#6c6b6b] dark:hover:text-[#f8f8f8] transition font-[500] leading-[125%] text-[14px]"
itemprop="item"
title="<?php echo esc_attr('Перейти в раздел: ' . $crumb['name']); ?>">
<span itemprop="name"><?php echo esc_html($crumb['name']); ?></span>
</a>
<?php else: ?>
<span class="text-[#6c6b6b] dark:text-[#6c6b6b] font-[500] leading-[125%] text-[14px]"
itemprop="name"
aria-current="page">
<?php echo esc_html($crumb['name']); ?>
</span>
<?php endif; ?>
<meta itemprop="position" content="<?php echo esc_attr($crumb['position']); ?>">
<?php if (!$is_last): ?>
<span class="select-none ml-[8px] flex items-center"
aria-hidden="true">
<?php echo $separator_svg; ?>
</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ol>
</nav>
<script type="application/ld+json">
<?php echo json_encode($yandex_schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); ?>
</script>
<?php
return true;
}
}
if (!function_exists('display_yandex_breadcrumbs')) {
function display_yandex_breadcrumbs()
{
if (is_front_page() || is_home() || is_admin()) {
return;
}
generate_yandex_breadcrumbs();
}
}