✏️ 正在编辑: breadcrumb.php
路径:
/home/h359620/public_html/wp-content/themes/datis/inc/includes/breadcrumb.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php /** * Datis Breadcrumb * Minimal breadcrumb with JSON-LD schema for Datis theme. * * Usage (template): datis_breadcrumbs(); * Usage (shortcode): [datis_breadcrumbs] */ if (! defined('ABSPATH')) { exit; } if (! class_exists('Datis_Breadcrumb')) { final class Datis_Breadcrumb { private static $instance = null; /** * Default args (filterable via `datis_breadcrumb_args`) */ private $args = [ 'show_on_front' => false, 'show_current' => true, 'wrap_class' => 'datis-breadcrumb', 'list_class' => 'datis-breadcrumb-list', 'item_class' => 'datis-breadcrumb-item', 'link_class' => 'datis-breadcrumb-link', 'current_class' => 'is-current', 'separator' => '/', 'text_domain' => 'datis', 'print_schema' => true, ]; public static function get_instance(): self { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->args = apply_filters('datis_breadcrumb_args', $this->args); add_shortcode('datis_breadcrumbs', [$this, 'shortcode']); add_action('wp_head', [$this, 'print_json_ld']); } private function __clone() {} public function __wakeup() { throw new \Exception('Cannot unserialize singleton'); } public function shortcode($atts = []): string { $atts = shortcode_atts([], $atts, 'datis_breadcrumbs'); return $this->render(false); } /** * Render HTML */ public function render(bool $echo = true, array $override_args = []): string { $a = wp_parse_args($override_args, $this->args); $trail = $this->build_trail($a); $trail = apply_filters('datis_breadcrumb_trail', $trail); if (empty($trail)) { return ''; } $separator_html = apply_filters( 'datis_breadcrumb_separator', $a['separator'] ); $total = count($trail); $html_items = ''; foreach ($trail as $index => $node) { $is_last = ($index === $total - 1); $is_current = ! empty($node['current']); $classes = [$a['item_class']]; if ($is_current) { $classes[] = $a['current_class']; } $html_items .= '<li class="' . esc_attr(implode(' ', $classes)) . '">'; $label_is_html = ! empty($node['is_html']); $label = $label_is_html ? $node['label'] : esc_html($node['label']); if (! empty($node['url']) && ! $is_current) { $html_items .= '<a class="' . esc_attr($a['link_class']) . '" href="' . esc_url($node['url']) . '">'; $html_items .= $label; $html_items .= '</a>'; } else { $html_items .= $label; } $html_items .= '</li>'; if (! $is_last && ! empty($separator_html)) { $html_items .= '<li class="datis-breadcrumb-sep">' . $separator_html . '</li>'; } } $nav = '<nav class="' . esc_attr($a['wrap_class']) . '" aria-label="' . esc_attr__('Breadcrumb', $a['text_domain']) . '">'; $nav .= '<ol class="' . esc_attr($a['list_class']) . '">'; $nav .= $html_items; $nav .= '</ol>'; $nav .= '</nav>'; $nav = apply_filters('datis_breadcrumb_html', $nav, $trail, $a); if ($echo) { echo $nav; return ''; } return $nav; } /** * Build trail as array of nodes */ private function build_trail(array $a): array { $trail = []; $home_label = apply_filters( 'datis_breadcrumb_home_label', __('Home', $a['text_domain']) ); $home_icon = apply_filters( 'datis_breadcrumb_home_icon', '' ); $home_html = esc_html($home_label); if (! empty($home_icon)) { $home_html = $home_icon . '<span class="datis-breadcrumb-home-text">' . esc_html($home_label) . '</span>'; } // Home $trail[] = [ 'label' => $home_html, 'url' => home_url('/'), 'current' => (is_front_page() && ! $a['show_on_front']), 'is_html' => true, ]; // Front page if (is_front_page()) { if (! $a['show_on_front']) { $trail[0]['current'] = true; return $trail; } $trail[0]['current'] = true; return $trail; } // Blog page if (is_home() && ! is_front_page()) { $page_for_posts = (int) get_option('page_for_posts'); $label = $page_for_posts ? get_the_title($page_for_posts) : __('Blog', $a['text_domain']); $trail[] = [ 'label' => $label, 'url' => '', 'current' => true, ]; return $trail; } // Post type archive if (is_post_type_archive()) { $obj = get_queried_object(); $label = ! empty($obj->labels->name) ? $obj->labels->name : post_type_archive_title('', false); $trail[] = [ 'label' => wp_strip_all_tags($label), 'url' => '', 'current' => true, ]; return $trail; } // Taxonomy (category / tag / custom tax) if (is_tax() || is_category() || is_tag()) { $term = get_queried_object(); if ($term && ! is_wp_error($term)) { $tax_obj = get_taxonomy($term->taxonomy); $post_types = ($tax_obj && ! empty($tax_obj->object_type)) ? $tax_obj->object_type : []; if (! empty($post_types)) { $pt = reset($post_types); $pto = get_post_type_object($pt); if ($pto && ! empty($pto->has_archive)) { $trail[] = [ 'label' => $pto->labels->name, 'url' => get_post_type_archive_link($pt), 'current' => false, ]; } } $this->append_term_ancestors($trail, $term); $trail[] = [ 'label' => $term->name, 'url' => '', 'current' => true, ]; return $trail; } } // Author archive if (is_author()) { $author = get_queried_object(); $trail[] = [ 'label' => sprintf(__('Author: %s', $a['text_domain']), $author->display_name), 'url' => '', 'current' => true, ]; return $trail; } // Date archive if (is_date()) { if (is_year()) { $trail[] = [ 'label' => get_the_date(_x('Y', 'yearly archives date format', $a['text_domain'])), 'url' => '', 'current' => true, ]; } elseif (is_month()) { $trail[] = [ 'label' => get_the_date(_x('F Y', 'monthly archives date format', $a['text_domain'])), 'url' => '', 'current' => true, ]; } elseif (is_day()) { $trail[] = [ 'label' => get_the_date(_x('j F Y', 'daily archives date format', $a['text_domain'])), 'url' => '', 'current' => true, ]; } return $trail; } // Search if (is_search()) { $trail[] = [ 'label' => sprintf(__('Search results for "%s"', $a['text_domain']), get_search_query()), 'url' => '', 'current' => true, ]; return $trail; } // 404 if (is_404()) { $trail[] = [ 'label' => __('404', $a['text_domain']), 'url' => '', 'current' => true, ]; return $trail; } // Singular (post / page / CPT) if (is_singular()) { $post = get_queried_object(); $post_type = get_post_type($post); if ($post_type && $post_type !== 'post') { $pto = get_post_type_object($post_type); if ($pto && ! empty($pto->has_archive)) { $trail[] = [ 'label' => $pto->labels->name, 'url' => get_post_type_archive_link($post_type), 'current' => false, ]; } } // Page ancestors if ($post_type === 'page') { $parents = array_reverse(get_post_ancestors($post->ID)); foreach ($parents as $parent_id) { $trail[] = [ 'label' => get_the_title($parent_id), 'url' => get_permalink($parent_id), 'current' => false, ]; } } if ($post_type === 'post') { $page_for_posts = (int) get_option('page_for_posts'); if ($page_for_posts) { $trail[] = [ 'label' => get_the_title($page_for_posts), 'url' => get_permalink($page_for_posts), 'current' => false, ]; } else { $trail[] = [ 'label' => __('Blog', $a['text_domain']), 'url' => home_url('/'), 'current' => false, ]; } } if ($a['show_current']) { $trail[] = [ 'label' => get_the_title($post), 'url' => '', 'current' => true, ]; } return $trail; } return $trail; } /** * Term ancestors */ private function append_term_ancestors(array &$trail, $term): void { $parents = []; $pid = (int) $term->parent; while ($pid) { $parent = get_term($pid, $term->taxonomy); if (is_wp_error($parent) || ! $parent) { break; } $parents[] = $parent; $pid = (int) $parent->parent; } if ($parents) { $parents = array_reverse($parents); foreach ($parents as $p) { $trail[] = [ 'label' => $p->name, 'url' => get_term_link($p), 'current' => false, ]; } } } public function print_json_ld(): void { if (is_admin() || is_feed()) { return; } $a = $this->args; $enabled = apply_filters('datis_breadcrumb_schema_enabled', ! empty($a['print_schema'])); if (! $enabled) { return; } $trail = $this->build_trail($a); if (empty($trail)) { return; } $items = []; $position = 1; $current_url = $this->current_url(); foreach ($trail as $node) { $name = wp_strip_all_tags(is_string($node['label']) ? $node['label'] : ''); $url = ! empty($node['url']) ? $node['url'] : $current_url; if ($name === '') { continue; } $items[] = [ '@type' => 'ListItem', 'position' => $position++, 'name' => $name, 'item' => esc_url_raw($url), ]; } if (empty($items)) { return; } $graph = [ '@context' => 'https://schema.org', '@type' => 'BreadcrumbList', 'itemListElement' => $items, ]; $graph = apply_filters('datis_breadcrumb_schema_graph', $graph, $trail); echo "\n<script type=\"application/ld+json\">" . wp_json_encode($graph, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "</script>\n"; } private function current_url(): string { $scheme = is_ssl() ? 'https' : 'http'; if (! empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) { $forwarded = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_PROTO'])); if ('https' === $forwarded) { $scheme = 'https'; } } $host = $_SERVER['HTTP_HOST'] ?? parse_url(home_url(), PHP_URL_HOST); $uri = $_SERVER['REQUEST_URI'] ?? '/'; return $scheme . '://' . $host . $uri; } } // Bootstrap Datis_Breadcrumb::get_instance(); // Template tag if (! function_exists('datis_breadcrumbs')) { function datis_breadcrumbs(array $args = []): void { Datis_Breadcrumb::get_instance()->render(true, $args); } } }
💾 保存文件
← 返回文件管理器