Fetching images for a snippet from multiple sub folders

Hi all!
I created a gallery slider for my website, but the code is repeating too often, so i want to turn it into a snippet. Here is the code:

<?php if ($page->children()->find('project-01')->hasImages()) : ?>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <?php foreach($page->children()->find('project-01')->images() as $file): ?>
                <figure class="swiper-slide">
                    <img src="<?= $file->url() ?>" alt="<?= $file->alt() ?>">
                    <figcaption><?= $file->caption() ?></figcaption>
                </figure>
            <?php endforeach ?>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
    </div>
<?php endif ?>

My limitation is on fetching the project folder (specified in 2 places on the code). How do you guys optimize this kind of situation?

Thanks in advance for any ideas you can share. Cheers!

<?php 
// fetch the child page into a variable and make sure it exists, then also check if it has images
if (($p = $page->children()->find('project-01')) && $p->hasImages()) : ?>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <?php foreach($p->images() as $file): ?>
                <figure class="swiper-slide">
                    <img src="<?= $file->url() ?>" alt="<?= $file->alt() ?>">
                    <figcaption><?= $file->caption() ?></figcaption>
                </figure>
            <?php endforeach ?>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
    </div>
<?php endif ?>

But in the title it says you want to fetch images from multiple subfolders, here we have only one? So I have a feeling there is some context missing…

Thanks, texnixe,
Yeah, i will list multiple projects on a single-page site. Images come from folders with a serial number: project-01, project-02, project-03, etc.

I tried your idea like this:

<?php  if (($p = $page->children()->find('project-01')) && $p->hasImages()) : ?>
    <?php snippet('gallery') ?>
<?php endif ?>

And then repeated it for project number 2, and i would continue like so until i reach the end of the list,

<?php  if (($p = $page->children()->find('project-02')) && $p->hasImages()) : ?>
    <?php snippet('gallery') ?>
<?php endif ?>

But it doesn’t work. I went back to adding the swiper-container element. How could i change the “project-01” into something more automatic, like, following the order of the folders that are there? I’m not sure if i’m being clear… Basically i have this folder structure with images inside of each folder:

Annotation 2020-04-05 224445

But then all you have to do is loop through these children instead of fetching every single child individually:

<?php foreach ($page->children()->listed() as $child) : ?>
  <?php if ($child->hasImages()) : ?>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <?php foreach ($child->images() as $file): ?>
                <figure class="swiper-slide">
                    <img src="<?= $file->url() ?>" alt="<?= $file->alt() ?>">
                    <figcaption><?= $file->caption() ?></figcaption>
                </figure>
            <?php endforeach ?>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
    </div>
<?php endif ?>
<?php endforeach ?>

(Assuming we are in the home.php template and calling the snippet)

Note that if you only put the swiper-container into the snippet, you would have to pass the $child variable to the snippet, like explained in my next post.

This cannot work, because $p is not known inside the snippet, you would have to pass it to the snippet snippet('gallery', ['p' => $p]). But for you use case, what I posted above would be more useful anyway.

It almost works, but now i am forcing all galleries to appear inside each project. Here’s my HTML (yes, it’s inside the homepage only):

Edit: how would i only list one gallery inside each tag, using your method?

Ok, in this case each section should be in the snippet in this case because everything is repetitive, not only the gallery:

<?php foreach ($page->children()->listed() as $child) : ?>
  <?php snippet('gallery', ['child' => $child]) ?>
<?php endforeach ?>

Then in snippet:

<section>
<?php echo $child->...??->kirbytext(); // is project-1() really the field name, seems strange ?>
<?php if ($child->hasImages()) : ?>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <?php foreach ($child->images() as $file): ?>
                <figure class="swiper-slide">
                    <img src="<?= $file->url() ?>" alt="<?= $file->alt() ?>">
                    <figcaption><?= $file->caption() ?></figcaption>
                </figure>
            <?php endforeach ?>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
    </div>
<?php endif ?>
</section>

Please don’t post code as screenshots in the future, I can’t copy from that.

1 Like

Or if you only want the gallery in the snippet:

<?php foreach ($page->children()->listed() as $child) : ?>
<section>
  <?php echo $child->text()->kirbytext(); ?>
  <?php if ($child->hasImages()) : ?>
    <?php snippet('gallery', ['child' => $child]) ?>
  <?php endif ?>
</section>
<?php endforeach ?>

Snippet:

    <div class="swiper-container">
        <div class="swiper-wrapper">
            <?php foreach ($child->images() as $file): ?>
                <figure class="swiper-slide">
                    <img src="<?= $file->url() ?>" alt="<?= $file->alt() ?>">
                    <figcaption><?= $file->caption() ?></figcaption>
                </figure>
            <?php endforeach ?>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
    </div>

Oh, sorry for the code screenshot! Yeah, i’m pulling the text content from home.txt, where i have the whole content, i have fields like so: project01, project02, project03, etc.

Rendered, i’d have text and the sliding gallery after, for each project.

It’s a single page site, so my first thought was having all content in one file, the home.txt. But now with the images organized in folders, it makes more sense to have a txt content file for each project. I tested it this way and it works. I do lose the ability to edit everything in one file, but now it’s more organized.

Thanks for your help, texnixe!