1

I have created a blog channel and a blog category along with a category field.

Now I wish output the category within the blog post.

{% set categoryEntry = craft.categories().group('blog') %}
{% set categories = categoryEntry.all() %}

  {% for blogEntry in craft.entries.section('blogPosts').limit(8).all() %}
  <div class="blog card">
    <ul>
      <li>Article</li>
      <li>|</li>
      {% nav category in categories %}
      <li><a href="{{ category.url }}"></a>{{ category.title }}</a></li>
      {% endnav %}
    </ul>
    <h1>{{ blogEntry.title }}</h1>
    <p>{{ blogEntry.excerpt }}</p>
  </div>
  {% endfor %}

My code outputs all categories rather than just the one assiotated with the post.

Why is this?

3

At the moment, you are loading all categories in the line {% set categories = categoryEntry.all() %} and that's why you are getting them all for each entries.

What you need to do is to fetch your categories in the context of your blogEntry.

Here I assume a field name of blogCategories on your blogEntry but change accordingly to match what your Categories field is call:

{% for blogEntry in craft.entries.section('blogPosts').limit(8).all() %}
  <div class="blog card">
    <ul>
      <li>Article</li>
      <li>|</li>
      {% nav category in blogEntry.blogCategories.all() %}
      <li><a href="{{ category.url }}"></a>{{ category.title }}</a></li>
      {% endnav %}
    </ul>
    <h1>{{ blogEntry.title }}</h1>
    <p>{{ blogEntry.excerpt }}</p>
  </div>
{% endfor %}

Alternatively (and probably best) you can eager-load your categories on your initial entries query:

{# Fetch your entries and eager-load your categories #}
{% set blogEntries = craft.entries()
  .section('blogPosts')
  .with(['blogCategories'])
  .limit(8)
  .all() %}

{% for blogEntry in blogEntries %}
  <div class="blog card">
    <ul>
      <li>Article</li>
      <li>|</li>
      {% nav category in blogEntry.blogCategories %}
      <li><a href="{{ category.url }}"></a>{{ category.title }}</a></li>
      {% endnav %}
    </ul>
    <h1>{{ blogEntry.title }}</h1>
    <p>{{ blogEntry.excerpt }}</p>
  </div>
{% endfor %}

You can read on eager-loading in the documentation here - https://craftcms.com/docs/3.x/dev/eager-loading-elements.html

1
  • Thanks very much, eager-loading looks interesting Oct 4 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.