Show each block as a single slide

Hello,
I am using a swiper js to show some images and on the last slide I need to have some project description, credits etc. So I thought the better way to do this would be to use the blocks fields. One field would be the gallery and for the description I think I will build a custom block to use a structure field with everything I need. At the moment I am testing the slider with just the gallery and some text from the built-in fields but somehow I can’t manage to show the gallery’s images and the text as single slides, they just all show below each other. I hardcoded this page first and everything works fine from the side of the slider and javascript. I would love to get some help here or if you think there’s a better way to do what I need I appreciate the tipp. When I inspect the code each slide is there and the counter is right but the content is just showing all on the first slide and the images are all showing on 1 slide as well because I am looping through them but I am not sure how to change this here is my code:
gallery php:

<?php /** @var \Kirby\Cms\Block $block */ ?>


    <?php foreach ($block->images()->toFiles() as $image): ?>
 
          <figure>
      <?= $image ?>
      <figcaption>lorem ipsum</figcaption>
        </figure>  
   
    <?php endforeach ?>
 

project php:

<div class="swiper mySwiper top">
      <div class="swiper-wrapper">
      
      <?php foreach ($page->imgs()->toBlocks() as $block): ?>
        <div class="swiper-slide" >
          <div class="slide-container">
          <?= $block ?>
        </div>
        </div>
        <?php endforeach ?>





      </div>
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
  
    </div>

Hi,

If I understand, this is something like this.

<div class="swiper mySwiper top">
      <div class="swiper-wrapper">
      
      <?php foreach ($page->imgs()->toBlocks() as $block): ?>
        <div class="swiper-slide" >
          <div class="slide-container">
          <?= $block ?>
        </div>
        </div>
        <?php endforeach ?>
        <div class="swiper-slide" >
          <div class="slide-container">
          <?= $page->description(); // you're description field ?>
        </div>
        </div>




      </div> <!-- end of the wrapper -->
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
  
    </div>

If the JS doesn’t work, check your browser console to find a clue.

Thank you for your time, the JS is working the only problem is that I did exactly as you wrote but first the slider only counts 2 slides (1 for image and 1 for description) because somehow all the images are being displayed in 1 slide only instead 1 slide for each image and second the description is only showing on the first slide and when I click the slide works but the next slide is just empty. I just don’t understand what am I doing wrong. (please see screenshot attached). I really appreciate your help since I am really stuck here! Thank you so much!

Not easy to help you without more code… here is my html in the inspector when I use swiper (with loop option).

I changed the code a little bit and now everything is as it should when I inspect it but even though the slider counts 5 slides the content is being shown on the first slide. (please see screenshot, black image should be slide 1, blue image should be slide 2, etc) but the content doesn’t stay inside the slide, it just goes down like a scrolling page.

here is my code:
gallery.php

<?php /** @var \Kirby\Cms\Block $block */ ?>


    <?php foreach ($block->images()->toFiles() as $image): ?>
      <div class="swiper-slide" >
          <div class="slide-container">
          <figure>
      <?= $image ?>
      <figcaption>lorem ipsum</figcaption>
      
        </figure>  
        </div>
        </div>
        <?php endforeach ?>
 

project php

<div class="swiper mySwiper top">
<div class="swiper-wrapper">
      
      <?php foreach ($page->imgs()->toBlocks() as $block): ?>
     
          <?= $block ?>
        
        
        <?php endforeach ?>

        <div class="swiper-slide">
    <div class="slide-container">

    <?php
// Strucutre: using the `toStructure()` method, we create a structure collection
$items = $page->proj()->toStructure();
// we can then loop through the entries and render the individual fields
foreach ($items as $item): ?>

<div class="project-description">
        <p class="proj-text">
        <?= $item->description()->html() ?>
        </p>
      </div>
        <div class="proj-infos">
        <p class="info-name"><?= ucfirst($page->place()->key()) ?></p>
          <p class="info-description"><?= $item->place() ?></p>
          <p class="info-name"><?= ucfirst($page->material()->key()) ?></p>
          <p class="info-description"><?= $item->material() ?></p>
          <p class="info-name"><?= ucfirst($page->type()->key()) ?></p>
          <p class="info-description"><?= $item->type() ?></p>
          <p class="info-name"><?= ucfirst($page->function()->key()) ?></p>
          <p class="info-description"><?= $item->function() ?></p>
          <p class="info-name"><?= ucfirst($page->size()->key()) ?></p>
          <p class="info-description"><?= $item->size() ?></p>
          <p class="info-name"><?= ucfirst($page->credits()->key()) ?></p>
          <p class="info-description"><?= $item->credits()->kti() ?></p>
        </div>
