简体   繁体   English

使用液体按字母顺序对帖子进行排序

[英]Using liquid to sort posts alphabetically

Is there a way to sort a number of posts alphabetically, using Jekyll? 是否可以使用Jekyll按字母顺序对一些帖子进行排序?

I have something like this now: 我现在有这样的事情:

{% for post in site.categories.threat %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}

It works, but the posts are jumbled up. 它有效,但帖子混乱。 Would look much nicer if they were sorted alphabetically I think. 我认为如果按字母顺序对它们进行排序会更好。

Thanks 谢谢

It can be done without a plugin, which means that it works with Github Pages . 无需插件即可完成,这意味着它可以与Github Pages一起使用

You have to use some ugly string manipulation tricks, though. 但是,您必须使用一些难看的字符串操作技巧。
I used a similar approach to implement a tag page (that lists all posts for each tag) . 我使用了类似的方法来实现标签页面(该页面列出了每个标签的所有帖子)

Same approach, slightly modified: 相同的方法,稍作修改:

{% capture posts %}
  {% for post in site.posts %}
    |{{ post.title }}#{{ post.url }}
  {% endfor %}
{% endcapture %}
{% assign sortedposts = posts | split: '|' | sort %}
{% for post in sortedposts %}
    {% assign postitems = post | split: '#' %}
    <a href={{ postitems[1] }}">{{ postitems[0] }}</a><br>
{% endfor %}

Beware: 谨防:

You need two different separator characters inside the first loop (and of course again in the split calls later on) . 您需要在第一个循环内使用两个不同的分隔符(当然,稍后在split调用中也要使用)
In order for this to work, both characters must not occur in any of the post titles or URLs!! 为了使它起作用,两个标题中的两个字符都不得出现!

I'm using | 我正在使用| and # in this example, which works for me (I just tested it with my blog) . #在本示例中适用于我(我刚刚在自己的博客中对其进行了测试) But you might need to use different characters, depending on your post titles and how your URLs are constructed. 但是,您可能需要使用不同的字符,具体取决于您的帖子标题和URL的构造方式。


Bonus: 奖金:

If you want to display only the posts in a certain tag/category (and not all posts) , you can change the first for loop (the one inside the capture ) to one of these: 如果您只想显示某个标签/类别中的帖子(而不是所有帖子) ,则可以将第一个for循环capture中的一个更改为以下其中一个:

{% for post in site.tags['whatever'] %}

{% for post in site.categories['whatever'] %}

According to the documentation, to filter an array by one of its field, you can use : 根据文档,要按其字段之一过滤数组,可以使用:

    {% assign sortedPosts = site.posts | sort: 'title' %}

Then the sortedPosts variable will contain the sorted array. 然后sortedPosts变量将包含已排序的数组。

The documentation can be found here : https://docs.shopify.com/themes/liquid/filters/array-filters#sort 可以在这里找到文档: https : //docs.shopify.com/themes/liquid/filters/array-filters#sort

It's both clean and elegant to sort in Jekyll in GitHub pages without a plugin. 在没有插件的情况下在GitHub页面的Jekyll中排序既干净又优雅。 Use your .yml data file in the _data directory. 使用_data目录中的.yml数据文件。 I use a data file here called team-members.yml : 我在这里使用一个名为team-members.yml的数据文件:

{% assign sorted_team = site.data.team-members | sort:'title' %}
{% for member in sorted_team %}
    <span class="title">{{ member.title }}</span>
{% endfor %}

This pattern will handle what you need to do here. 此模式将处理您在此处需要执行的操作。

I adapted a Jekyll plugin from https://gist.github.com/3812259 to accomplish this. 我从https://gist.github.com/3812259改编了Jekyll插件来完成此任务。 I couldn't use the plugin as-is, because it failed in the presence of null values. 我不能按原样使用该插件,因为它在存在空值时失败。 I'm a beginning ruby programmer, and coded the null handling with help from https://stackoverflow.com/a/808721/1135052 我是一名红宝石程序员,并在https://stackoverflow.com/a/808721/1135052的帮助下编码了null处理

