如何在Liquid中对转换为数组的哈希进行排序

时间:2011-06-17 14:44:02

标签: liquid jekyll

我的理解是Liquid将Ruby Hashes转换为数组以用于标记。例如,使用Jekyll时:

{% for category in site.categories %}
    <li>{{ category[0] }}</li>
{% endfor %}

...将site.categories转换为元组数组,其中[0]表示键,[1]表示值。

如果我想通过键(每个元组的[0])按字母顺序对上面的类别映射进行排序,我该怎么办?

8 个答案:

答案 0 :(得分:8)

这是一个老问题,但我只花了最后一点时间为自己搞清楚这一点。我使用以下代码来实现您(和我)想要的。

{% capture get_items %}
 {% for cat in site.categories %}
   {{ cat | first }}
 {% endfor %}
{% endcapture %}
{% capture num_words %}
 {{ get_items | split:' ' |  sort | join:' ' | number_of_words }}
{% endcapture %}
{% for item in (1..num_words) %}
 <li>{{ get_items | split:' ' |  sort | join:' ' | truncatewords:item | remove:'.    ..' |    split:' ' | last }}</li>
{% endfor %}

答案 1 :(得分:7)

您也可以使用数组而不是哈希值!

而不是使用这个yaml:

categories:
  a_category: category description
  another_category: another category description

你可以使用这个:

categories:
  - {name: 'a category', description: 'category description'}
  - {name: 'another category', description: 'another category description'}

然后你可以像这样迭代,并且将保留订单:)

{% for category in site.categories %}
  <li>{{ category['name'] }}</li>
{% endfor %}

答案 2 :(得分:4)

按字母顺序排序的标签(标签名称中不允许的空格)的帖子索引:

{% capture tags %}
  {% for tag in site.tags %}
    {{ tag[0] }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}

{% for tag in sortedtags %}
  <h4>#{{ tag }}</h4>
  <ul>
  {% for post in site.tags[tag] %}
    <li>
      <span>{{ post.date | date_to_string }}</span>
      <a href="{{ post.url }}">{{ post.title }}</a>
    </li>
  {% endfor %}
  </ul>
{% endfor %}

答案 3 :(得分:1)

我也想成为这场模糊竞争的一部分(伙计,number_of_words,认真吗?)。

此代码按标记构建列表标记,在每个步骤的列表中按字典顺序查找下一个标记。它在O( n ²)中,其中 n 是标签的数量。

<section>
  <h1>Pick a tag!</h1>
  <ul id="recent_posts">
    {% assign current_tag = ' ' %}
    {% for t in site.categories %}
      <li class="post">
        {% assign next_tag = 'ZZZ' %}
        {% for item in site.categories %}
          {% assign tag = item.first %}
          {% if tag > current_tag and tag < next_tag %}
            {% assign next_tag = tag %}
          {% endif %}
        {% endfor %}
        {{ next_tag | category_link }} {{ site.categories[next_tag].size }}
        {% assign current_tag = next_tag %}
      </li>
    {% endfor %}
  </ul>
</section>
顺便说一下,Liquid评论看起来很荒谬。

答案 4 :(得分:1)

您可以使用以下方法(与Github Pages兼容)按键排序:

{% assign sorted_categories = (site.categories | sort:0) %}
{% for category in sorted_categories %}
   <!-- Using the 'capitalize' filter in Liquid Tags - you can leave this out -->
   <li>{{category[0] | capitalize }}</li>

   {% assign sorted_catposts = (category[1] | sort: 'title', 'last') %}
   {% for catpost in sorted_catposts %}
     <!-- The posts within each category are now alphabetically sorted by title -->
     <!-- Do stuff with each post in each category -->
   {% endfor %}
{% endfor %}

希望这有帮助。

答案 5 :(得分:0)

默认的Liquid实现和Jekyll的添加都不能满足您的需求。

我担心你想要的东西根本不可能用当前的设置。你必须使用monkeypatch Jekyll或Liquid来使哈希按照排序的顺序返回它们的键。

答案 6 :(得分:0)

以下是我修复Nikos问题的方法:

{% capture get_items %}
   {% for cat in site.categories %}
    {{ cat | first | replace: ' ', '_' }}
   {% endfor %}
{% endcapture %}
{% capture num_words %}
  {{ get_items | split:' ' |  sort | join:' ' | number_of_words }}
{% endcapture %}
{% for item in (1..num_words) %}
  <li>{{ get_items | split:' ' |  sort | join:' ' | truncatewords:item | remove:'...' | split:' '  | last | replace: '_', ' ' }}</li>
{% endfor %}

现在如何使用HAML ...

答案 7 :(得分:0)

你可以省去一些麻烦和extend Liquid

e.g。

# https://gist.github.com/dnozay/026862f5d65dcb8b4353

module Jekyll
  module Toolbox
    def keys(hash)
      hash.keys
    end
    def to_ul(collection)
      result = ''
      collection.each do |item|
        result << "<li>#{item}</li>"
      end
      result
    end
  end
end

Liquid::Template.register_filter(Jekyll::Toolbox)

用法:

{{ myhash | keys | to_ul }}

示例:

# https://gist.github.com/dnozay/026862f5d65dcb8b4353

@context = { 'myhash' => { 'b' => 'B', 'a' => 'A', 'c' => 'C' } }
@template = Liquid::Template.parse("{{ myhash | keys | to_ul }}")
@template.render(@context)  # => "<li>b</li><li>a</li><li>c</li>"
@template = Liquid::Template.parse("{{ myhash | keys | sort | to_ul }}")
@template.render(@context)  # => "<li>a</li><li>b</li><li>c</li>"

如果您感到幸运,可以在github上查找for.rb文件并扩展for语法以更好地处理哈希值。)。