Jekyll/Liquid Templating:如何按年度对博客文章进行分组?

And*_*rew 40 liquid jekyll

我正在改写我的博客以使用Jekyll.Jekyll使用Liquid模板语言,因此学习如何自定义更加困难.

我想按年份将我的博客帖子分组.如何编写Liquid代码才能执行此操作?

{% for post in site.posts %}
  <li><!-- display post year here (but only once, per year) --></li>
  <li>
    <a href="{{ post.url }}">{{ post.title }}</a>
  </li>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

Chr*_*cht 57

它可以使用比现有答案更多的液体代码来完成:

{% for post in site.posts %}
  {% assign currentdate = post.date | date: "%Y" %}
  {% if currentdate != date %}
    <li id="y{{currentdate}}">{{ currentdate }}</li>
    {% assign date = currentdate %} 
  {% endif %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

这将完全返回您问题中指定的HTML:

<li id="y2013">2013</li>
<li><a href="/2013/01/01/foo/">foo</a></li>
<li id="y2012">2012</li>
<li><a href="/2012/02/01/bar/">bar</a></li>
<li><a href="/2012/01/01/baz/">baz</a></li>
Run Code Online (Sandbox Code Playgroud)

但是,这不是最佳解决方案,因为年份数字也是"仅"列表项.
将年份放入标题并<ul>为每年的帖子开始新的内容并不是更多的液体代码:

{% for post in site.posts %}
  {% assign currentdate = post.date | date: "%Y" %}
  {% if currentdate != date %}
    {% unless forloop.first %}</ul>{% endunless %}
    <h1 id="y{{post.date | date: "%Y"}}">{{ currentdate }}</h1>
    <ul>
    {% assign date = currentdate %}
  {% endif %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% if forloop.last %}</ul>{% endif %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

生成的HTML:

<h1 id="y2013">2013</h1>
<ul>
<li><a href="/2013/01/01/foo/">foo</a></li>
</ul>
<h1 id="y2012">2012</h1>
<ul>
<li><a href="/2012/02/01/bar/">bar</a></li>
<li><a href="/2012/01/01/baz/">baz</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

您也可以按月和年分组(以便标题为February 2012,January 2012等等).

要做到这一点,你只需要更换date: "%Y" (在这两个上面例子的第二行)通过date: "%B %Y".
(%B是完整的月份名称,请参阅文档)


Raf*_*ido 33

如果你想按年分解,这是代码:

{% for post in site.posts  %}
    {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
    {% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}

    {% if forloop.first %}
    <h2 id="{{ this_year }}-ref">{{this_year}}</h2>
    <ul>
    {% endif %}

    <li><a href="{{ post.url }}">{{ post.title }}</a></li>

    {% if forloop.last %}
    </ul>
    {% else %}
        {% if this_year != next_year %}
        </ul>
        <h2 id="{{ next_year }}-ref">{{next_year}}</h2>
        <ul>
        {% endif %}
    {% endif %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

如果你想将其分解为年和月,可以这样实现:

{% for post in site.posts  %}
    {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
    {% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %}
    {% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
    {% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %}

    {% if forloop.first %}
    <h2 id="{{ this_year }}-ref">{{this_year}}</h2>
    <h3 id="{{ this_year }}-{{ this_month }}-ref">{{ this_month }}</h3>
    <ul>
    {% endif %}

    <li><a href="{{ post.url }}">{{ post.title }}</a></li>

    {% if forloop.last %}
    </ul>
    {% else %}
        {% if this_year != next_year %}
        </ul>
        <h2 id="{{ next_year }}-ref">{{next_year}}</h2>
        <h3 id="{{ next_year }}-{{ next_month }}-ref">{{ next_month }}</h3>
        <ul>
        {% else %}    
            {% if this_month != next_month %}
            </ul>
            <h3 id="{{ this_year }}-{{ next_month }}-ref">{{ next_month }}</h3>
            <ul>
            {% endif %}
        {% endif %}
    {% endif %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

这只是你在哪里进行切割的问题.


Tre*_*vor 23

这些先前的解决方案非常棒,但幸运的是在2016年底,Jekyll添加了一个group_by_exp可以更干净地完成这一过程过滤器.

{% assign postsByYear =
    site.posts | group_by_exp:"post", "post.date | date: '%Y'" %}
{% for year in postsByYear %}
  <h1>{{ year.name }}</h1>
    <ul>
      {% for post in year.items %}
        <li><a href="{{ post.url }}">{{ post.title }}-{{ post.date }}</a></li>
      {% endfor %}
    </ul>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

可以在Jekyll模板页面上找到文档.


Ank*_*iya 7

上面的一些解决方案非常复杂,但随后@Trevor指出我们可以使用Jekyll的group_by_exp过滤器.我也喜欢这个解决方案,但我需要的是按年份分组,然后在按月分组的列表中.所以,我稍微调整了一下.

{% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'" %}
    {% for year in postsByYear %}
      <h1>{{ year.name }}</h1>
      {% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: '%B'" %}

      {% for month in postsByMonth %}
        <h2>{{ month.name }}</h2>
        <ul>
          {% for post in month.items %}
            <li><a href="{{ post.url }}">{{ post.title }}-{{ post.date }}</a></li>
          {% endfor %}
        </ul>

      {% endfor %}
    {% endfor %}
Run Code Online (Sandbox Code Playgroud)


Sco*_*ner 6

Ankit R Gadiya答案的变。内部for循环显示 html 代码。我需要取消缩进以使其正确呈现标记。我还添加了帖子的摘录:

{% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'" %}
{% for year in postsByYear %}
  <h1>{{ year.name }}</h1>
  {% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: '%B'" %}

{% for month in postsByMonth %}
<h2>{{ month.name }}</h2>
<ul>
  {% for post in month.items %}
    <li>
      <a href="{{ post.url }}">{{ post.title }}</a>
      <br>{{ post.excerpt }}
    </li>
  {% endfor %}
</ul>

{% endfor %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

例子:

例子