保哥笔记

为Shopify的Blog页面添加面包屑导航和配套的面包屑结构化数据

Shopify有很多主题不支持多级Blog导航,如何为你的Shopify改造成以下的面包屑导航:

Blog首页:全站页首 > 博客首页
Blog分类页:全站页首 > 博客首页 > 博客分类页
Blog文章页:全站页首 > 博客首页 > 博客分类页 > 博客文章页

下面保哥为你讲解具体的操作方案和步骤:

创建Blog首页

先创建一个Blog分类,URL为/blog/all,作为Blog首页

为Blog首页创建模板

为这个Blog分类创建一个模板,并将/blog/all页面的模板样式绑定这个Blog模板,将所有分类及分类下的6篇文章进行调用

编辑breadcrumb.liquid代码

将以下代码替换原来的breadcrumb.liquid代码

{% assign _breadcrumb_mobile = settings.breadcrumb_mobile %}
{% assign _breadcrumb_styles = settings.breadcrumb_styles %}

{% if template contains 'customers' or template == 'page' %}
  {% capture _breadcrumb_image %} {{ 'breadcrumb_bg.jpg' | asset_url }} {% endcapture %}
{% else %}
  {% capture _breadcrumb_image %} {{ sectionhttps://www.holkieusa.com.settings.breadcrumb_image | img_url: '1920x' }} {% endcapture %}
  {% if section.settings.breadcrumb_image == blank %}{% capture _breadcrumb_image %} {{ 'breadcrumb_bg.jpg' | asset_url }} {% endcapture %}{% endif %}
{% endif %}

<div class="wrap-breadcrumb bw-{{ _breadcrumb_styles }} {% unless _breadcrumb_mobile %} d-none d-md-block{% endunless %}"{% if _breadcrumb_styles == 'image' %} style="background-image: url({{_breadcrumb_image }});"{% endif %}>
  <div id="breadcrumb" class="breadcrumb-holder container">
        <ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
          <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
            <a itemprop="item" href="/">
              <span itemprop="name" class="d-none">Home</span>{{ 'general.text.home' | t }}
              <meta itemprop="position" content="1" /> 
            </a>
          </li>
          {% if template contains 'product' or template contains 'collection' %}
            {% comment %} Get breadcrumb path from metafields {% endcomment %}
            {% assign breadcrumb_path = nil %}
            {% if template contains 'product' %}
              {% assign breadcrumb_path = product.metafields.custom.breadcrumb_path.value %}
            {% elsif template contains 'collection' %}
              {% assign breadcrumb_path = collection.metafields.custom.breadcrumb_path.value %}
            {% endif %}
            {% if breadcrumb_path %}
              {% assign position_counter = 2 %}
              {% for crumb in breadcrumb_path %}
                {% assign crumb_url = '/collections/' | append: crumb.handle %}
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                  <a href="{{ crumb_url }}" itemprop="item">
                    <span itemprop="name">{{ crumb.name }}</span>
                    <meta itemprop="position" content="{{ position_counter }}" />
                  </a>
                </li>
                <li>{{ crumb.name | link_to: crumb_url }}</li>
                {% assign position_counter = position_counter | plus: 1 %}
              {% endfor %}
            {% endif %}
          {% endif %}
          {% if template contains 'product' %}
            {% comment %} Set product position based on path existence {% endcomment %}
            {% assign product_position = position_counter | default: 2 %}
            <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
              <a href="{{product.url}}" itemprop="item">
                <span itemprop="name">{{ product.title }}</span>
                <meta itemprop="position" content="{{ product_position }}" />
              </a>
            </li>
            <li class="active">{{ product.title }}</li>
          {% elsif template contains 'collection' %}
            {% if current_tags %}
              {% comment %} Tag filtering - show tag as last item {% endcomment %}
              <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                <a href="{{collection.url}}" itemprop="item">
                  <span itemprop="name">{{ collection.title }}</span>
                  <meta itemprop="position" content="{{ position_counter }}" />
                </a>
              </li>
              <li>{{ collection.title | link_to: collection.url }}</li>
              
              {% assign tag_position = position_counter | plus: 1 | default: 3 %}
              <li itemprop="itemListElement" itemscopehttps://www.holkieusa.com itemtype="http://schema.org/ListItem" class="d-none">
                <a href="{{collection.url}}/{{ current_tags.first }}" itemprop="item">
                  <span itemprop="name">{{ current_tags.first }}</span>
                  <meta itemprop="position" content="{{ tag_position }}" />
                </a>
              </li>
              <https://www.holkieusa.comli class="active">{{ current_tags.first }}</li>
            {% else %}
              {% comment %} Default collection view {% endcomment %}
              {% if breadcrumb_path == blank %}
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                  <a href="{{collection.url}}" itemprop="item">
                    <span itemprop="name">{{ collection.title }}</span>
                    <meta itemprop="position" content="{{ position_counter | default: 2 }}" />
                  </a>
                </li>
              {% endif %}
              <li class="active">{{ collection.title }}</li>
            {% endif %}

          {% comment %} show all {% endcomment %}
          {% elsif template == 'blog' %}
            {% if blog.handle == 'all' or request.path == '/blogs/all' %}
            {% comment %} blog all - 特殊处理当前位置 {% endcomment %}
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="active">
                 <a itemprop="item" href="{{ canonical_url }}">
                   <span itemprop="name">All Blog</span>
                   <meta itemprop="position" content="2" />
                 </a>
               </li>
            {% else %}
            {% comment %} blog collections {% endcomment %}
             <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                <a itemprop="item" href="/blogs/all">
                      <span itemprop="name">All Blog</span>
                      <meta itemprop="position" content="2" />
                </a>
               </li>
               <li>{{ 'All Blog' | link_to: "/blogs/all" }}</li>
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                  <a itemprop="item" href="{{ blog.url }}">
                     <span itemprop="name">{{ blog.title }}</span>
                     <meta itemprop="position" content="3" />
                  </a>
                </li>
                 <li class="active">{{ blog.title }}</li>
                 {% endif %}
          {% elsif template == 'article' %}
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                <a itemprop="item" href="/blogs/all">
                      <span itemprop="name">All Blog</span>
                      <meta itemprop="position" content="2" />
                </a>
               </li>
               <li>{{ 'All Blog' | link_to: "/blogs/all" }}</li>
            {% comment %} blog collections {% endcomment %}
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                  <a itemprop="item" href="{{ blog.url }}">
                     <span itemprop="name">{{ blog.title }}</span>
                     <meta itemprop="position" content="3" />
                  </a>
                </li>
                     <li>{{ blog.title | link_to: blog.url }}</li>
            {% comment %} blog article {% endcomment %}
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="d-none">
                  <a itemprop="item" href="{{ article.url }}">
                     <span itemprop="name">{{ article.title }}</span>
                     <meta itemprop="position" content="4" />
                  </a>
                </li>
                <li class="active">{{ article.title }}</li>
            {% else %}
                <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem" class="active">
          <a itemprop="item" href="{{ canonical_url }}">
            <span itemprop="name">{{ page_title }}</span>
            <meta itemprop="position" content="2" />
          </a>
        </li>
            {% endif %}
        </ul>
  </div>
</div>

保存即可。

设置301跳转

将系统的/blog这个打开404状态的页面设置跳转到/blogs/all

内容 —— 菜单 —— 创建URL重定向

将/blog跳转到/blogs/all

常见问答解答

  1. 修改breadcrumb.liquid代码后,面包屑样式和主题原有样式(如颜色、字体)冲突,怎么调整?
    需在代码中补充主题样式类或自定义CSS:①先查看主题原有面包屑的样式类(如通过浏览器“检查元素”找到breadcrumb容器的class,假设为theme-breadcrumb);②将代码中wrap-breadcrumb的class改为wrap-breadcrumb theme-breadcrumb,继承主题样式;③若仍有差异(如分隔符、间距),在代码末尾添加<style>标签,例如:.breadcrumb li { margin: 0 8px; } .breadcrumb li::after { content: ">"; margin-left: 8px; },按需调整样式属性。
  2. 我的Blog有三级分类(如“All Blog>科技分类>AI子分类”),原文代码只支持两级分类,怎么修改代码实现三级面包屑?
    需在“Blog分类页”和“Article文章页”逻辑中补充子分类层级:①先确保Shopify后台的Blog子分类URL格式为/blogs/科技分类/AI子分类;②在代码{% elsif template == 'blog' %}(分类页逻辑)中,添加子分类判断:{% if blog.handle contains '科技分类' and request.path contains 'AI子分类' %},然后插入子分类面包屑项:<li>{{ '科技分类' | link_to: "/blogs/科技分类" }}</li><li class="active">AI子分类</li>;③同步调整itemprop="position"的数值(子分类设为3,分类名设为2),确保结构化数据正确。
  3. 设置301跳转后,之前外部网站链接到/blog的URL会不会失效?对SEO有影响吗?
    不会失效,且对SEO友好:①301是“永久重定向”,搜索引擎会自动将/blog的权重转移到/blogs/all,不会导致权重流失;②外部链接访问/blog时,会自动跳转到/blogs/all,用户无感知;③建议在Google Search Console或百度资源平台提交“更改地址”请求,加速搜索引擎识别重定向,进一步减少SEO影响。
  4. 使用原文代码后,移动端面包屑完全不显示,怎么排查和解决?
    问题源于代码中的移动端隐藏逻辑,排查步骤:①查看代码中{% unless _breadcrumb_mobile %} d-none d-md-block{% endunless %}——d-none d-md-block表示“移动端隐藏,桌面端显示”;②若主题支持settings.breadcrumb_mobile设置,进入Shopify后台“主题设置→面包屑”,勾选“移动端显示面包屑”;③若主题无此设置,直接删除代码中的{% unless _breadcrumb_mobile %} d-none d-md-block{% endunless %},或改为d-block(强制所有设备显示),保存后刷新移动端即可。
  5. 改造后,Blog文章页的面包屑显示的“Blog分类名”和实际分类名不一致(如实际是“时尚”,显示成“Fashion”),怎么排查?
    多因代码中分类名调用逻辑或Blog设置问题,排查步骤:①检查Shopify后台“Blog分类”的“标题”是否为中文(若标题是“Fashion”,面包屑会同步显示,需改为“时尚”);②查看代码中{{ blog.title }}的调用位置——文章页逻辑中{{ blog.title | link_to: blog.url }}是调用当前文章所属Blog的标题,若分类名错误,需确认文章是否正确归属到目标分类(进入文章编辑页,“博客”选项需选对分类);③若仍错误,替换代码中的blog.titlearticle.blog.title,强制调用文章所属分类的标题。
  6. Shopify后台将Blog首页标题从“Blog”改成“博客中心”后,面包屑里的“All Blog”没同步更新,怎么修改代码?
    需将代码中硬编码的“All Blog”改为动态调用Blog标题:①找到代码中所有'All Blog'的位置(共3处:Blog分类页、Article文章页的链接文本);②将'All Blog'替换为blogs['all'].titleblogs['all']表示URL为/blogs/all的Blog首页,title会动态获取后台设置的标题);③例如原代码{{ 'All Blog' | link_to: "/blogs/all" }}改为{{ blogs['all'].title | link_to: "/blogs/all" }},保存后面包屑会同步显示后台修改的标题。
  7. 主题自动升级后,之前修改的breadcrumb.liquid代码被覆盖,面包屑恢复原状,怎么避免或快速恢复?
    避免与恢复方案:①避免覆盖:提前将修改后的breadcrumb.liquid文件备份(下载到本地),并在Shopify后台“主题→操作→编辑代码”中,将该文件重命名(如改为breadcrumb-custom.liquid),再在主题的“布局文件”(如theme.liquid)中,将调用原面包屑的代码{% section 'breadcrumb' %}改为{% include 'breadcrumb-custom' %},后续主题升级不会影响自定义文件;②快速恢复:若已被覆盖,直接将备份的代码重新粘贴到breadcrumb.liquid,或上传重命名的自定义文件并修改布局调用。
  8. 想在面包屑的每个层级之间添加“>”分隔符,原文代码没显示分隔符,怎么添加?
    需通过CSS或HTML添加分隔符,两种方式任选:①CSS方式:在代码末尾添加<style> .breadcrumb li:not(:last-child)::after { content: ">"; margin: 0 8px; color: #666; } </style>not(:last-child)表示不为最后一项添加,避免多余分隔符);②HTML方式:在每个<li>标签后添加<span class="separator">></span>,例如</li><span class="separator">></span><li>,再通过CSS调整分隔符样式(如颜色、间距)。
  9. 多语言店铺(如中英文),面包屑里的“全站页首”和“All Blog”怎么实现多语言切换?
    需使用Shopify的多语言翻译功能:①进入Shopify后台“设置→语言”,添加目标语言(如中文);②在“翻译”界面,搜索“面包屑”相关关键词:“general.text.home”对应“全站页首”(可修改中文翻译为“首页”);③找到“博客”相关翻译,将blogs['all'].title的中文翻译设为“博客首页”(对应英文“Blog Center”);④代码中无需修改,{{ 'general.text.home' | t }}blogs['all'].title会自动根据用户选择的语言显示对应文本(| t是多语言过滤标签)。
  10. 怎么检查/blog/blogs/all的301跳转是否生效?有没有快速验证的方法?
    有3种简单验证方法:①直接访问:在浏览器地址栏输入https://你的店铺域名/blog,若自动跳转到https://你的店铺域名/blogs/all,且地址栏URL变化,说明跳转生效;②工具验证:使用在线HTTP状态码工具(如https://httpstatus.io/),输入/blog的URL,查看返回状态码是否为“301 Moved Permanently”,且“Location”字段显示/blogs/all;③Shopify后台验证:进入“内容→菜单→URL重定向”,查看该重定向的“状态”是否为“启用”,且无报错提示。
  11. 原文代码中提到settings.breadcrumb_mobilesettings.breadcrumb_styles,我的主题没有这些设置项,会导致代码报错吗?怎么处理?
    可能导致报错(如显示“undefined”),需修改代码屏蔽未定义设置:①找到代码开头的{% assign _breadcrumb_mobile = settings.breadcrumb_mobile %}{% assign _breadcrumb_styles = settings.breadcrumb_styles %};②改为带默认值的赋值,例如:{% assign _breadcrumb_mobile = settings.breadcrumb_mobile | default: true %}(默认移动端显示)、{% assign _breadcrumb_styles = settings.breadcrumb_styles | default: 'text' %}(默认文本样式,避免背景图报错);③同时将代码中{% if _breadcrumb_styles == 'image' %}改为{% if _breadcrumb_styles == 'image' and section.settings.breadcrumb_image != blank %},防止无背景图时样式错乱。
  12. 想让面包屑里的“博客首页”链接到自定义页面(如/pages/blog-home,而非/blogs/all),怎么修改代码?
    需修改代码中“博客首页”的链接路径和调用逻辑:①先确保自定义页面/pages/blog-home已创建并发布;②找到代码中所有/blogs/all的位置(共3处:Blog分类页、Article文章页的链接URL),替换为/pages/blog-home;③找到代码中blogs['all'].title的位置(若已修改过动态标题),改为pages['blog-home'].title,动态调用自定义页面的标题;④若自定义页面不是Blog类型,无需创建Blog模板,直接确保该页面能正常访问即可,面包屑会正确链接到自定义页面。