Jekyll/Liquid 模板:如何按年份对博客文章进行分组?
Posted
技术标签:
【中文标题】Jekyll/Liquid 模板:如何按年份对博客文章进行分组?【英文标题】:Jekyll/Liquid Templating: How to group blog posts by year? 【发布时间】:2013-10-05 20:20:56 【问题描述】:我正在重写我的博客以使用 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 %
【问题讨论】:
它涉及或涉及捕获,非常可怕。 mikerowecode.com/2010/08/jekyll_archives_grouped_by_year.html 【参考方案1】:它可以用比现有答案少得多的 Liquid 代码来完成:
% for post in site.posts %
% assign currentdate = post.date | date: "%Y" %
% if currentdate != date %
<li id="ycurrentdate"> 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>
但是,这不是最佳解决方案,因为年份数字也是“唯一”列表项。
将年份放入标题并为每年的帖子开始一个新的<ul>
的 Liquid 代码并不多:
% for post in site.posts %
% assign currentdate = post.date | date: "%Y" %
% if currentdate != date %
% unless forloop.first %</ul>% endunless %
<h1 id="ypost.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 2012
、January 2012
等)。
为此,您只需将date: "%Y"
(在上述两个示例的第二行)替换为date: "%B %Y"
。(%B
是完整的月份名称,见documentation)
【讨论】:
这太好了,谢谢!需要注意的是,您不会为最后一组创建最终的 。因此,在 for 循环之后,您需要在 for 循环之后执行 % if site.posts.size != 0 %% endif % 之类的操作。 或者就在循环结束之前,% if forloop.last %% endif %。 我想补充一点,其他解决方案对我不起作用,因为我的帖子不一定按日期排序,但是这个解决方案可以!谢谢! 这篇文章很棒。我设法使它适应我的情况。我对它的工作原理感到困惑 - 任何人都可以用 Liquid 代码中的 cmets 更新这个答案吗? 除了年月外,还能显示发帖数吗?【参考方案2】:如果你想按年份细分,代码如下:
% 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 %
这只是你在哪里进行循环切割的问题。
【讨论】:
这可以与 site.categories.xxx 一起使用吗?【参考方案3】:这些以前的解决方案非常棒,但幸运的是,在 2016 年末,Jekyll added a 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 %
可以在Jekyll Templates page 上找到文档。
【讨论】:
是否可以使用 site.data 而不是帖子来做到这一点?例如,我有 10 组数据,所有数据都包含一个数据变量,它们位于我想像这样循环的 3 个日期内。还是只有嵌套的液体循环才有可能?谢谢! 是的,您可以使用相同的技术对任何数组进行分组:% assign groupedData = site.data | group_by_exp: "data", "data.yourVariable" % 感谢您的出色回答。如果您使用的是较新版本的 Jekyll,这绝对是您的必经之路。【参考方案4】:上面的一些解决方案非常复杂,但正如 @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 %
【讨论】:
【参考方案5】:试试:
% 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 »</span>
<a href=" post.url "> post.title </a>
</li>
% if forloop.last %
</ul>
% endif %
% capture last_year % this_year % endcapture %
% endfor %
【讨论】:
【参考方案6】:<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>
【讨论】:
【参考方案7】:不太喜欢其他答案,所以这里有一个替代方案。基本逻辑:只有“新”时才显示年/月:
% 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 %
【讨论】:
【参考方案8】:Ankit R Gadiya 的 answer 的变体。内部的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 %
例子:
【讨论】:
以上是关于Jekyll/Liquid 模板:如何按年份对博客文章进行分组?的主要内容,如果未能解决你的问题,请参考以下文章
Jekyll/Liquid - 如何将大块文本添加到 YAML 前端?
html 条形图Jekyll LIquid for JSON
在 Jekyll/Liquid 和 pygments 的 html 问题中突出显示
检查带有/ Jekyll Liquid 的页面上是不是存在带有/ class x 的 div