3

Here's my current setup:

Blog (Channel) - All of my blog posts will go here

Blog Landing (Single) - This section only has one field - a Featured Articles Entries field that lets me select 3 entries from the "Blog" channel.

Basically what I want to do on the Blog Landing section is have a dedicated area for the 3 Featured articles (ones that I will choose from that Featured Articles entries field), but then display the next 5 most recent articles that have not been selected as a Featured article in a different area.

I've successfully outputted my Featured Articles with this code:

{% set featured = entry.featuredArticles %}
  {% for entry in featured %}
    {{ entry.title }}
  {% endfor %}

And I can get my 5 most recent with this code:

{% set allEntries = craft.entries.section('blog') %}
  {% for entry in allEntries.limit(5) %}
   {{ entry.title }}
  {% endfor %}

I can't figure out how to exclude the entries from the Featured Articles area from the output of the Recent Articles area.

So say I have 10 entries in my Blog channel, (Post 1 is most recent, Post 2 is second most recent, and so on), and I've selected Posts 2, 4, and 5 as my "Featured" articles, how do I get it so that the 5 "Recent" articles display Posts 1, 3, 6, 7, and 8 instead of Posts 1, 2, 3, 4, and 5?

  • 1
    Hi Tyler, I don't have a direct answer, but check out this thread I think it is almost exactly what you are looking for. – Damon Feb 22 '16 at 19:15
4

What you could do is get the ids of the featured element, and exclude those from the second craft.entries call. Something like this:

{# Get the ids of the featured items you got above #}
{% set featuredIds = featured.ids() %}

{# Get entries in section 'blog' which don't have an id in featuredIds #}
{% set allEntries = craft.entries.section('blog').id('and, not ' ~ featuredIds | join(', not ')) %}

{# Loop and output #}
{% for entry in allEntries.limit(5) %}
  {{ entry.title }}
{% endfor %}

The use of the join filter may seem a bit cryptic. But, when excluding one id from a list of entries, you'd do .id('not 3'). When excluding more than one, you need to specify the conditional first (the and part) and then a comma separated list of not (id). So the join basically creates a string like .id('and, not 3, not 4, not 5'), if the ids of the featured articles where 3, 4 and 5.

Edit: added necessary space to join(', not ')

| improve this answer | |
2
{# set featured entries by finding their IDs #}    
{% set featuredEntries = entry.featuredArticles.ids() %}

{# set all entries by finding their IDs #}
{% set allEntries = craft.entries.section('blog').ids() %}

{# filter out the feature entries from the regular entries #}
{% set filteredEntries = allEntries|without(featuredEntries)

{# loop through blog entries, excluding featured entries #}
{% for entry in craft.entries.id(filteredEntries) %}
  {{ entry.title }}<br>
{% endfor %}

The key here is using Craft's built-in |without filter to remove feature IDs from the regular IDs.

| improve this answer | |
  • 2
    I like how approachable this seems and I think it works well to answer Tyler's scenario given the relatively low number of "Featured" entries. André's answer below, while a little tougher to understand for those new to Twig, would be better for heavier lifting (more entries). – Matt P Feb 22 '16 at 22:51
  • That solution is about 50% less efficient. Not to mention the can of worms you open if you have more than 100 blog entries and want some kind of pagination. – André Elvan Feb 23 '16 at 9:12

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.