2

I want to only display entries on the category page which is the last in the array of the entries category, so that it doesn't also show on parent category page.

Let say these are my categories:

Shop

  • List item
  • Shoes
  • T-shirts

Entries with a category of "shoes" displays under both "shop" and "shoes" because of the way categories work as an array. My aim is to have it show only on "shoes", not "shop".

Here is my current code:

<!-- Get entries from the shop section -->
    {% set params = {
      section: 'shop'
    } %}

    <!-- Check if curreny entry is a category page, Set params to get entries related to current category, order by entry "order" field -->
    {% if category is defined %}
      {% set params = params | merge({
        relatedTo: category
      }) %}
    {% endif %}

    <!-- Get all entries by params -->
    {% set blogEntries = craft.entries(params) %}

    <!-- Paginate entries (9 per page) -->
    {% paginate blogEntries.limit(9) as pageInfo, pageEntries %}

    <!-- Display each entry, only if the current category is the same as the LAST category in the entries array. The conditional makes sure that the entries with non-top-level categories aren't displayed under parent categories. -->
    <ul>
      {# for entry in pageEntries if category.id == entry.productCategory.last().id #}
      {% for entry in pageEntries %}
        <li>{{ entry.title }} ({{ entry.productCategory | join(', ') }})</li>
      {% endfor %}
    </ul>
  </div>

  {% if blogEntries|length > 9 %}
    {% include "_partials/pagination.twig" %}
  {% endif %}

I've managed to display the entries under the correct categories with the if category.id == entry.productCategory.last().id on the for loop displaying all the entries, however this does not work with pagination.

My question is, is there a way to bake the conditional into the initial category params to avoid looping through all entries where the current category doesn't match the last category within the entry's array.

I hope this makes sense, please feel free to get in touch for any clarification.

Thanks, Teegan

1

Found the solution, thanks to Aaron Berkowitz on How to get entries related to current category only (not children)

You need to exclude the entries related to the subcategories.

 {% if category is defined %}
 {% set dontInclude = [] %}
     {% for child in craft.categories.descendantOf(category) %}
        {% set dontInclude = dontInclude|merge(craft.entries.relatedTo(child).ids) %}
      {% endfor %}

      {% set str = dontInclude|join(', not ') %}


  {% if dontInclude|length > 0 %}
    {% set params = params | merge({
      relatedTo: category,
      order: 'order ASC',
      id: 'and, not '~str
    }) %}
  {% else %}
    {% set params = params | merge({
      relatedTo: category,
      order: 'order ASC'
    }) %}
  {% endif %}
    {% endif %}

    <!-- Get all entries by params -->
    {% set blogEntries = craft.entries(params) %}

    <!-- Paginate entries (9 per page) -->
    {% paginate blogEntries.limit(2) as pageInfo, pageEntries %}
<ul>
      {% for entry in pageEntries %}
        <li>{{ entry.title }} ({{ entry.productCategory|join(', ') }})</li>
      {% endfor %}
    </ul>

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.