<?php endforeach ?>      
      </div>
</div>



      </div>
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
  
    </div>


<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
    <script src="assets/js/index.js"></script>
</body>
</html>```

Any message in console (cmd+alt+j in Chrome) ?
CSS from slider is important too.
JS is in the footer ?

Your question just solved my problem, I forgot to include the CSS link from the swiper! thank youuu and thank you for all your help your first answer also helped me to structure the code beteer!! THANK YOU

1 Like

I just have one more question, is it possible to only call a specific block like only the gallery? at the moment I am looking through all the blocks even though I only need the gallery and I just don’t want in the future if my client adds another block my mistake that this will show on the website! thank you sooo much!!

You can filter blocks by type:

$gallery = $page->blocks()->toBlocks()->filterBy('type', 'gallery');

This will give you all gallery blocks. If you only want to get the first:

$firstGallery = $page->blocks()->toBlocks()->filterBy('type', 'gallery')->first();
2 Likes

thank you so much for your help!!

I am sorry, I bumped into another problem! On this slider I need the possibility of adding 2 images side by side per slide or just 1 image per slide. My idea was to use a select field for images left and images right and say if these select field exists the images should be shown side by side otherwise is just 1 image per slide. at the moment I still get only 1 image per slide, I know this code is not correct and I have tried a lot of other things but I can’t seem figure it out the best way to achieve this. do you have any idea of should I achieve this? thank you so much, I appreciate every input. here’s my blocks gallery php:

<?php /** @var \Kirby\Cms\Block $block */ ?>


    <?php foreach ($block->images()->toFiles() as $image): ?>
     
      <div class="swiper-slide" >
      
      <?php if($block->images()->toFiles()->findBy('slide', 'left')):?>   
        <div class="slide-container two-imgs">
        <?php $classfig = 'fig-' . $image->slide(); ?>
        <figure class="<?= $classfig ?>">
          <img src="<?= $image->url() ?>" alt="<?= $image->caption() ?>">
      <figcaption  class="two-fig"> <?= $image->caption() ?></figcaption>
        </figure>  
        </div>
        <?php elseif($block->images()->toFiles()->findBy('slide', 'right')):?> 
          <figure class="<?= $classfig ?>">
          <img src="<?= $image->url() ?>" alt="<?= $image->caption() ?>">
      <figcaption  class="two-fig"> <?= $image->caption() ?></figcaption>
      
        </figure>  
        </div>
        <?php else: ?>
          <div class="slide-container">
          <figure>
          <img src="<?= $image->url() ?>" alt="<?= $image->caption() ?>">
      <figcaption> <?= $image->caption() ?></figcaption>
      
        </figure>  
        </div>
        <?php  endif?>

      </div>
        <?php endforeach ?>

and here’s my project.php


<div class="swiper mySwiper top">
<div class="swiper-wrapper">
      
<?php foreach ($page->slides()->toBlocks()->filterBy('type', 'gallery') as $block): ?>
     
          <?= $block ?>
        
        
        <?php endforeach ?>

        <div class="swiper-slide">
    <div class="slide-container">

    <?php

$items = $page->proj()->toStructure();
foreach ($items as $item): ?>
<div class="project-description">
        <p class="proj-text">
        <?= $item->description()->html() ?>
        </p>
      </div>
        <div class="proj-infos">
        <p class="info-name"><?= ucfirst($page->place()->key()) ?></p>
          <p class="info-description"><?= $item->place() ?></p>
          <p class="info-name"><?= ucfirst($page->material()->key()) ?></p>
          <p class="info-description"><?= $item->material() ?></p>
          <p class="info-name"><?= ucfirst($page->type()->key()) ?></p>
          <p class="info-description"><?= $item->type() ?></p>
          <p class="info-name"><?= ucfirst($page->function()->key()) ?></p>
          <p class="info-description"><?= $item->function() ?></p>
          <p class="info-name"><?= ucfirst($page->size()->key()) ?></p>
          <p class="info-description"><?= $item->size() ?></p>
          <p class="info-name"><?= ucfirst($page->credits()->key()) ?></p>
          <p class="info-description"><?= $item->credits()->kti() ?></p>
        </div>
<?php endforeach ?>      
      </div>
</div>



      </div>
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
  
    </div>

The closing div before else looks wrong

I already tried to change it but keep getting only 1 image per slide. the idea would be the first if to put 2 images side by side (left & right classes) and else only 1 image per slide. but at the moment is only 1 image per slidie