development

Jekyll 및 Liquid로 정렬 된 탐색 메뉴

big-blog 2020. 11. 6. 21:02
반응형

Jekyll 및 Liquid로 정렬 된 탐색 메뉴


Jekyll / Liquid로 정적 사이트 (블로그 없음)를 구축하고 있습니다. 모든 기존 페이지를 나열하고 현재 페이지를 강조 표시하는 자동 생성 탐색 메뉴를 갖고 싶습니다. 항목은 특정 순서로 메뉴에 추가되어야합니다. 따라서 weight페이지의 YAML에 속성을 정의합니다 .

---
layout : default
title  : Some title
weight : 5
---

탐색 메뉴는 다음과 같이 구성됩니다.

<ul>
  {% for p in site.pages | sort:weight %}
    <li>
      <a {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">
        {{ p.title }}
      </a>
    </li>
  {% endfor %}
</ul>

이렇게하면 모든 기존 페이지에 대한 링크가 생성되지만 정렬되지 않고 sort필터가 무시되는 것 같습니다. 분명히 내가 뭔가 잘못하고 있지만 무엇을 알 수는 없습니다.


Jekyll 2.2.0부터는 객체 속성별로 객체 배열을 정렬 할 수 있습니다. 이제 다음을 수행 할 수 있습니다.

{% assign pages = site.pages | sort:"weight"  %}
<ul>
  {% for p in pages %}
    <li>
      <a {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">
        {{ p.title }}
      </a>
    </li>
  {% endfor %}
</ul>

@kikito 솔루션에 비해 빌드 시간이 많이 절약됩니다.

편집 : 정렬 속성을 문자열이 아닌 정수로 지정 해야 합니다 .weight: 10weight: "10"

정렬 속성을 문자열로 지정하면 "1, 10, 11, 2, 20, ..."과 같은 문자열 정렬로 끝납니다.


유일한 옵션은 이중 루프를 사용하는 것 같습니다.

<ul>
{% for weight in (1..10) %}
  {% for p in site.pages %}
    {% if p.weight == weight %}
      <li>
        <a {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">
          {{ p.title }}
        </a>
      </li>
    {% endif %}
  {% endfor %}
{% endfor %}
</ul>

못생긴 그대로 작동해야합니다. 가중치가없는 페이지도있는 경우 {% unless p.weight %}현재 내부 루프 이전 / 이후에 수행하는 추가 내부 루프를 포함해야합니다 .


아래 솔루션은 Github에서 작동합니다 (플러그인이 필요하지 않음).

{% assign sorted_pages = site.pages | sort:"name" %}
{% for node in sorted_pages %}
  <li><a href="{{node.url}}">{{node.title}}</a></li>
{% endfor %}

위의 스 니펫은 파일 이름별로 페이지를 정렬합니다 ( name페이지 개체의 속성은 파일 이름에서 파생 됨). 원하는 순서에 맞게 파일 이름을 변경했습니다. 00-index.md, 01-about.md– 및 presto! 페이지가 정렬됩니다.

한 가지 문제는 이러한 번호 접두사가 URL에 들어가기 때문에 대부분의 페이지에서 어색해 보이고 00-index.html에서는 실제 문제입니다. 구조에 대한 Permalilnks :

---
layout: default
title: News
permalink: "index.html"
---

추신 : 나는 영리하고 정렬을 위해 사용자 정의 속성을 추가하고 싶었습니다. 안타깝게도 사용자 지정 속성은 Page 클래스의 메서드로 액세스 할 수 없으므로 정렬에 사용할 수 없습니다.

{% assign sorted_pages = site.pages | sort:"weight" %} #bummer

이 문제를 해결하기 위해 간단한 Jekyll 플러그인을 작성했습니다.

  1. 복사 sorted_for.rb에서 https://gist.github.com/3765912_plugins당신의 지킬 프로젝트의 하위 디렉토리 :

    module Jekyll
      class SortedForTag < Liquid::For
        def render(context)
          sorted_collection = context[@collection_name].dup
          sorted_collection.sort_by! { |i| i.to_liquid[@attributes['sort_by']] }
    
          sorted_collection_name = "#{@collection_name}_sorted".sub('.', '_')
          context[sorted_collection_name] = sorted_collection
          @collection_name = sorted_collection_name
    
          super
        end
    
        def end_tag
          'endsorted_for'
        end
      end
    end
    
    Liquid::Template.register_tag('sorted_for', Jekyll::SortedForTag)
    
  2. 사용 태그 sorted_for대신 forsort_by:property매개 변수는 주어진 속성에 의해 정렬합니다. reversed원본처럼 추가 할 수도 있습니다 for.
  3. 다른 종료 태그를 사용하는 것을 잊지 마십시오 endsorted_for.

귀하의 경우 사용법은 다음과 같습니다.

<ul>
  {% sorted_for p in site.pages sort_by:weight %}
    <li>
      <a {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">
        {{ p.title }}
      </a>
    </li>
  {% endsorted_for %}
</ul>

가장 간단한 해결책은 페이지의 파일 이름 앞에 다음과 같은 색인을 붙이는 것입니다.

00-home.html 01-services.html 02-page3.html

페이지는 파일 이름별로 정렬됩니다. 그러나 이제는 못생긴 URL을 갖게됩니다.

yaml 머리말 섹션에서 permalink 변수를 설정하여 생성 된 URL을 재정의 할 수 있습니다.

예를 들면 :

---
layout: default
permalink: index.html
---

쉬운 솔루션 :

site.pages먼저 정렬 된 배열을 할당 한 다음 배열 에서 for 루프를 실행합니다.

코드는 다음과 같습니다.

{% assign links = site.pages | sort: 'weight' %}
{% for p in links %}
  <li>
    <a {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">
      {{ p.title }}
    </a>
  </li>
{% endfor %}

이것은 내 navbar에서 작동합니다 _include.

<section id="navbar">
    <nav>
        {% assign tabs = site.pages | sort: 'weight' %}
        {% for p in tabs %}
            <span class="navitem"><a href="{{ p.url }}">{{ p.title }}</a></span>
        {% endfor %}
    </nav>
</section>

나는 발전기를 사용하여 이것을 해결했습니다. 생성기는 페이지를 반복하고 탐색 데이터를 가져 와서 정렬하고 사이트 구성으로 다시 푸시합니다. 거기에서 Liquid는 데이터를 검색하고 표시 할 수 있습니다. 항목 숨기기 및 표시도 처리합니다.

다음 페이지 조각을 고려하십시오.

---
navigation:
  title: Page name
  weight: 100
  show: true
---
content.

탐색은 다음 Liquid 조각으로 렌더링됩니다.

{% for p in site.navigation %}
<li> 
    <a  {% if p.url == page.url %}class="active"{% endif %} href="{{ p.url }}">{{ p.navigation.title }}</a>
</li>
{% endfor %}

Put the following code in a file in your _plugins folder:

module Jekyll

  class SiteNavigation < Jekyll::Generator
    safe true
    priority :lowest

    def generate(site)

        # First remove all invisible items (default: nil = show in nav)
        sorted = []
        site.pages.each do |page|
          sorted << page if page.data["navigation"]["show"] != false
        end

        # Then sort em according to weight
        sorted = sorted.sort{ |a,b| a.data["navigation"]["weight"] <=> b.data["navigation"]["weight"] } 

        # Debug info.
        puts "Sorted resulting navigation:  (use site.config['sorted_navigation']) "
        sorted.each do |p|
          puts p.inspect 
        end

        # Access this in Liquid using: site.navigation
        site.config["navigation"] = sorted
    end
  end
end

I've spent quite a while figuring this out since I'm quite new to Jekyll and Ruby, so it would be great if anyone can improve on this.


I can get the code below works on with Jekyll/Liquid match to your requirement with category:

  • creates links to all existing pages,
  • sorted by weight (works as well on sorting per category),
  • highlight the current page.

On top of them it shows also number of post. All is done without any plug-in.

<ul class="topics">
{% capture tags %}
    {% for tag in site.categories %}
        {{ tag[0] }}
    {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}
    {% for tag in sortedtags %}
    <li class="topic-header"><b>{{ tag }} ({{ site.categories[tag] | size }} topics)</b>
        <ul class='subnavlist'>
        {% assign posts = site.categories[tag] | sort:"weight" %}
        {% for post in posts %}
            <li class='recipe {% if post.url == page.url %}active{% endif %}'>
            <a href="/{{ site.github.project_title }}{{ post.url }}">{{ post.title }}</a>
            </li>
        {% endfor %}
        </ul>
    </li>
    {% endfor %}
</ul>

Check it on action on our networking page. You may click a post to highlight the navigation, as well a given link to bring you to the source page where their weight is assigned.


If you're trying to sort by weight and by tag and limit the number to 10, here's code to do it:

{% assign counter = '0' %}
{% assign pages = site.pages | sort: "weight"  %}
{% for page in pages %}
{% for tag in page.tags %}
{% if tag == "Getting Started" and counter < '9' %}
{% capture counter %}{{ counter | plus:'1' }}{% endcapture %}
<li><a href="{{ page.permalink | prepend: site.baseurl }}">{{page.title}}</a></li>
{% endif %}
{% endfor %}
{% endfor %} 

The solution above by @kikito also worked for me. I just added a few lines to remove pages without weight from the navigation and to get rid of white space:

<nav>
  <ul>
    {% for weight in (1..5) %}
      {% unless p.weight %}
        {% for p in site.pages %}
          {% if p.weight == weight %}
            {% if p.url == page.url %}
              <li>{{ p.title }}</li>
            {% else %}
              <li><a href="{{ p.url }}" title="{{ p.title }}">{{ p.title }}</a></li>
            {% endif %}
          {% endif %}
        {% endfor %}
      {% endunless %}
    {% endfor %}
  </ul>
</nav>

참고URL : https://stackoverflow.com/questions/9053066/sorted-navigation-menu-with-jekyll-and-liquid

반응형