【问题标题】:Filter or group a collection in Liquid在 Liquid 中过滤或分组集合
【发布时间】:2012-11-14 02:51:13
【问题描述】:

对于一个简单的个人 Jekyll 博客,我想通过 post 上的一个属性对我的 site.posts 进行分组,lang(语言)。这是“en”、“nl”或 nil。

然后我想呈现两个帖子列表。目前我有:

<section lang="nl">
<h2>Nederlandse Artikelen</h2>
<ul class="posts">
  {% for post in site.posts limit:50 %}
    {% if post.lang == "nl" %}
      {% include li_for_post_with_date.yml %}
    {% endif %}
  {% endfor %}
</ul>
<a href="archief.html">Archief »</a>
</section>
<section lang="en">
<h2>English Articles</h2>
<ul class="posts">
  {% for post in site.posts limit:50 %}
    {% if post.lang == nil or post.lang == "en" %}
      <li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ BASE_PATH }}{{ post.url }}">{{ post.title }}</a></li>
    {% endif %}
  {% endfor %}
</ul>

这有两个问题:

  1. 最烦人的;在最后 50 个帖子中,有 47 个 lang=en 和 3 个 lang=nl,我现在得到一个倾斜的列表。我想要 25 个 lang=en 和 25 个 lang=nl 条目。
  2. 循环遍历了两次,这让我觉得无能为力。

有没有办法在 Liquid 中分配或准备一个集合?这样我就可以循环一次 site.posts 并准备一个像 site.grouped_posts[en] 这样的嵌套集合。

还是其他技巧?

解决方案

正如Tom Clarkson 指出的那样,保持计数器是正确的方向。然而,增加计数器只出现在最近的 Liquid 版本中,在 Github 上运行的版本(我的 Liquid 在这里编译)具有 2.2.2,无法增加计数器。 Toms 解决方案本身也不起作用,因为 Liquid 将变量 counter 转换为字符串,无法与 &lt; 进行比较。

我通过附加一个字符串并计算字符数创建了一个 hack。

{% assign counter = '.' %}
{% for post in site.posts %}
  {% if counter.size <= 25 and post.lang == "nl" %}
    {% capture counter %}{{ counter | append:'.' }}{% endcapture %}
    {% include li_for_post_with_date.yml %}
  {% endif %}
{% endfor %}

如上所述,丑陋,所以如果有更清洁的解决方案,请添加解决方案!

【问题讨论】:

    标签: jekyll liquid


    【解决方案1】:

    很遗憾,Liquid 的过滤器在 for 循环中不起作用。但是,它们确实在变量赋值中起作用。

    {% assign posts_by_lang = site.posts | group_by: "lang" %}
    {% for lang in posts_by_lang %}
      {{ lang.name }}
      {% for post in lang.items limit: 25 %}
        {{ post.title }}
      {% endfor %}
    {% endfor %}
    

    nameitems属性由group_by生成,其余一切照旧。

    【讨论】:

      【解决方案2】:

      我认为您不能在不制作插件或自定义过滤器的情况下创建过滤后的集合,但您可以计算已为该组收集的帖子数量,而不是使用限制。

      {% for post in site.posts %}
          {% if counter < 25 and post.lang == nil or post.lang == "en" %}
              {% capture counter %}{{ counter | plus:1 }}{% endcapture %} 
              <li></li>
          {% endif %}
      {% endfor %}
      

      代码未经测试,但类似的东西应该可以工作。

      【讨论】:

      • 有趣的方向。但是,Capture 会将counter 转换为字符串,在第一次迭代后无法将其与 25 进行比较:/。最近的“流动”版本有“增量”,但没有在 Github 上运行的版本。
      • 尝试一些变化 - 与字符串“25”比较可能有效,或者如果 plus 不会添加到字符串中,您可以使用字符串的长度而不是其值作为计数器。
      • 是的,我正在涉足字符串长度。我只是简单地连接一系列点并进行比较:)。
      • @berkes 当然,{% increment somevar %} 与其他所有 {% %} Liquid 表达式不同,它是一个输出语句,因此无论如何您都必须捕获(并字符串化)它。 Liquid 确实是对模板系统的粗野、设计不佳的 hack。即使构造一个简单有效的整数循环计数器也会耗费数小时的时间。
      猜你喜欢
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-21
      • 2016-03-11
      • 1970-01-01
      • 2019-01-27
      相关资源
      最近更新 更多