Peiwen
Peiwen

Reputation: 692

Automatically add class when listing all Jekyll posts

I'd like to list all Jekyll posts in chronological order, and all posts in same category will have a same class name as I give (e.g. cate1, cate2, cate3...). I've tried in many ways, still cannot figure this out. Can you help me please?

For instance, the following code can list all posts in chronological order, but all links will have the same cate1 class.

{% for post in site.posts %}
  {% if site.categories.CATEGORY1 %}
    <a class="cate1" href="{{ post.url }}">{{ post.title }}</a>
  {% elsif site.categories.CATEGORY2 %}
    <a class="cate2" href="{{ post.url }}">{{ post.title }}</a>
  {% elsif site.categories.CATEGORY3 %}
    <a class="cate3" href="{{ post.url }}">{{ post.title }}</a>
  {% endif %}
{% endfor %}

I've also tried:

{% for post in site.posts %}
  {% for post in site.categories.CATEGORY1 %}
    <a class="cate1" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
  {% for post in site.categories.CATEGORY2 %}
    <a class="cate2" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
  {% for post in site.categories.CATEGORY3 %}
    <a class="cate3" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
{% endfor %}

This will generate each link 13 times which is my total posts amount. The link order is based on the order of categories in the loop not in chronological order.

I've also tried:

{% for post in site.posts %}
  {% for CATEGORY1 in site.categories %}
    <a class="cate1" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
  {% for CATEGORY2 in site.categories %}
    <a class="cate2" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
  {% for CATEGORY3 in site.categories %}
    <a class="cate3" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
{% endfor %}

This will generate each link 25 times. I guess this is because I have 5 categories and 5*5=25. Each link will have different class name (e.g. a_CATEGORY1_post.cate1, a_CATEGORY1_post.cate2, a_CATEGORY1_post.cate3). But all posts is in chronological order.

Upvotes: 0

Views: 620

Answers (1)

J W
J W

Reputation: 2871

You'll want to another loop inside the posts loop like this:

{% for post in site.posts %}
  {% for cat in post.categories %}
      <a class="{{ cat }}" href="{{ post.url }}">{{ post.title }}</a>
  {% endfor %}
{% endfor %}

See here for details on what is accessible in the loop:
https://github.com/mojombo/jekyll/wiki/template-data

There are two problems this approach:

  1. If one of your posts does not have a category assigned to it, it won't be listed. So you might want to do a check for that too.

  2. You get the same post listed multiple times if it is assigned to more than one category. So for this I would redo the code using Liquid Filters to have it like: class="cat1 cat2 cat3" like this:

    {% for post in site.posts %}
      <a class="{{ post.categories | join: ' ' }}" href="{{ post.url }}">{{ post.title }}</a>
    {% endfor %}
    

See here for Liquid Filters:
https://github.com/shopify/liquid/wiki/liquid-for-designers

EDIT: Do you mean you want to add a unique class to each link instead of the category name(s)? Not sure what you mean by specific. For unique you could do a case statement before the <a href part:

  {% case condition %}
    {% when cat = 'cat1' %}
      cat = 'unique_class_1'
    {% when cat = 'cat2' %}
      cat = 'unique_class_2'
    {% else %}
      ... else ...
  {% endcase %}

But in that case, why won't the category class be unique enough?

EDIT Example 3 for Peiwin's comment - I would not recommend doing it this way as it is poor coding practice. Instead work with your jQuery to make it more flexible and work with #2 above:

{% for post in site.posts %}
  {% for cat in post.categories %}
    {% case condition %}
      {% when cat = 'cat1' %}
        {% assign cat_class = 'unique_class_1' %}
      {% when cat = 'cat2' %}
        {% assign cat_class = 'unique_class_2' %}
      {% else %}
        ... else ...
    {% endcase %}
  {% endfor %}

  <a class="{{ cat_class }}" href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}

Upvotes: 2

Related Questions