我的理解是 Liquid 将 Ruby 哈希转换为数组以在标签中使用。例如,使用 Jekyll 时:
{% for category in site.categories %}
<li>{{ category[0] }}</li>
{% endfor %}
... 将 site.categories 转换为元组数组,其中 [0] 表示键,[1] 表示值列表。
如果我希望上述类别映射按键(每个元组的 [0])按字母顺序排序,我该怎么做?
这是一个老问题,但我只是花最后一点时间为自己解决这个问题。我使用以下代码来实现您(和我)想要的。
{% 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 %}
您还可以使用数组代替哈希!
而不是使用这个 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 %}
{% 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 %}
您可以使用以下方法(与 Github Pages 兼容)按 key 排序:
{% 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 %}
希望这可以帮助。
您可以为自己节省一些麻烦并扩展Liquid
:
例如
# 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
语法以更好地处理哈希 :)。
默认的 Liquid 实现和 Jekyll 所做的添加都不能满足您的需求。
恐怕目前的设置根本不可能实现您想要的。您必须对 Jekyll 或 Liquid 进行猴子补丁,以使哈希以排序顺序返回其键。
我也想成为这个模糊竞争的一部分(伙计们,真的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 评论看起来很荒谬。
这是我解决 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 一起工作......