Каковы некоторые хорошие способы реализации панировочных сухарей на сайте Jekyll?

Я знаю, что в 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" участников "" вверху.

Вот мой макет. Да, это уродливо. Я не много изучил Жидкость. Можете ли вы предложить лучший способ?

<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>

Ответ 1

Это должно дать панировочные сухари на любой глубине (с оговоркой, см. конец). К сожалению, фильтры Liquid довольно ограничены, поэтому это неустойчивое решение: в любое время /index.html появляется, оно удаляется, что приведет к поломке URL-адресов, у которых есть папка, начинающаяся с index.html (например, /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>

Как это работает:

  • отделяет URL-адрес, игнорируя index.html (например, /a/b/index.html становится a b, /a/b/c.html становится a b c.html),
  • последовательно принимает и удаляет первое слово url_parts, чтобы перебирать все, кроме последнего слова (например, он идет a b c.html → (a, b c.html) → (b, c.html), а затем остановимся).
  • на каждом шаге он делает ссылку с использованием текущей first_word и previous, которая является всеми предыдущими каталогами (в примере выше она будет идти """/a""/a/b")

NB. page.content в цикле for - это просто дать что-то итерацию, волшебство выполняется с помощью 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 в качестве заполнителя вместо page.content.

Вот пример (он не использует точно тот же код, что и выше, но это всего лишь несколько небольших изменений).

Ответ 2

Я немного улучшил ответы, высказанные ранее. Я удалил неупорядоченный список и разделил элементы символом (косой чертой). Я добавил фильтр для "index.html" и ".html", поэтому также поддерживаются такие ссылки, как "mysite.com/path/index.html" и "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

Ответ 3

Я сделал следующие панировочные сухари с жидкими шаблонами, которые были такими же изящными, как я мог бы управлять:) Он использует jQuery для установки активного класса в последнем элементе 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>

Ответ 5

Подумал, что я могу бросить это в микс. Это основано на приведенном выше примере 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>

Ответ 6

Мне удалось просто еще больше. Вот что я сейчас использую:

{% 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>

Ответ 7

Вот как я применил сухарь на сайте, который я унаследовал, который основан на некоторых других версиях здесь. В нашем случае некоторые из наших папок не содержали страницу 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>

Ответ 8

И я улучшил ответ JoostS, чтобы иметь следующие возможности:

  • Замените разделитель пути//на правый треугольник (▶ & # 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 %}
    

Ответ 9

Здесь мое решение, которое работает с Jekyll 3.1.3 и GitHub Pages на сегодняшний день. Как и некоторые другие решения, они просто проверяют 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 %}

Ответ 10

Я нашел альтернативный метод, который не является полностью автоматическим, но работает на страницах 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>

Подробнее см. в этой статье и ссылки на реализацию.

Ответ 11

Я подумал о автоматической панировке, в которой также отображается хороший текст элемента палитры из 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>

breadcrumb отобразит следующие

<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>