1

I'm trying to show a list of entries related to the same category on a page that contains a single entry. I have two category separate category fields in the entry, both with one category each selected in them. The two category groups are named eventType and venue. The code below successfully shows a list of entry titles for one category group but not the other, and I can't seem to find out what's going wrong.

The code below works for the eventType category group (it shows all the entries related to eventType). But when I swap out eventType for venue, it returns my else statement.

I'm new to Craft (it's great!), so maybe I'm going about this all wrong, or missing something obvious.

{% for thisCategory in entry.eventType %}

    <h1>Other Events in {{ thisCategory.title }}</h1>
    {% set category = craft.categories.slug(thisCategory.title) %}
    {% set entries = craft.entries.section('events').relatedTo(category).find() %}

    {# If there are any entries, loop through them #}
    {% if entries | length %}
        {# For each entry we find, do this #}
        {% for entry in entries %}
            <p>{{ entry.title }}</p>
        {% endfor %}
    {% else %}
        <p>Found no entries</p>
    {% endif %}
{% endfor %}

1 Answer 1

2

Your approach seems interesting but you should never do such "relations". They can be broken all over the way. Let me explain that.

Title vs Handle

Most objects in Craft have the attributes title and handle. The title is the name that can be rendered in the frontend. This should be your attribute to show users what the object is about. The handle is your "developing" attribute. This is a unique field, with several validation rules to make this field selectable via getEntryByHandle() thus you can link entries via handle, get them via handle and change the display name (title) however you like and can still select those via handle.

<h1>Other Events in {{ thisCategory.title }}</h1>

Is totally correct, you show the title to the frontend

{% set category = craft.categories.slug(thisCategory.title) %}

Is absolutely wrong. The validation rules for title and the validation rules for the slug attribute are totally different and you should never match those fields. When you have a title like Foo Bar you'll never be able to match them since your slug would be foo-bar.

The correct way would be this

{% set category = entry.yourCategoryFieldHandle.first() %}
{% set entries = craft.entries.section('events').relatedTo(category).find() %}

If you really really want to relate objects not via the relation Field but via strings you should do it with the handle but never with titles or slugs

2
  • Ahhh, that explains why one was working and one wasn't. The entry I was testing had a simple one-word category selected for my first test, but a three-word-with-punctuation category selected for the one that wasn't working (i.e. the title and handle were one and the same for the first test, but not the second). Your change fixed everything immediately. And I have a clear understanding of why it wasn't working. Thank you sooo much! Dec 17, 2017 at 13:57
  • You are welcome. Btw just as a side note: relations work in both ways. Every object in craft has a unique ID and the relatedTo logic checks if a is related to b or b is related to a it does not matter if your entry is the source or the target. Your entry.relationFieldHandle is a ready to use ElementQuery so you can fetch all related elements Dec 17, 2017 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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