2

I'm trying to paginate a channel of entries but I also need to exclude any entries that relate to a specific category.

This is what I have so far...

{% set insightCategory = craft.categories({"slug": "insights"}).first() %}
{% set insightsEntryIds = craft.entries.section('blogChannel').relatedTo({targetElement: insightCategory}).limit(null).ids() %}

{% paginate craft.entries.section('blogChannel')|without(insightsEntryIds) as entries %}
    {% for blogEntry in entries %}
        <p>{{ blogEntry.title }} ({{ blogEntry.id }})</p>
    {% endfor %}
{% endpaginate %}

Unfortunately the pagination doesn't seem to work with the |without filter. How can I achieve this?

Thanks

6

The without filter converts your ElementCriteriaModel into an array of entry models (the same as find() does). But that array won't work with paginate, as explained in the docs:

This parameter needs to be an actual ElementCriteriaModel object; not an array of elements. So don’t call find() on the object.

So you need to query for the entries you're after directly with an ElementCriteriaModel. The workaround to get there would be to pass an array of entry IDs into the id() parameter.

{% set categoriesToExclude = craft.categories({slug: 'berlin'}) %}
{% set entriesToExcludeIds = craft.entries.section('news').relatedTo(categoriesToExclude).limit(null).ids() %}
{% set entryIds = craft.entries.section('news').limit(null).ids()|without(entriesToExcludeIds) %}

{% set entries = craft.entries.id(entryIds) %}

{% paginate entries as entriesOnPage %}
    ...
{% endpaginate %}

It's not recommended to use the without filter with objects anyways (→ see Brad's answer to a related question)!

3

The probably more elegant way to handle this is to not use the without filter at all and simply list the categories you want to exclude prefixed with not.

{% set categories = craft.categories({
    group: 'location',
    slug: [
        'and',
        'not berlin',
        'not amsterdam',
    ],
    limit: null,
}) %}

{% set entries = craft.entries.section('news').relatedTo(categories) %}

{% paginate entries as entriesOnPage %}
    ...
{% endpaginate %}
  • Hm, this looks like it could be a really nice solution, but would there be a problem with this whereby any entries which didn't have any categories in the location group also wouldn't show? (i.e. any entry would have to have at least one category in the location group for it to show). – Mike Vaux Jan 5 '17 at 10:10
  • Yes, this only returns entries that are related to at least one of the categories. Useful if you have set the categories field to be required. You can add more groups to the group param or don't use it at all. – carlcs Jan 5 '17 at 11:00
  • Ok, thanks - just wanted to make sure I wasn't missing anything! :) Good shout re. using this if the categories field is required. – Mike Vaux Jan 5 '17 at 16:13

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.