Jekyll /液体模板:如何按年分组博客post?

我正在改写我的博客使用Jekyll。 Jekyll使用了Liquid模板语言,所以它使得学习如何定制变得更加困难。

我想在一年中将我的博客post分组。 我将如何写液体代码才能做到这一点?

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

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

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

如果你想把它分解成一年和几个月,可以这样来实现:

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

这只是你在哪里做循环的问题。

与现有的答案相比,可以用更less的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 %} 

这将完全返回您的问题中指定的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> 

但是,这不是最佳解决scheme,因为年份数字也是“唯一”列表项目。
将年份放入标题并为每年的post开始一个新的<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 %} 

生成的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> 

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

为此,只需要按date: "%Y"replacedate: "%Y" (在上述两个示例的第二行中) date: "%B %Y"
%B是完整的月份名称,请参阅文档 )

这些以前的解决scheme非常棒,但在2016年底幸运的是, Jekyll添加了一个group_by_expfilter,可以做得更干净。

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

文档可以在Jekyll模板页面find 。

尝试:

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

上面的一些解决scheme是非常复杂的,但是@Trevor指出,我们可以从Jekyll的group_by_expfilter中获益 。 此外,我喜欢这个解决scheme,但是我需要的是按年份分组,然后按月分组。 所以,我稍微调整了一下。

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