【问题标题】:WordPress breadcrumbs in search results搜索结果中的 WordPress 面包屑
【发布时间】:2025-11-28 19:50:02
【问题描述】:

在 WordPress 中,我目前使用Yoast's SEO Plugin 为我的页面和帖子显示breadcrumbs,这在访问特定页面时工作正常。

这是我用来在我的 WordPress 模板中显示面包屑的函数:

<?php if ( function_exists('yoast_breadcrumb') ) {
    yoast_breadcrumb('<p id="breadcrumbs">','</p>');
} ?>

例如,当浏览到Team Members 这是About Us 的孩子时,我得到:

Home > About Us > Team Members

但是我希望能够在搜索结果循环中显示相同的面包屑(针对单个页面和帖子)。

到目前为止,搜索Members 时显示的是:

您的搜索结果:

Team Members 
Home > Search > Members

Members Area 
Home > Search > Members

但我不想要搜索结果页面的面包屑,我希望它们用于作为搜索关键字的结果显示的各个页面和帖子。

例如,假设我再次搜索Members 我想显示以下内容:

您的搜索结果:

Team Members 
Home > About Us > Team Members

Members Area 
Home > Members Area

我不介意这是否与 SEO 插件集成,但到目前为止,这是我发现在 WordPress 中显示面包屑的最佳解决方案!

如果有人需要,这里是我的search.php 文件:http://pastebin.com/0qjb2954

【问题讨论】:

    标签: php wordpress breadcrumbs


    【解决方案1】:

    试试这个。这是我自己的工作 sn-p,它在搜索循环中显示面包屑。

    /*Begin Loop */
    <?php 
    echo '<div class="b-search_result_list__item_breadcrumbs breadcrumbs">';
    
    $current_type = get_post_type();
    if ($current_type == 'page') {
    
        $parents = get_post_ancestors(get_the_ID());
        if($parents){
    
            for($i=count($parents)-1;$i>=0;$i--){
                echo '<span typeof="v:Breadcrumb">';
                echo '<a rel="v:url" property="v:title" title="'.get_the_title($parents[$i]).'" href="'.get_permalink($parents[$i]).'">'.get_the_title($parents[$i]).'</a>';
                echo '</span>';
            }
        }else{
            echo '<span typeof="v:Breadcrumb">';
            echo '<a rel="v:url" property="v:title" title="'.get_bloginfo('name').'" href="'.get_bloginfo('url').'">'.get_bloginfo('name').'</a>';
            echo '</span>';
        }
        echo '<span typeof="v:Breadcrumb">';
        echo '<span property="v:title">'.get_the_title().'</span>';
        echo '</span>';
    }else{
        $current_obj = get_post_type_object($current_type);
    
            echo '<span typeof="v:Breadcrumb">';
            echo '<a rel="v:url" property="v:title" title="'.get_bloginfo('name').'" href="'.get_bloginfo('url').'">'.get_bloginfo('name').'</a>';
            echo '</span>';
            echo '<span typeof="v:Breadcrumb">';
            echo '<a rel="v:url" property="v:title" title="'.$current_obj->labels->name.'" href="'.get_post_type_archive_link( $current_type ).'">'.$current_obj->labels->name.'</a>';
            echo '</span>';
    
            $current_taxonomies = get_object_taxonomies($current_type);
    
            if($current_taxonomies){
                $current_terms = get_the_terms(get_the_ID(), $current_taxonomies[0]);
    
                if($current_terms){
                    $current_term = array_shift($current_terms);
    
                    echo '<span typeof="v:Breadcrumb">';
                        echo '<a rel="v:url" property="v:title" title="'.$current_term->name.'" href="'.get_term_link($current_term).'">'.$current_term->name.'</a>';
                    echo '</span>';
    
                    /*
                    var_dump($current_obj->labels->name); // Archive name
                    var_dump(get_post_type_archive_link( $current_type )); // Archive link
                    var_dump($current_term->name);  // Term name
                    var_dump(get_term_link($current_term)); // Term link
                    var_dump(get_permalink()); // Post link 
                    */
                }
            }
            echo '<span typeof="v:Breadcrumb">';
            echo '<span property="v:title">'.get_the_title().'</span>';
            echo '</span>';
    
    }    
    
    echo '</div>';
    ?>
    /*End Loop*/
    

    【讨论】:

      【解决方案2】:

      尝试在 search.php 文件中的 yoast 面包屑函数上方添加这行代码:

      WPSEO_Breadcrumbs::$instance = NULL;
      

      我相信这将是第 22 行,并确保使用您问题中的 Yoast 面包屑函数,而不是现在的新面包屑()函数。

      如果可行,请告诉我!

      完整解释:

      Yoast 插件面包屑功能基于页面加载构建,基于当前页面作为子页面。为了让它加载正确的孩子和父母,你需要在运行函数之前重置它。没有内置的重置功能,但是将静态 $instance 设置为 NULL 应该会导致插件根据循环时设置的当前全局 post 对象重新生成其数据。

      【讨论】:

      • @Giles 你测试了吗?
      • 看起来这是不可能的。即使在重置实例之后,插件也会使用 is_singular() 来确定当前页面是否为帖子,并且此函数不能被覆盖。因此,即使它在重置实例后加载了正确的帖子,它也会根据当前页面的类型(帖子/存档/类别/等)选择错误类型的面包屑来显示。
      • 5 年后,仍然像魅力一样工作。谢谢雅沃尔!
      【解决方案3】:

      根据 Yavor 的回答,我找到了一种方法。几个小时以来一直在敲我的头。不过,您可以将备份和恢复放在循环之外。这里是:

      global $wp_query;
      //backup
      $old_singular_value = $wp_query->is_singular;
      //change
      $wp_query->is_singular = true;
      //reset
      WPSEO_Breadcrumbs::$instance = NULL;
      //breadcrumbs
      if (function_exists('yoast_breadcrumb')){
          yoast_breadcrumb('<p id="breadcrumbs">','</p>');
      }
      //restore
      $wp_query->is_singular = $old_singular_value;
      

      它伪造查询以使其成为单数,因此新刷新的面包屑认为这不是搜索页面,而是单个帖子或页面或您作为搜索结果显示的任何内容。

      【讨论】:

        【解决方案4】:

        使用插件生成面包屑并不是真正必要的。这是一个简单的 PHP 函数,您可以将其添加到 functions.php 文件中:

        function breadcrumbs() {
            global $post;
            echo "<ul id='breadcrumbs'>";
            if (!is_home()) {
                echo '<li><a href="' . get_option('home') . '">Home</a></li>';
                if (is_category() || is_single()) {
                    echo "<li>" . the_category(' </li><li> ');
                    if (is_single()) {
                        echo "</li><li>" . the_title() . "</li>";
                    }
                } elseif (is_page()) {
                    if($post->post_parent){
                        foreach ( get_post_ancestors( $post->ID ) as $ancestor ) {
                            echo '<li><a href="' . get_permalink($ancestor) . '" title="' . get_the_title($ancestor) . '">' . get_the_title($ancestor) . '</a></li>' .  get_the_title();
                        }
                    } else {
                        echo "<li>" . get_the_title() . "</li>";
                    }
                }
            } elseif (is_tag()) {
                single_tag_title();
            } elseif (is_day()) {
                echo "<li>Archive for " . the_time('F jS, Y') . "</li>";
            } elseif (is_month()) {
                echo "<li>Archive for " . the_time('F, Y') . "</li>";
            } elseif (is_year()) {
                echo "<li>Archive for " . the_time('Y') . "</li>";
            } elseif (is_author()) {
                echo "<li>Author Archive</li>";
            } elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {
                echo "<li>Blog Archives</li>";
            } elseif (is_search()) {
                echo "<li>Search Results for" . the_search_query() . "</li>";
            }
            echo "</ul>";
        }
        

        连同一些 CSS 来设置样式,随心所欲地自定义

        #breadcrumbs {
            list-style:none;
            margin:5px 0;
            overflow:hidden;
        }
        
        #breadcrumbs li{
            float:left;
        }
        #breadcrumbs li+li:before {
            content: '| ';
            padding:0 4px;
        }
        

        然后,您可以在您喜欢的任何页面上实现这些面包屑,包括您的 searchpage.php 文件或您用于通过此调用显示搜索结果的任何文件

        <?php breadcrumbs(); ?>
        

        【讨论】:

        • 很抱歉刚刚发现了一些语法错误,但现在应该一切都好。几周没接触过 php,所以让我知道它是怎么回事,不过应该可以正常工作。
        • 搜索结果总是只比 home 高 1 级,不是吗?
        • 当然!但是我不需要搜索结果页面的面包屑我需要搜索关键字时找到的页面的面包屑。例如查看我的问题,我希望页面的面包屑与标题和摘录一起出现。
        • 稍微修改了 php 代码的搜索部分.. 不确定它是否是您要找的。不过替我上床睡觉。希望你能弄清楚。
        • 为您的帮助干杯!恐怕不是。我很快会重新编辑我的问题,让其他人有更好的机会理解我,啊哈。
        【解决方案5】:

        搜索页面有一个可以使用的conditional function。您始终可以将其应用于加载面包屑。这是一个例子:

        if ( ! is_search() ) {
            if ( function_exists('yoast_breadcrumb') ) {
                yoast_breadcrumb('<p id="breadcrumbs">','</p>');
            }
        }
        

        这也取决于您加载面包屑的位置,但这通常应该有效,除非您的主题非常独特。

        【讨论】: