10

I have a page that should show entries within a category, and then entries within children of that category. Basically, I need a way to loop through entries that have a level 1 category but not a level 2 category.

To give an example, suppose I've got some categories set up like this:

1.

— 1.1.

—— 1.1.1.

— 1.2.

2.

There's also one entry related to each category. I'd then use code like this:

{# Reference the category #}
{% set cat = craft.categories.title('1.').first() %}

{# Find related entries #}
{% set entries = craft.entries.section('mySection').relatedTo(cat).find() %}

{# Print them out #}
{% for entry in entries %}
    <p>{{ entry.title }}</p>
{% endfor %}

This would output:

1.

1.1.

1.1.1.

1.2.

How can I find entries which are directly related to the category “1.”?

9

Categories are Craft's implementation of a taxonomy, which itself is the classification of things into groups and sub-groups. In this respect, I suppose it makes sense that if an entry is related to a sub-category, it inherits (it's also related to) its parent. That would explain why you're getting all entries in this way.

At the moment, the only way I can think of is to test what level the category/sub-category is.

Something like this would get you started for the time being. I don't really like this because it seems convoluted, so I'll put my thinking cap on and I may revise.

{% set category = craft.categories.group('myGroup').title('1.').first() %}
{% set entries = craft.entries.section('mySection').relatedTo(category).find() %}
{% set isThisLevel = false %}
{% for entry in entries %}

    {# Test if this entry is related to the correct category level #}
    {% for relatedCat in entry.catField %}
        {% if relatedCat.level == category.level %}
            {% set isThisLevel = true %}
        {% endif %}
    {% endfor %}

    {# Only output if it's this category level #}
    {% if isThisLevel %}
        {# Do whatever you want #}
    {% endif %}

{% endfor %}
  • 1
    This is how I thought it would work, however there is seemingly no way to assign a level 2 category to an entry without it inheriting the level 1 category. Therefore, I can't loop through entries with a level 1 category, but not a level 2 category; the entries with a level 2 category inherently have a level 1 category and there seems to be no way to exclude them. – Angus Fretwell Jun 20 '14 at 1:16
  • Ah right, I didn't totally understand the situation. I've revised my answer but I'm still not happy with it. I'll have a think. I've also submitted a modification to the question to clarify the problem. – Stuart Whitehead Jun 20 '14 at 8:55
  • Yeah, sorry my question was so vague I didn't know how to word it. I actually came to the same solution as the one you've suggested. Works fine but it's a little gross. – Angus Fretwell Jun 25 '14 at 5:26
3

You can use the level parameter of a Categories ElementCriteriaModel to get a list of nth-level categories, just to make your category search a bit more robust.

Then, you can use Twig's without filter to create the set of entries related to the primary category but not related to its child categories:

{# Identify the primary category you want #}
{% set cat = craft.categories.title('1.').level(1).first() %}

{# Identify the [child] categories you don't want #}
{# set childCats = cat.children #}

{# Grab an array of entries related to the primary category #}
{% set entries = craft.entries.section('mySection').relatedTo(cat).find() %}

{# Get an array of entries related to the child categories #}
{% set excludedEntries = craft.entries.section('mySection').relatedTo(childCats).find() %}

{# Exclude the second set and loop over the resulting array #}
{% for entry in entries|without(excludedEntries) %}
    <p>{{ entry.title }}</p>
{% endfor %}

This is still a bit janky, and you'd have to tweak it for performance if you were interested in more than one primary category at a time... but maybe it's a start.

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.