5

I'm converting a WordPress blog to Craft - first time playing with categories in Craft, so how can I display the related posts (by category) at the bottom of each post?

4

This can be done quite easily as follows, assuming that you are on an entry page so entry is a variable in your template and your category field is called categories.

{% for relatedEntry in craft.entries({
    section: 'blog',
    relatedTo: entry.categories,
    id: 'not ' ~ entry.id
}) %}
    <a href="{{ relatedEntry.url }}">{{ relatedEntry.title }}</a>
{% endfor %}

I am passing an object into the ElementCriteriaModel for clarity above but you could just as easily do it by chaining parameters onto the ElementCriteriaModel as follows, it's just a matter of preference.

{% for relatedEntry in craft.entries.section('blog').relatedTo(entry.categories).id('not ' ~ entry.id) %}
    <a href="{{ relatedEntry.url }}">{{ relatedEntry.title }}</a>
{% endfor %}

See the relatedTo param in the docs to understand the magic.

  • 1
    Thanks guys! :) Would be awesome and very useful if someone could add the categories & tags templates on the Craft demo site github.com/pixelandtonic/ontherocks ;) – lucassoares Jun 26 '14 at 23:47
  • 2
    @lucassoares Sounds like somebody's got a great idea for a pull request! And by somebody, I mean you. :) – Matt Stein Jun 27 '14 at 1:13
3

This can be accomplished using Craft's Relations.

My example code assumes you know the blog categories slug, and that you are pulling posts from a single category.

First, you'll have to get a reference to the category ElementCriteriaModel object pointing to the category of the blog post.

{% set category = craft.categories.slug('your-category-slug').first() %}

With a reference to the category model, you'll be able to find related entries.

{% for post in craft.entries.section('blog').relatedTo({targetElement: category}) %}
    {% if post.id != entry.id %}
        <div class="related-entry">
            <h2>{{ post.title }}</h2>
            {{ post.body }}
        </div>
    {% endif %}
{% endfor %}

The if statement makes sure you aren't including the current post with the related posts.

  • 1
    It is also probably worth throwing an if statement in the loop so you don't display the original entry as a related entry. – Andris Sevcenko Jun 26 '14 at 10:42
  • 1
    Yeah, great call. I included that in the answer. – Coppa Jun 26 '14 at 16:53
1
{% set category = craft.categories.group('{{ entry.topic }}').first() %}`enter code here`

For anyone else who stumbles on this post, I wasn't able to get the code working until I changed a few things.

Instead of categories.slug, I used category.group and made 'your category-slug' {{ entry.topic }}, topic being how I assign my single category to entries.

  • 1
    Passing a string '{{ entry.topic }}' to the param works for you? Doesn't sound right... – carlcs Apr 10 '16 at 18:20
  • topic is how I call the single category name that I've assigned to my entries. – Aaron Ransom Apr 11 '16 at 22:20

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.