Displaying Entries Based on User Input

Problem

You want to display x entries on the homepage. 0...x of these entries may have been specified by the site author, using an Entries field. Those projects must come first, and the remaining n slots must be filled with the most recent entries, no duplicates allowed.

Solution

Let’s say you have retrieved a single Entry from a services section.

That Entry contains an Entries field entitled relatedProjects, which may contain up to 6 related projects, selected by the author (six isn’t in any way significant, the recipe will work just fine for any number).

If the author has selected fewer than 6 related projects, we want to make up the numbers with the newest entries in the projects section. Here’s how we go about that:

  1. We retrieve the related projects chosen by the site author. We call this the chosen list.
  2. If the chosen list contains fewer than 6 entries, we retrieve the 6 most recently published projects. We call this the recent list.
  3. We remove any of the chosen entries from the recent list, to ensure we don’t have any duplicates.
  4. We merge our chosen and recent lists, and limit the length of our new list to 6 items, and call this the filtered list.
  5. We pass our filtered list to craft.entries, to retrieve the entry details.

Enough talk, let’s see some code:

{% set chosen = entry.relatedProjects.ids() %}
{% if chosen | length < 6 %}
    {% set recent = craft.entries.section('projects').limit(6).ids() | without(chosen) %}
    {% set filtered = chosen | merge(recent) | slice(0,6) %}
{% endif %}

{% set projectsToDisplay = craft.entries.section('projects').id(filtered).fixedOrder(true) %}

Full credit for this recipe goes to Jérôme Coupé for this recipe (with some input from Brandon Kelly), which first appeared on the Craft Google+ group.