Matt Smith
Matt Smith

Reputation: 2158

Jekyll tags in alphabetical order regardless of case

I'm using Jekyll for a blog, and I have certain tags for topics (ex: CSS, JavaScript, front-end, accessibility, etc.). I want have these appear in alphabetical order regardless of case: accessibility, CSS, front-end, JavaScript, etc.

I'm a newbie with Jekyll, but I haven't found anything that demonstrates how this can be done. Here's what my current code looks like. Any suggestions would be helpful.

[//]: # (Get the tag name for every tag on the site and set them to the site_tags variable.)
{% capture site_tags %}{% for tag in site.tags %}{{ tag | first }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}

[//]: # (tag_words is a sorted array of the tag names.)
{% assign tag_words = site_tags | split:',' | sort %}

[//]: # (Build the Page)

[//]: # (List of all tags)
<section>
  <ul>
    {% for item in (0..site.tags.size) %}{% unless forloop.last %}
      {% capture this_word %}{{ tag_words[item] }}{% endcapture %}
      <li>
        <a href="#{{ this_word | cgi_escape }}" class="tag">{{ this_word }}
          <span>({{ site.tags[this_word].size }})</span>
        </a>
      </li>
    {% endunless %}{% endfor %}
  </ul>
</section>

[//]: # (Posts by tags)
<section class="tags">
  {% for item in (0..site.tags.size) %}{% unless forloop.last %}
    {% capture this_word %}{{ tag_words[item] }}{% endcapture %}
    <h3 id="{{ this_word | cgi_escape }}">{{ this_word }}</h3>
    {% for post in site.tags[this_word] %}{% if post.title != null %}
      <div class="row">
        <span>
          <a href="{{ post.url }}">{{ post.title }}</a>
        </span>
        <span class="post-date archive-date">
          {{ post.date | date: "%b %-d, %Y" }}
        </span>
      </div>
    {% endif %}{% endfor %}
  {% endunless %}{% endfor %}
</section>

Upvotes: 3

Views: 555

Answers (3)

David P. Chassin
David P. Chassin

Reputation: 41

I think if you want to alphabetize the tags regardless of case you need to include the filter downcase, e.g.,

{% assign tags = '' | split: '' %}
{% for tag in site.tags %}
  {% assign tagName = tag | first | downcase | split: ' ' %}
  {% assign tags = tags | concat: tagName %}
{% endfor %}
{% assign tags = tags | sort %}  
{% for tag_name in tags %}
  ...
{% endfor %}

Keep in mind that if you want to keep the original case of the tag when displaying, you cannot use tag_name to display the tag. You'll have to keep track of the original name.

Upvotes: 0

Lia Prins
Lia Prins

Reputation: 11

There's also the sort_natural liquid filter instead of the sort filter.

Upvotes: 0

DC.Azndj
DC.Azndj

Reputation: 1396

You're actually really close! There's a few bugs, but you have everything else right.

In the first part where you're making the array of tags, it's a little easier to concat to an array rather than make a string then split it into an array.

// create empty array
{% assign tags = '' | split: '' %}

// iterate through tags, get tag name and make into an array, concat arrays
{% for tag in site.tags %}
    {% assign tagName = tag | first | split: ' ' %}
    {% assign tags = tags | concat: tagName %}
{% endfor %}

// sort tags
{% assign tags = tags | sort %}

Now that you have an array of tags, you can just iterate through them with the for loop. No need to iterate item=0...n and use tags[item].

// create list of tags and number of posts with that tag
<section>
    <ul>
        {% for tag in tags %}
            {% assign postCount = site.tags[tag] | size %}
            <li>
                <a href="#{{ tag | cgi_escape }}" class="tag">
                    {{ tag }}
                    <span>({{ postCount }})</span>
                </a>
            </li>
        {% endfor %}
    </ul>
</section>

// create list of posts per title (posts are newest to oldest)
<section class="tags">
    {% for tag in tags %}
        <h3 id="{{ tag | cgi_escape }}">{{ tag }}</h3>
        {% for post in site.tags[tag] %}
            {% if post.title != null %}
                <div class="row">
                    <span>
                        <a href="{{ post.url }}">{{ post.title }}</a>
                    </span>
                    <span class="post-date archive-date">
                        {{ post.date | date: "%b %-d, %Y" }}
                    </span>
                </div>
            {% endif %}
        {% endfor %}
    {% endfor %}
</section>

Upvotes: 2

Related Questions