web-dev-qa-db-ja.com

JekyllとLiquidを使用したナビゲーションメニューの並べ替え

Jekyll/Liquidで静的なサイト(ブログなし)を構築しています。既存のすべてのページを一覧表示し、現在のページを強調表示する自動生成されたナビゲーションメニューが必要です。アイテムは特定の順序でメニューに追加する必要があります。したがって、ページのYAMLでweightプロパティを定義します。

---
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フィルターは無視されるようです。明らかに、私は何か間違ったことをしているが、何がわかるのか分からない。

68
flyx

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ソリューションと比較してビルド時間を大幅に節約できます。

編集:あなた[〜#〜] must [〜#〜]ソートプロパティを整数として割り当てるweight: 10および文字列としてではないweight: "10"

ソートプロパティを文字列として割り当てると、「1、10、11、2、20、...」などの文字列ソートになります。

74
David Jacquel

あなたの唯一のオプションは、二重ループを使用しているようです。

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

Uい、それは動作するはずです。重みのないページもある場合は、{% unless p.weight %}現在の内部の前後。

36
kikito

以下のソリューションはGithubで動作します(プラグインは不要です):

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

上記のスニペットは、ページをファイル名でソートします(Pageオブジェクトのname属性はファイル名から派生しています)。希望の順序に一致するようにファイル名を変更しました:00-index.md01-about.md –そしてpresto!ページが注文されます。

1つの落とし穴は、これらの番号のプレフィックスがURLで終わるということです。これは、ほとんどのページでは扱いにくく、00-index.htmlでの実際の問題です。救助へのPermalilnks:

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

追伸賢くて、ソートのためだけにカスタム属性を追加したかったのです。残念ながら、カスタム属性はPageクラスのメソッドとしてアクセスできないため、並べ替えには使用できません。

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

この問題を解決する簡単なJekyllプラグインを作成しました。

  1. sorted_for.rbhttps://Gist.github.com/3765912 からJekyllプロジェクトの_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. forの代わりにsorted_forパラメーターを指定したタグsort_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>
15
Jan Dupal

簡単な解決策:

最初に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>
10
sdmeyers

最も簡単な解決策は、次のようなインデックスをページのファイル名の前に付けることです。

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

ページはファイル名順に並べられます。ただし、今はyouいURLがあります。

Yamlフロントマターセクションでは、permalink変数を設定して、生成されたURLをオーバーライドできます。

例えば:

---
layout: default
permalink: index.html
---
10
Mark Meeus

ジェネレーターを使用してこれを解決しました。ジェネレーターはページを反復処理し、ナビゲーションデータを取得し、ソートして、サイト構成にプッシュします。そこから、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 %}

_pluginsフォルダーのファイルに次のコードを配置します。

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

私はJekyllとRubyが初めてなので、これを理解するのにかなりの時間を費やしてきました。

5
kevin

以下のコードは、Jekyll/Liquidがカテゴリの要件に一致する場合に動作します。

  • 既存のすべてのページへのリンクを作成し、
  • 重みで並べ替え(カテゴリごとの並べ替えでも機能します)、
  • 現在のページを強調表示します。

それらの上に、投稿数も表示されます。すべてはプラグインなしで行われます。

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

ネットワーキングページのアクションで確認してください。投稿をクリックしてナビゲーションを強調表示したり、特定のリンクをクリックして、重みが割り当てられているソースページに移動したりできます。

1
Chetabahana

重量とタグでソートし、数を10に制限しようとしている場合、次のコードを実行します。

{% 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 %} 
0
Tom Johnson