在Jekyll网站上实施面包屑有哪些好方法?

时间:2012-03-08 02:45:18

标签: breadcrumbs jekyll liquid

我知道http://raphinou.github.com/jekyll-base/中存在单级面包屑,但我正在寻找一些好方法,当目录达到四个或五个级别的深度时,在Jekyll网站上有面包屑

(是的,我很清楚Jekyll主要是一个博客引擎,也许我不应该将它用于通用网站,特别是在许多目录级别。我也知道http://octopress.org但是没有找到合适的插件。)

在很大程度上基于http://forums.shopify.com/categories/2/posts/22172我想出了以下面包屑的Jekyll布局,您可以在http://crimsonfu.github.com/members/pdurbin看到其中的变体。你应该在顶部看到面包屑“ home»members»”。

这是我的布局。是的,这很难看。我还没有学过液体。你能建议一个更好的方法吗?

<html>
<head>
<title>{{ page.title }}</title>
<style type="text/css">
#bread ul {
  padding-left: 0;
  margin-top: 2px;
  margin-bottom: 2px;
} 
#bread ul li {
  display: inline;
  font-size: 70%;
}
</style>
</head>
<body>
<div id="bread">
<ul>

{% assign url = {{page.url}} %}
{% assign delimiter = '/' %}
{% capture allparts %}{{ url | replace: delimiter, ' ' }}{% endcapture %}

{% capture myFirstWord  %}{{ allparts    | truncatewords: 1 | remove: '...' }}{% endcapture %}
{% capture minusFirst   %}{{ allparts    | replace_first: myFirstWord, ''   }}{% endcapture %}

{% capture mySecondWord %}{{ minusFirst  | truncatewords: 1 | remove: '...' }}{% endcapture %}
{% capture minusSecond  %}{{ minusFirst  | replace_first: mySecondWord, ''  }}{% endcapture %}

{% capture myThirdWord  %}{{ minusSecond | truncatewords: 1 | remove: '...' }}{% endcapture %}
{% capture minusThird   %}{{ minusSecond | replace_first: myThirdWord, ''   }}{% endcapture %}

{% capture myFourthWord %}{{ minusThird  | truncatewords: 1 | remove: '...' }}{% endcapture %}
{% capture minusFourth  %}{{ minusThird  | replace_first: myFourthWord, ''  }}{% endcapture %}

{% capture myFifthWord  %}{{ minusFourth | truncatewords: 1 | remove: '...' }}{% endcapture %}

