Kitsuneippiki 狐一匹     Blog 日誌     Projects 項目     About 關於

Sort tags and categories by post count or alphabetically in Jekyll without plugins

|

This post introduces a solution of sorting tags and categories by post count or alphabetically in Jekyll without plugins. Since no plugin is needed, this solution works on Github Pages. Preview it on my site. Because liquid template does not support direct sort of array by a value (here the post list in site.tags)’s property, I have to do some dirty work by passing tags’ name and post count, separated by delimiters, to a string and sort the string by post count or alphabetically. Anyway, liquid is good at dealing with strings.

Tags are sorted by post count correctly if the count is less than 100. Christian Specht’s answer on Stackoverflow works with count < 1000 and has the same way of implementation as this solution. His code does not deal with tag having space properly, but this problem can be easily solved by replacing the ‘ ‘ delimiter in the string with another character.

Here is the code. If you want to transplant it to your site, remember to use your own css style. The style I used here comes from Codinfox’s GitHub Pages site.


These codes sort and list tags by post count in a tag.html page. A list of tags with related posts is then generated below the tag list.

<div class="tags-expo">
  <div class="tags-expo-list">
    {% for tag in site.tags  %}
      {% assign tag_size = tag[1].size %}
      {% assign tag_name = tag[0] %}
      {% if tag_size < 10 %} {% comment %} Add a '0' to the size section if size < 10. {% endcomment %}
        {% assign taglist = taglist | append: "0"|append: tag_size|append: ","|append: tag_name |append: "@" %}
      {% else %}
      {% assign taglist = taglist | append: tag_size|append: ","|append: tag_name |append: "@" %}
      {% endif %}
    {% endfor %}
    {% assign sorted_taglist = taglist | split: "@" |sort|reverse %}
    {% for sorted_tag in sorted_taglist %}
      {% assign sorted_tag_array = sorted_tag | split: "," %}
      {% if sorted_tag_array[0].size == 2 %}
        {% assign sorted_tag_size = sorted_tag_array[0] | slice: 1 %}
      {% endif %}
      <a href="#{{ sorted_tag_array[1] | slugify }}" class="post-tag">{{sorted_tag_array[1]}}<small> ×{{sorted_tag_size}}</small></a>
    {% endfor %}
  </div>
  <hr/>
  <div class="tags-expo-section">
    {% for sorted_tag in sorted_taglist %}
      {% assign sorted_tag_array = sorted_tag | split: "," %}
      {% if sorted_tag_array[0].size == 2 %}
        {% assign sorted_tag_size = sorted_tag_array[0] | slice: 1 %}
      {% endif %}
      <h2 id="{{ sorted_tag_array[1] | slugify }}">{{sorted_tag_array[1]}}</h2>
      <ul>
        {% for post in site.posts %}
          {% if post.tags contains sorted_tag_array[1] %}
          <a class="post-title" href="{{ site.baseurl }}{{ post.url }}">
          <li>
            {{ post.title }}
          <small class="post-date">{{ post.date | date_to_string }}</small>
          </li>
          </a>
          {% endif %}
        {% endfor %}
      </ul>
    {% endfor %}
  </div>
</div>

Sort and display categories with associated posts alphabetically.

<div class="tags-expo">
  <div class="tags-expo-list">
    {% for tag in site.categories  %}
      {% assign tag_name = tag[0] %}
      {% assign taglist = taglist | append: tag_name |append: "@" %}
    {% endfor %}
    {% assign sorted_taglist = taglist | split: "@" |sort %}
    {% for sorted_tag in sorted_taglist %}
    <a href="#{{ sorted_tag | slugify }}" class="post-category-tag">{{ sorted_tag }}</a>
    {% endfor %}
  </div>
  <hr/>
  <div class="tags-expo-section">
    {% for sorted_tag in sorted_taglist %}
    <h2 id="{{ sorted_tag | slugify }}">{{ sorted_tag }}</h2>
    <ul>
    {% for post in site.posts %}
      {% if post.categories contains sorted_tag %}
      <a class="post-title" href="{{ site.baseurl }}{{ post.url }}">
      <li>
        {{ post.title }}
      <small class="post-date">{{ post.date | date_to_string }}</small>
      </li>
      </a>
      {% endif %}
    {% endfor %}
    </ul>
    {% endfor %}
  </div>
</div>

Comments