Fetch images from children that have certain metadata applied to them

I’m building a photographers portfolio and have set up individual projects as children on a “Projects”-page. The structure looks like:

– Home
– Projects
---- Project A
---- Project B
---- Project C
– About

You get the idea… Photos for each project will be dumped into their respective folders and can have certain metadata applied to them (using file fields), if they should be featured on the front page or not.

Now, I’m sure it’s super easy, but I just can’t seem to figure it out: How would I search all children of “Projects” for featured images and echo them on the front page?

Unfortunately, you cannot get all images of all children in one go, so you need to filter the images within a foreach loop, something like:

<?php
foreach(page('projects')->children() as $child) {
  $featuredImages = $child->images()->filter(function($image) {
    return $image->featured() == 1;
  });
  foreach($featuredImages as $image) {
    //do stuff with the image
  }
} 
?>

Instead of the filter with callback, you can also use filterBy()

1 Like

Cool, that’s a step in the right direction! I just gave it a quick try and it seemed to output only the featured images of the last project. So I guess I need to populate a collection with every iteration the loop, right? Ideally, all featured images from all projects should be stored in a variable.

Since the second foreach loop is within the first, it should iterate through the children first, return a collection of images for the first child, output these images and then go on and do the same for the next child … Can’t currently see the error at the mo …:confounded:

Did you try this? Doesn’t a “toggle” output “true” or “false”? I’m not sure about that though.

<?php
foreach(page('projects')->children() as $child) {
  $featuredImages = $child->images()->filterBy("featured", "true");
  foreach($featuredImages as $image) {
    // stuff
  }
} 
?>
1 Like

Yeah it does. I’ve also found another post on the topic and kind of tried to combine the two. This is what I got so far, still doesn’t work though:

<?php
$featuresImages = new ArrayObject();
foreach(page('projects')->children() as $child) {
  $images = $child->images()->filterBy("frontpageFeature", "true");
  foreach($images as $image) {
    $featuresImages->append($image);
  }
};
?>
1 Like

True and 1 should be the same, when the “==” operator is used and the featured images of the first loop were fetched correctly.

@rppld: remove the semicolon after the closing curly bracket …

Alright, got it:

<?php
  $featuresImages = new Collection();
  foreach(page('projects')->children() as $child) {
    $images = $child->files()->filterBy('frontpageFeature', 'true');
    $featuresImages = $featuresImages->merge($images);
  }
?>

Thanks for your help!

1 Like

Please correct me if I am wrong. In my test ‘true’ and 1 are not the same, when the “==” operator is used with the filterBy method.
For a single checkbox field I have to use 1.
And the toggle field only filters correctly with true.

<?php foreach($page->images()->filterBy("imagevisible", "==", "1") as $image): ?>
  <div class="image">
    <img src="<?= $image->url() ?>">
  </div>
<?php endforeach ?>

The behavior of the checkbox field and the toggle field is not consistent. In the text files you will find:

  • for the toggle field: true/false
  • for the checkbox field: 1/0

I’m not sure if there is an issue on GitHub, need to check this.

1 Like