sort_for example reversing the sort and performing case-sensitive string comparisons (ignored if the sorted property is not a string): sort_例如反转排序并执行区分大小写的字符串比较(如果sorted属性不是字符串,则忽略):

{% sorted_for node in site.pages reversed sort_by:title case_sensitive:true %}
  {{ node.title }}
{% endsorted_for %}

sorted_keys_for example: sorted_keys_例如:

{% sorted_keys_for tag in site.tags %}
  <a href="/tags/{{ tag | downcase | replace:" ","-"}}.html">{{ tag }}</a><br />
  Num posts: {{ site.tags[tag].size }}
{% endsorted_keys_for %}

For use in Jekyll, put this code in _plugins/sort_for.rb 要在Jekyll中使用,请将此代码放在_plugins / sort_for.rb中

module Jekyll
  module SortedForImpl
    def render(context)
      sorted_collection = collection_to_sort context
      return if sorted_collection.empty?
      sort_attr = @attributes['sort_by']
      case_sensitive = @attributes['case_sensitive'] == 'true'
      i = sorted_collection.first

      if sort_attr != nil
        if i.to_liquid[sort_attr].instance_of? String and not case_sensitive
          sorted_collection.sort_by! { |i|
            k = i.to_liquid[sort_attr]
            k ? k.downcase : ''
          }
        else
          sorted_collection.sort_by! { |i|
            k = i.to_liquid[sort_attr]
            [k ? 1 : 0,k || 1]
          }
        end
      else
        if i.instance_of? String and not case_sensitive
          sorted_collection.sort_by! { |i| i.downcase }
        else
          sorted_collection.sort!
        end
      end

      original_name = @collection_name
      result = nil
      context.stack do
        sorted_collection_name = "#{@collection_name}_sorted".sub('.', '_')
        context[sorted_collection_name] = sorted_collection
        @collection_name = sorted_collection_name
        result = super
        @collection_name = original_name
      end
      result
    end
  end

  class SortedForTag < Liquid::For
    include SortedForImpl

    def collection_to_sort(context)
      return context[@collection_name].dup
    end

    def end_tag
      'endsorted_for'
    end
  end

  class SortedKeysForTag < Liquid::For
    include SortedForImpl

    def collection_to_sort(context)
      return context[@collection_name].keys
    end

    def end_tag
      'endsorted_keys_for'
    end
  end
end

Liquid::Template.register_tag('sorted_for', Jekyll::SortedForTag)
Liquid::Template.register_tag('sorted_keys_for', Jekyll::SortedKeysForTag)

I wanted to add following for future reference. 我想添加以下内容以供将来参考。

To sort posts by title, you can use sort filter. 要按标题对帖子进行排序,可以使用sort过滤器。 See http://jekyllrb.com/docs/templates/#filters 参见http://jekyllrb.com/docs/templates/#filters

So, this works: 因此,这有效:

{% assign sorted_threat_posts = site.categories.threat | sort: 'title', 'last' %}
{% for post in sorted_threat_posts %}
   <li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}

It cannot be done without a plugin or custom function. 没有插件或自定义功能就无法完成。 Although, there is an ongoing effort to implement this in the next releases: https://github.com/Shopify/liquid/pull/101 and then it would look like: 虽然,正在不断努力以在下一个版本中实现此目的: https : //github.com/Shopify/liquid/pull/101 ,然后看起来像:

{% for tag in site.tags order:ascending %} 
   ...
{% endfor %}

See also: Order an array with Jekyll / liquid template 另请参阅: 使用Jekyll /液体模板订购阵列

我在本地站点上测试了Christian的出色解决方案:在第一行之前,输出中有一个空链接(我不为什么),因此第一个链接不起作用,因此我修改了他的代码,插入{% if postitems[1] %}在行<a href={{ postitems[1] }}">{{ postitems[0] }}</a><br>以及{% endif %}之后,建议了tanky woo的评论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM