Related posts

Hi there,
I’m building a theme for Zola which require a related posts sections. Here is how I made the related posts list at the moment:

{% if category %}
    {% set related_posts = get_section(path="posts/_index.md")
      | get(key="pages")
      | sort(attribute="date")
      | filter(attribute="taxonomies.categories", value=[category])
      | slice(end=3)
    %}
    <div class="post-items-list columns">
      {% for post in related_posts %}
        {#
          Since we cannot use a negative filter the only solution to remove the current page from the
          related_posts is the following condition
        #}
        {% if post.permalink != page.permalink %}
          {{ macros::post_item(post=post) }}
        {% endif %}
      {% endfor %}
    </div>
  {% endif %}

The main problem is that I can’t filter the posts with a negative filter, like: | filter(attribute="permalink", not_value=page.permalink) so sometimes related_posts contains the current post and I need to filter using an if condition in the display loop. But this solution doesn’t suit me because I end with 2 posts in related posts instead of 3.

Am I missing something or there is no other solution at the moment to achieve that?

It seems like it would be easier to do something like:

{% set related_posts = get_taxonomy(kind="categories", term=post.category) %}

and just iterate on that with and skip the current page as you do. But the term argument or get_taxonomy doesn’t currently exist so you would need to compare the term in the loop.

There are no negative filters in Tera right now :confused: An exclude or something could be added to complement filter

1 Like

Hi @keats,

Thanks for your insight. My question wasn’t complete, I need to limit my related_posts to 3 items. So I ended writing something like this:

{% if category %}
  {% set related_posts = get_taxonomy(kind="categories")
    | get(key="items")
    | filter(attribute="name", value=category)
    | first
    | get(key="pages")
  %}
  {% set_global related_posts_counter = 0 %}

  {% if related_posts | length > 0 %}
    <h2>{{ trans(key="related_posts", lang=lang) }}</h2>

    <div class="post-items-list columns">
      {% for post in related_posts %}
        {#
          Since we cannot use a negative filter the only solution to remove the current page from the
          related_posts and having max 3 related posts is the following condition - @awea 20191207
        #}
        {% if post.permalink != page.permalink and related_posts_counter <= 2 %}
          {{ macros::post_item(post=post) }}
          {% set_global related_posts_counter = related_posts_counter + 1 %}
        {% endif %}
      {% endfor %}
    </div>
  {% endif %}
{% endif %}

The term argument in get_taxonomy would be great to only fetch the given category with its items ^^

1 Like

Yeah it’s quite verbose x)
I think the term argument makes sense to have, I’ll think about it today and create a GH issue for it if I don’t see any issues with it.

2 Likes

Hey Awea, Keats,

I’ve tried to repeat that code to get related posts (it’s really valuable thing), but I can’t understand what I supposed to do, if I have two or more tags\categories per article?

Hoy Roman,

The theme I’m working on use only one category per post and multiple tags per post. So I get the first category (the first because taxonomies.categories is a list) of the current post then I can use it in the related_posts above.

{% if page.taxonomies.categories %}
  {% set category = page.taxonomies.categories | first %}
  <small>{{ category }}</small>
{% endif %}

but I can’t understand what I supposed to do, if I have two or more tags\categories per article?

You can still use the set category above. But If you want to work with multiple tags\categories and fetch related_posts using those taxonomies you’ll need to rewrite the set related_posts part.

Hope it helps.