简体   繁体   English

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

[英]Jekyll/Liquid Templating: How to group blog posts by year?

I'm rewriting my blog to use Jekyll.我正在重写我的博客以使用 Jekyll。 Jekyll uses the Liquid templating language so it makes it a little more difficult to learn how to customize. Jekyll 使用 Liquid 模板语言,因此学习如何自定义变得更加困难。

I'd like to group my list of blog posts by year.我想按年份对我的博客文章列表进行分组。 How would I write the Liquid code to be able to do this?我将如何编写 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 %}

It can be done with much, much less Liquid code than in the existing answers:它可以用比现有答案少得多的 Liquid 代码来完成:

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

This will return exactly the HTML specified in your question:这将准确返回您的问题中指定的 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>

However, this is not the optimal solution, because the year numbers are "only" list items as well.但是,这不是最佳解决方案,因为年份数字也是“仅”列表项。
It's not much more Liquid code to put the year into a headline and to begin a new <ul> for each year's posts:将年份放入标题并为每年的帖子开始一个新的<ul>并不是更多的 Liquid 代码:

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

The generated HTML:生成的 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>

You can also group by month and year instead (so that the headlines are February 2012 , January 2012 and so on).您也可以按月和年分组(这样标题是February 2012January 2012 February 2012 January 2012等)。

To do this, you just need to replace date: "%Y" (in the second line of both above examples) by date: "%B %Y" .为此,您只需将date: "%Y" (在上述两个示例的第二行中)替换为date: "%B %Y"
( %B is the full month name, see the documentation ) %B是完整的月份名称,请参阅文档

If you want to break it down by year, here's the code:如果你想按年份分解,这里是代码:

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

If you want to break it down to year and months it can be achieved like this:如果你想把它分解成年和月,可以这样实现:

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

It is only a matter of where do you make the cut on the loop.这只是你在循环上的哪里进行切割的问题。

These previous solutions are fantastic but luckily in late 2016, Jekyll added a group_by_exp filter that can do this much more cleanly.这些以前的解决方案非常棒,但幸运的是,在 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 %}

Documentation can be found on the Jekyll Templates page .文档可以在Jekyll 模板页面找到

Some solutions above are very complex but then as @Trevor pointed out that we can levarage Jekyll's group_by_exp filter.上面的一些解决方案非常复杂,但正如@Trevor指出的那样,我们可以利用 Jekyll 的group_by_exp过滤器。 Also I liked the solution but what I needed was grouped by Year and then inside that list grouped by Month.我也喜欢这个解决方案,但我需要的是按年分组,然后在按月分组的列表中。 So, I tweaked it a little bit.所以,我稍微调整了一下。

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

Try:尝试:

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

  {% if forloop.first %}
  <h2 id="{{ this_year }}-ref">{{this_year}}</h2>
  <ul class="posts">
  {% else %}
      {% if this_year != last_year %}
      </ul>
      <h2 id="{{ this_year }}-ref">{{this_year}}</h2>
      <ul class="posts">
      {% endif %}
  {% endif %}

    <li>
      <span class="post-date">{{ post.date | date_to_string }} &raquo;</span>
      <a href="{{ post.url }}">{{ post.title }}</a>
    </li>

  {% if forloop.last %}
    </ul>
  {% endif %}

  {% capture last_year %}{{ this_year }}{% endcapture %}
{% endfor %}
<ul>
  {% for post in site.posts %}
      {% assign year = post.date | date: "%Y" %}

      {% if year != prev_year %}
        <h3>{{year}}</h3>
      {% endif %}

      <li>
        <span>{{ post.date | date: "%B %e, %Y" }}</span>
        <a href="{{ post.url }}">{{ post.title }}</a>
      </li>
      {% assign prev_year = year %}
  {% endfor %}
</ul>

Did not much like the other answer so here's an alternative for you.不太喜欢另一个答案,所以这里有一个替代方案。 Basic logic: Display year/month only if it "new":基本逻辑:仅在“新”时显示年/月:

{% assign var currentYear = 0 %}
{% assign var currentMonth = 0 %}
{% for post in site.posts  %}
{% capture year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture month %}{{ post.date | date: "%B" }}{% endcapture %}

{% if currentYear != year %}
<div>
  <h2>{{ year }}</h2>
</div>
{% assign var currentYear = year %}
{% endif %}
{% if currentMonth != month %}
<div>
  <h3>{{ month }}</h3>
</div>
{% assign var currentMonth = month %}
{% endif %}
<p>{{ post.title }}</p>
{% endfor %}

Variation of Ankit R Gadiya 's answer . Ankit R Gadiya答案的变化 The inner for loop was displaying the html code.内部for循环显示 html 代码。 I needed to de-indent it to get it to properly render the markup.我需要取消缩进以使其正确呈现标记。 I also added the post's excerpt:我还添加了帖子的摘录:

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

Example:示例:

例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM