Using liquid to sort posts alphabetically

后端 未结 7 1258
借酒劲吻你
借酒劲吻你 2021-02-01 19:45

Is there a way to sort a number of posts alphabetically, using Jekyll?

I have something like this now:

{% for post in site.categories.threat %}


        
相关标签:
7条回答
  • 2021-02-01 19:58

    It's both clean and elegant to sort in Jekyll in GitHub pages without a plugin. Use your .yml data file in the _data directory. I use a data file here called 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.

    0 讨论(0)
  • 2021-02-01 20:00

    I adapted a Jekyll plugin from https://gist.github.com/3812259 to accomplish this. 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

    sort_for example reversing the sort and performing case-sensitive string comparisons (ignored if the sorted property is not a string):

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

    sorted_keys_for example:

    {% 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

    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)
    
    0 讨论(0)
  • 2021-02-01 20:00

    i tested Christian's great solution in my local site: before the first row there is an empty link (i don't no why) in output, therefore the first link doesn't work, so i modified his code inserting {% if postitems[1] %} before the line <a href={{ postitems[1] }}">{{ postitems[0] }}</a><br>and an {% endif %} after. suggested tanky woo's comment.

    0 讨论(0)
  • 2021-02-01 20:05

    It can be done without a plugin, which means that it works with 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).
    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.


    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 post in site.tags['whatever'] %}
    
    {% for post in site.categories['whatever'] %}
    
    0 讨论(0)
  • 2021-02-01 20:10

    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:

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

    See also: Order an array with Jekyll / liquid template

    0 讨论(0)
  • 2021-02-01 20:11

    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.

    The documentation can be found here : https://docs.shopify.com/themes/liquid/filters/array-filters#sort

    0 讨论(0)
提交回复
热议问题