Find a unique article for each tag in a loop

Hi there, I’ve been racking my brain for a couple of hours on this but haven’t really found a solution.

I have a list of categories with an image from an article based on this category attached.

The issue here is that articles have multiple categories. This means the image chosen can appear multiple times.

I’m trying to make sure that each article chosen is unique.

<? foreach($tags as $tag): ?>
  <?
    $existing = ''; 
    $selectedArticle = $articles->not($existing)->filterBy('tags', $tag, ',');
    $image = $selectedArticle->images()->filterBy('featured', 'Featured');
    $existing .= '\'' . $selectedArticle . '\', ';
  ?>
  <span class="category-name"><?= $tagname ?></span>
  <img src="<?= $image->url() ?>" class="category-image" alt=""/>
<? endforeach ?>

Any ideas?

Where are you setting that, and how? if your using pluck tags, you can set true which will only find unique tags, and i think in turn, will mean you wont end up with duplicate article images.

But there are bits of your code that doesnt make alot of sense. your setting $existing = ''; and then using it while empty inside ->not(), which wont do anything.

Then $existing .= '\'' . $selectedArticle . '\', '; … what are you trying to do there? you don’t seem to be using these variables in the rest of the foreach, apart from $image

1 Like

No, that’s not quite correct, because if each article has multiple tags, it could happen that you get duplicated images.

@iam_timm Your general idea is correct, but you would have to add the newly found article to a new pages collection (at least that makes things easier) that you declare outside the loop (otherwise, it will be empty again at each new loop). Also, your selected article is not a single page but a collection, so using findBy() is more useful here, or limit filterBy() to the first article.

However, what if you are left without an article for the tag, because the one with only one tag was already used for another tag?

Something like this maybe(not tested):

<?php
$existing = new Pages();
foreach($tags as $tag):

    if ($selectedArticle = $articles->not($existing)->findBy('tags', $tag, ',')) :
      $image = $selectedArticle->images()->findBy('featured', 'Featured');
      $existing  = $existing->add($selectedArticle);
    endif;
?>
<?php if ($image) : ?>
  <span class="category-name"><?= $tagname ?></span>
  <img src="<?= $image->url() ?>" class="category-image" alt=""/>
<?php endif ?>
<?php endforeach ?>

On a side note: It is not recommended to use PHP short tags (<?). It also makes it more difficult to easily test your code in our environments.

Thanks! This works perfectly and I understand the solution.