{% if myFirstWord contains '.html' %}
  <li><a href="/">home</a> &nbsp; </li>
{% elsif mySecondWord contains '.html' %}
  <li><a href="/">home</a> &#187; </li>
  {% unless mySecondWord == 'index.html' %}
  <li><a href="/{{myFirstWord}}">{{myFirstWord}}</a> &#187; </li>
  {% endunless %}
{% elsif myThirdWord contains '.html' %}
  <li><a href="/">home</a> &#187; </li>
  <li><a href="/{{myFirstWord}}">{{myFirstWord}}</a> &#187; </li>
  {% unless myThirdWord == 'index.html' %}
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}">{{mySecondWord}}</a> &#187; </li>
  {% endunless %}
{% elsif myFourthWord contains '.html' %}
  <li><a href="/">home</a> &#187; </li>
  <li><a href="/{{myFirstWord}}">{{myFirstWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}">{{mySecondWord}}</a> &#187; </li>
  {% unless myFourthWord == 'index.html' %}
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}/{{myThirdWord}}">{{myThirdWord}}</a> &#187; </li>
  {% endunless %}
{% elsif myFifthWord contains '.html' %}
  <li><a href="/">home</a> &#187; </li>
  <li><a href="/{{myFirstWord}}">{{myFirstWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}">{{mySecondWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}/{{myThirdWord}}">{{myThirdWord}}</a> &#187; </li>
  {% unless myFifthWord == 'index.html' %}
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}/{{myThirdWord}}/{{myFourthWord}}">{{myFourthWord}}</a> &#187; </li>
  {% endunless %}
{% else %}
  <li><a href="/">home</a> &#187; </li>
  <li><a href="/{{myFirstWord}}">{{myFirstWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}">{{mySecondWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}/{{myThirdWord}}">{{myThirdWord}}</a> &#187; </li>
  <li><a href="/{{myFirstWord}}/{{mySecondWord}}/{{myThirdWord}}/{{myFourthWord}}">{{myFourthWord}}</a> &#187; </li>
{% endif %}
</ul>
</div>
<h1>{{ page.title }}</h1>
{{ content }}
</body>
</html>

12 个答案:

答案 0 :(得分:14)

我对前面给出的答案略有改进。我删除了无序列表,并用一个字符(正斜杠)分隔了这些项目。我为&#39; index.html&#39;添加了一个过滤器和&#39; .html&#39;,所以网址如&#39; mysite.com/path/index.html'和&#39; mysite.com/path/item-name.html'也支持。最后,我将这些头衔资本化了。这会产生如下情况:

主页/路径/项目名称

{% assign crumbs = page.url | remove:'/index.html' | split: '/' %}

<a href="/">Home</a>
{% for crumb in crumbs offset: 1 %}
  {% if forloop.last %}
    / {{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}
  {% else %}
    / <a href="{% assign crumb_limit = forloop.index | plus: 1 %}{% for crumb in crumbs limit: crumb_limit %}{{ crumb | append: '/' }}{% endfor %}">{{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}</a>
  {% endif %}
{% endfor %}

PS。我已经为这样的代码段创建了一个在线资源:jekyllcodex.org/without-plugins

答案 1 :(得分:7)

这应该给任何深度的面包屑(有警告,见结束)。不幸的是,Liquid过滤器相当有限,所以这是一个不稳定的解决方案:任何时候出现/index.html,它都会被删除,这将破坏具有以index.html开头的文件夹的URL(例如{{1}希望这不会发生。

/a/index.html/b/c.html

工作原理是:

  • 分隔网址,忽略{% capture url_parts %} {{ page.url | remove: "/index.html" | replace:'/'," " }}{% endcapture %} {% capture num_parts %}{{ url_parts | number_of_words | minus: 1 }}{% endcapture %} {% assign previous="" %} <ol> {% if num_parts == "0" or num_parts == "-1" %} <li><a href="/">home</a> &nbsp; </li> {% else %} <li><a href="/">home</a> &#187; </li> {% for unused in page.content limit:num_parts %} {% capture first_word %}{{ url_parts | truncatewords:1 | remove:"..."}}{% endcapture %} {% capture previous %}{{ previous }}/{{ first_word }}{% endcapture %} <li><a href="{{previous}}">{{ first_word }}</a> &#187; </li> {% capture url_parts %}{{ url_parts | remove_first:first_word }}{% endcapture %} {% endfor %} {% endif %} </ol> (例如index.html变为/a/b/index.htmla b变为/a/b/c.html),
  • 连续取下并移除a b c.html的第一个单词,以迭代除最后一个单词之外的所有单词(例如,它变为url_parts - &gt;(a b c.htmla) - &gt;(b c.htmlb);然后我们停止)。
  • 在每一步中,它使用当前c.htmlfirst_word使用当前所有目录(使用上面的示例,它将previous - &gt;来生成面包屑链接; "" - &gt; "/a"

NB。 for循环中的"/a/b"只是为了迭代,魔术由page.content完成。但是,这意味着,如果limit:num_parts的段落少于page.content,则不会显示所有面包屑,如果可能的话,可能会在num_parts _config.yml中定义一个网站变量并使用breadcrumb_list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]作为占位符而不是site.breadcrumb_list

Here is an example(它没有使用与上面完全相同的代码,但只是进行了一些修改)。

答案 2 :(得分:3)

我使用液体模板制作了以下面包屑,它尽可能地优雅:)它使用jQuery在li last li项目上设置活动类。

            <ul class="breadcrumb">
                <li><a href="#"><i class="icon-home"></i>Home</a> </li>
                {% assign crumbs = page.url | split: '/' %}
                {% assign crumbstotal = crumbs | size %}
                {% for crumb in crumbs offset:2 %}
                    {% unless crumb == 'index.html' %}
                        <li><span class="divider">&#187;</span> {{ crumb | remove: '.html' }} </li>
                    {% endunless %}
                {% endfor %}
            </ul>
                            <script>$(".breadcrumb li").last().addClass('active');</script>

答案 3 :(得分:2)

This plugin似乎有点强大。

答案 4 :(得分:2)

这是我在我继承的网站中实现面包屑的方式,这是基于其他一些版本的。在我们的例子中,我们的一些文件夹不包含index.html页面。因此,单击链接到没有index.html的文件夹的面包屑会导致错误。这可以通过更好的文件结构来消除,但我无法改变它。

这是我想出的。

<ol class="pull-right breadcrumb">
            <li><a href="/">Home</a></li>
            {% assign crumbs = page.url | split: '/' %}
            {% assign crumbs_total = crumbs | size | minus: 1 %}
            {% for crumb in crumbs offset: 1 %}
                {% if forloop.index == crumbs_total %}
                    <li class="active"><a href="{{ site.baseurl }}{{ page.url }}">{{page.title}}</a></li>
                {% else %}
                    {% assign crumb_limit = forloop.index | plus: 1 %}
                    {% capture crumb_url %}{% for c in crumbs limit: crumb_limit %}{{ c | append: '/' }}{% endfor %}{% endcapture %}
                    {% capture crumb_with_index %}{{ crumb_url | append: 'index.html' }}{% endcapture %}
                    {% capture current_page %}{{ site.baseurl }}{{ page.url }}{% endcapture %}
                    {% for p in site.pages %}
                        {% if crumb_with_index != current_page and crumb_with_index == p.url %}
                            <li><a href="{{ crumb_with_index }}">{{ crumb | replace:'-',' ' | capitalize}}</a>
                        {% endif %}
                    {% endfor %}
                {% endif %}
            {% endfor %}
        </ol>

答案 5 :(得分:2)

这是我的解决方案,与今天的Jekyll 3.1.3和GitHub页面一起使用。像其他人给出的一些解决方案一样,它只是检查页面的URL并从中构建面包屑。

{% unless page.hide-breadcrumbs %}
  <ul class="breadcrumb">
    <li><a href="/">{{site.title}}</a> </li>
    {% assign crumbs = page.url | split: '/' %}
    {% for crumb in crumbs offset:1 %}
      <li {% if forloop.last %}class="active"{% endif %}>
        {% unless forloop.last %}
          <a href="/{% for crumb in crumbs offset:1 limit:forloop.index %}{{crumb}}/{% endfor %}">
            {{ crumb | capitalize }}
          </a>
        {% else %}
          {{ crumb | capitalize }}
        {% endunless %}
      </li>
    {% endfor %}
  </ul>
{% endunless %}

答案 6 :(得分:2)

我找到了一种不完全自动但可以在GitHub页面上运行的替代技术。

它包括使用可能路径列表创建数据文件。 例如,我的网站_data/breadcrumbs.csv为:

url,title
/,Home
/api/,API
/api/jsonarray/,JsonArray
/api/jsonbuffer/,JsonBuffer
/api/jsonobject/,JsonObject
/api/jsonvariant/,JsonVariant
/doc/,Manual
/example/,Examples
/news/,News
/faq/,FAQ

然后,一个简单的循环创建了痕迹:

<ol class="breadcrumb">
  {% for crumb in site.data.breadcrumbs %}
    {% assign url_prefix = page.url | slice: 0, crumb.url.size %}
    {% if (url_prefix == crumb.url) and (page.url != crumb.url) %}
    <li class="breadcrumb-item">
      <a href="{{ crumb.url | prepend: site.baseurl }}">
        {{ crumb.title }}
      </a>
    </li>
    {% endif %}
  {% endfor %}
  <li class="breadcrumb-item active">
    <a href="{{ page.url | prepend: site.baseurl }}">
      {{ page.title }}
    </a>
  </li>
</ol>

有关详细信息和实施的链接,请参阅this article

答案 7 :(得分:1)

以为我可能会把它扔进去。这是基于Davelab6的上述示例,并进行了一些改进。活动类由循环中的最后一个条目设置 - 还包含每个碎屑的永久链接。

我尚未对帖子进行过测试 - 但它应该可行。如果有任何问题,请告诉我。

<ul class="breadcrumbs">
 <li><a href="/">Home</a></li>
 {% assign crumbs = page.url | split: '/' %}
 {% assign crumbs_total = crumbs | size | minus: 1 %}
   {% for crumb in crumbs offset: 1 %}
    {% if forloop.index == crumbs_total %}
        <li class="active">{{ crumb | replace:'-',' ' }}</li>
    {% else %}
        <li><a href="{% assign crumb_limit = forloop.index | plus: 1 %}{% for crumb in crumbs limit: crumb_limit %}{{ crumb | append: '/' }}{% endfor %}">{{ crumb | replace:'-',' ' }}</a>
    {% endif %}
  {% endfor %}
</ul>

答案 8 :(得分:1)

我设法更进一步。以下是我现在使用的内容:

{% assign crumbs = page.url | split: '/' %}

<ul class="lv-breadcrumbs">
    <li><a href="/">Home</a></li>
    {% for crumb in crumbs offset: 1 %}
        {% if forloop.last %}
            <li class="active">{{ crumb | replace:'-',' ' }}</li>
        {% else %}
            <li><a href="{% assign crumb_limit = forloop.index | plus: 1 %}{% for crumb in crumbs limit: crumb_limit %}{{ crumb | append: '/' }}{% endfor %}">{{ crumb | replace:'-',' ' }}</a></li>
        {% endif %}
    {% endfor %}
</ul>

答案 9 :(得分:1)

我想到了一个自动痕迹,还显示了来自 frontmatter 的漂亮的痕迹痕迹元素文字。

在GitHub页面上完美运行

在这里查看: http://blog.comsysto.com/2015/04/25/automatic-breadcrumb-for-jekyll-on-github-pages/

如果您有此设置:

<强> /mypage1/index.html

---
layout: default
title: My Page 1 - My Homepage
breadcrumb: My Page 1
---
<div class="container">
  <div class="row">
    <div class="col-md-12">
      peace yo!
    </div>
  </div>
</div>

<强> /mypage1/subpage1/index.html

---
layout: default
title: My Sub Page 1 - My Homepage
breadcrumb: My Sub Page 1
---
<div class="container">
  <div class="row">
    <div class="col-md-12">
      foobar!
    </div>
  </div>
</div>

面包屑将呈现以下内容

<ol class="breadcrumb">
  <li><a href="/">Home</a></li>
  <li><a href="/mypage1/index.html">My Page 1</a></li>
  <li class="active"><a href="/mypage1/subpage1/index.html">My Sub Page 1</a></li>
</ol>

答案 10 :(得分:1)

我已经改进了JoostS的回应,具备以下功能:

  • 用右向三角形替换“/”路径分隔符(▶&amp;#9654;)
  • 如果存在,请使用最终页面前面的breadcrumb:

    {% assign crumbs = page.url | remove:'/index.html' | split: '/' %}
    
    <a href="/">Home</a>
    {% for crumb in crumbs offset: 1 %}
      {% if forloop.last %}
        {% if page.breadcrumb != '' %}
          &#9654; <a href="#">{{ page.breadcrumb }} </a>
        {% else %}
          &#9654; <a href="#">{{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}</a>
        {% endif %}
      {% else %}
          &#9654; <a href="{% assign crumb_limit = forloop.index | plus: 1 %}{% for crumb in crumbs limit: crumb_limit %}{{ crumb | append: '/' }}{% endfor %}">{{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}</a>
      {% endif %}
    {% endfor %}
    

答案 11 :(得分:0)

这是解决此问题的另一种方法:与其从URL生成帖子的面包屑,不如使用帖子的集合,类别,日期(年,月,日)和标题来形成面包屑。这意味着面包屑不必与URL匹配(尽管您仍然可以将其匹配)。这意味着类别,年份等的面包屑可以找到并链接到这些类别,年份等的页面(如果存在)。

生成的面包屑如下:

主页>帖子>示例类别> 2019> 12月> 23> Jekyll的面包屑

有一些选项可以省略住所,馆藏,类别,日期和标题中的每个部分,因此您可以自定义面包屑,以显示自己想要的样子。

面包屑将自动链接到相应的页面(如果该页面存在)。例如,首页面包屑将链接到URL“ /”的页面。如果存在,则“ foo”类别的面包屑将链接到“ / foo /”的页面(否则,该面包屑将不会被链接)。 2019年的面包屑将链接到“ / 2019 /”页面。依此类推。

模板粘贴在下面。用法:{% include breadcrumbs.html %}。有关更多详细信息,请参见我的gistblog post

_includes/breadcrumbs.html

{% assign omit_home = include.omit_home %}
{% if omit_home == nil %}
{% assign omit_home = site.breadcrumbs_omit_home %}
{% endif %}

{% assign omit_collection = include.omit_collection %}
{% if omit_collection == nil %}
{% assign omit_collection = site.breadcrumbs_omit_collection %}
{% endif %}

{% assign omit_categories = include.omit_categories %}
{% if omit_categories == nil %}
{% assign omit_categories = site.breadcrumbs_omit_categories %}
{% endif %}

{% assign omit_date = include.omit_date %}
{% if omit_date == nil %}
{% assign omit_date = site.breadcrumbs_omit_date %}
{% endif %}

{% assign omit_year = include.omit_year %}
{% if omit_year == nil %}
{% assign omit_year = site.breadcrumbs_omit_year %}
{% endif %}

{% assign omit_month = include.omit_month %}
{% if omit_month == nil %}
{% assign omit_month = site.breadcrumbs_omit_month %}
{% endif %}

{% assign omit_day = include.omit_day %}
{% if omit_day == nil %}
{% assign omit_day = site.breadcrumbs_omit_day %}
{% endif %}

{% assign breadcrumbs = "" | split: "" %}

{% if page.url == "/" %}
{% assign is_front_page = true %}
{% else %}
{% assign is_front_page = false %}
{% endif %}

{% unless is_front_page %}
{% assign page = include.page | default: page %}
{% unless omit_home %}
    {% capture breadcrumb_text %}{% include breadcrumb_text.html url="/" default="Home" %}{% endcapture %}
    {% assign breadcrumb_text = breadcrumb_text | split: "?" %}
    {% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}
{% endunless %}

{% unless omit_collection or page.collection == nil %}
{% assign collection_slug = page.collection | replace: " ", "-" | downcase | url_encode %}
{% assign collection_page_url = "/" | append: collection_slug | append: "/" %}
{% capture breadcrumb_text %}{% include breadcrumb_text.html url=collection_page_url default=page.collection %}{% endcapture %}
{% assign breadcrumb_text = breadcrumb_text | split: "?" %}
{% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}

{% unless omit_categories %}
{% for category in page.categories %}
    {% assign category_slug = category | replace: " ", "-" | downcase | url_encode %}
    {% assign category_page_url = "/" | append: category_slug | append: "/" %}
    {% capture breadcrumb_text %}{% include breadcrumb_text.html url=category_page_url default=category %}{% endcapture %}
    {% assign breadcrumb_text = breadcrumb_text | split: "?" %}
    {% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endfor %}
{% endunless %}

{% unless omit_date or page.date == nil %}
{% assign year = page.date | date: "%Y" %}
{% assign year_page_url = "/" | append: year | append: "/" %}
{% assign month_int = page.date | date: "%m" %}
{% assign month_page_url = year_page_url | append: month_int | append: "/" %}
{% assign day_int = page.date | date: "%d" %}
{% assign day_page_url = month_page_url | append: day_int | append: "/" %}

{% unless omit_year %}
    {% capture breadcrumb_text %}{% include breadcrumb_text.html url=year_page_url default=year %}{% endcapture %}
    {% assign breadcrumb_text = breadcrumb_text | split: "?" %}
    {% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}

{% unless omit_month %}
    {% assign month_str = page.date | date: "%b" %}
    {% capture breadcrumb_text %}{% include breadcrumb_text.html url=month_page_url default=month_str %}{% endcapture %}
    {% assign breadcrumb_text = breadcrumb_text | split: "?" %}
    {% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}

{% unless omit_day %}
    {% assign day_str = page.date | date: "%e" %}
    {% capture breadcrumb_text %}{% include breadcrumb_text.html url=day_page_url default=day_str %}{% endcapture %}
    {% assign breadcrumb_text = breadcrumb_text | split: "?" %}
    {% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}
{% endunless %}

{% unless is_front_page %}
{% if page.title == nil %}
    {% assign title = page.name %}
{% else %}
    {% assign title = page.title %}
{% endif %}
{% capture breadcrumb_text %}<strong>{{ title }}</strong>{% endcapture %}
{% assign breadcrumb_text = breadcrumb_text | split: "?" %}
{% assign breadcrumbs = breadcrumbs | concat: breadcrumb_text %}
{% endunless %}

{% if breadcrumbs != empty %}
<nav style="display: inline-block;">
    {% for breadcrumb in breadcrumbs %}{{ breadcrumb }}{% endfor %}
</nav>
{% endif %}

_includes/breadcrumb_text.html

{% assign breadcrumb_page = nil %}
{% for page in site.pages %}
{% if page.url == include.url %}
    {% assign breadcrumb_page = page %}
    {% break %}
{% endif %}
{% endfor %}

{% assign breadcrumb_text = breadcrumb_page.breadcrumb_text | default: breadcrumb_page.title | default: include.default %}

{% unless breadcrumb_page == nil %}
<a href="{{ breadcrumb_page.url | relative_url }}">{{ breadcrumb_text }}</a>
{% else %}
{{ breadcrumb_text }}
{% endunless %}
>