Slider content in the panel, and foreach loop on front end

Hi all

Once again, new to Kirby and I’m converting my site into Kirby, so far, it’s going okay.

I’m looking at adding my slider content through the panel, and displaying it in the front end using the foreach loop. I’m thinking of ‘duplicating’ the notes mechanism, where I have a ‘slider’ as a tab on the home page in the panel, and then have ‘slides’ as pages with fields and an image. Then displaying it through a loop.

Is this the best way to go about it or is there an easier way?

Currently my slider contains the image, a h1 title, h2 title and a caption. So I’m thinking 3 fields and an image per slide.

Hello,
you could use a Structure Field (Structure | Kirby CMS) to build your Slider Content in a blueprint.

It is just a field where you can add “items” and the term item is what you define, in you case e.g.

your_field_name:
    label: 'Slider'
    type: structure
    fields:
        slide_image:
            label: 'Image'
            type: files
            multiple: false
        slide_headline:
            label: 'H1 Headline'
            type: text
        slide_second_headline:
            label: 'H2 Headline'
            type: text
        slide_caption:
            label: 'Caption'
            type: text

You can then easily enter the field in your template.php as followed:

...
<?php if($page->your_field_name()->isNotEmpty()) 
foreach($page->your_field_name()->toStructure() as $slide): ?>

<?= $slide->slide_image()->url() ?>
<?= $slide->slide_headline() ?>
<?= $slide->slide_second_headline() ?>
<?= $slide->slide_caption() ?>

<?php endforeach; endif; ?>

Hope this helps. You can go even further and just add a Files (Files | Kirby CMS) Field and add Headline, Subheadline and Caption to the Files Blueprint. You can then just iterate over the files and use the File-Fields for your content.

Hi Habundloot

That worked, I just added the columns to that blueprint and it’s perfect.

So now that I have my slides in I have also added a toggle on/off, and then using a php statement if toggle is ‘on’ display slide. Would that be the right way to go about it? Is there a draft/published state for structured fields?

Another question - default values in fields, I can’t seem to set a default value to the toggle or to an options field.

toggle

          status:
              width: 1/3
              label: Status
              type: toggle
              default: Active
              text:
                Inactive
                Active

options

          text_color:
              width: 1/3
              label: Text Color
              type: select
              default: Light
              required: true 
              options:
                light: Light
                dark: Dark

I read on the forum that default values don’t work in Structured Fields - not sure if that is still the case?

Defaults work, but you have to put yes/true or no/false, not your text values.

toggle:
  type: toggle
  default: true
  text:
    Inactive
    Active
1 Like

I’m assuming that’s for the toggle?

Heyho @Milos2504,
I guess you would make it with a toggle as you did. At least that is the way I would do it.

As you can see here Toggle | Kirby CMS the toggle field returns a boolean wich is “true” or “false”. What you do with “Text” Option is make it readable in the blueprint with your own label. But in the Template it returns a boolean. Therefore you have to access it in the Template like (the unnecessary long way for visualization):

<?php if ($page->toggle()->toBool() === true) : ?>
//... do amazing stuff here...
<?php endif; ?>

And in the short way

<?php if ($page->toggle()->toBool()) : ?>
// ... do amazing stuff here...
<?php endif; ?>

That’s possible because your toggle returns “true” or “false” and with the method toBool() it becomes a real Boolean. So the last if clause would return true or false as well as the first one. :slight_smile:

Oh well… it’s a bit too early. But as @texnixe wrote you can set default values, but for toogles it must be the boolean. And dont forget that these values are set when you create a new item. Not for the old ones. :slight_smile:

1 Like

Okay so I tried.

Here is my template

            <?php if($page->slider()->isNotEmpty()) 
                foreach($page->slider()->toStructure() as $slide): ?>
                <?php if ($page->toggle()->toBool() === true) : ?>
                <div class="carousel-item active">
                <picture>
                    <source srcset="<?= $slide->slide_image()->url() ?>" media="(min-width: 768px)">               
                    <img src="<?= $slide->slide_image_mobile()->url() ?>" class="d-block w-100" alt="">
                </picture>
                <div class="custom-caption">
                    <h1 class="d-none d-lg-block"><?= $slide->slide_headline() ?></h1>
                    <h2><?= $slide->slide_second_headline() ?></h2>
                    <h3><?= $slide->slide_caption() ?></h3>
                    <a href="<?= $slide->button_url() ?>" class="btn-big rounded"><?= $slide->button_caption() ?></a>
                </div>
                </div>
                <?php endif; ?>   
            <?php endforeach; endif; ?> 

and it doesn’t work… any help?

Isn’t the toggle inside the structure? Then it should be

<?php if ($slide->toggle()->toBool() === true) : ?>
1 Like

@texnixe is totally right. I forgot about the context. If you switch the if-clause from $page to $slide it should work.

I thought that would be the case too - but I also tried removing that whole if statement and still didn’t work.

Now I’ve changed the $page to $slide and the error in the debugger I’m getting is

ParseError
syntax error, unexpected token “endif”, expecting end of file

Code now looks like,

            <?php if($page->slider()->isNotEmpty()) 
                foreach($page->slider()->toStructure() as $slide): ?>
                <?php if ($slide->toggle()->toBool() === true) : ?>
                <div class="carousel-item active">
                <picture>
                    <source srcset="<?= $slide->slide_image()->url() ?>" media="(min-width: 768px)">               
                    <img src="<?= $slide->slide_image_mobile()->url() ?>" class="d-block w-100" alt="">
                </picture>
                <div class="custom-caption">
                    <h1 class="d-none d-lg-block"><?= $slide->slide_headline() ?></h1>
                    <h2><?= $slide->slide_second_headline() ?></h2>
                    <h3><?= $slide->slide_caption() ?></h3>
                    <a href="<?= $slide->button_url() ?>" class="btn-big rounded"><?= $slide->button_caption() ?></a>
                </div>
                </div>
                <?php endif; ?>   
            <?php endforeach; endif; ?>     

There’s a colon missing…

Instead of checking for the toggle with an if statement, I’d filter the structure items by the toggle field to clean up the code a bit. You also don’t need the first if statement:

<?php foreach($page->slider()->toStructure()->filterBy('toggle', true) as $slide): ?>
  <div class="carousel-item active">
  <picture>
      <source srcset="<?= $slide->slide_image()->url() ?>" media="(min-width: 768px)">               
      <img src="<?= $slide->slide_image_mobile()->url() ?>" class="d-block w-100" alt="">
  </picture>
  <div class="custom-caption">
      <h1 class="d-none d-lg-block"><?= $slide->slide_headline() ?></h1>
      <h2><?= $slide->slide_second_headline() ?></h2>
      <h3><?= $slide->slide_caption() ?></h3>
      <a href="<?= $slide->button_url() ?>" class="btn-big rounded"><?= $slide->button_caption() ?></a>
  </div>
  </div>
<?php endforeach; ?>   

Okay so still no luck with your shortened code. I don’t get an error but nothing is showing up. Could be something to do with the toggle. I tried changing the toggle field name from status to toggle, and then I get an error.

This is my blueprint. Sorry bit long.

tabs:

  # content tab
  slider:
    label: Slider
    icon: grid-top
    fields:
      slider:
        label: 'Slider'
        type: structure
        columns:
          status:
            width: 1/8
          title:
            width: 1/8
          slide_image:
            width: 1/8
          slide_image_mobile:
            width: 1/8
          slide_headline:
            width: 2/8
          slide_second_headline:
            width: 1/8
          slide_caption:
            width: 1/8
        fields:
          title:
              width: 1/3
              label: Title
              type: text
          status:
              width: 1/3
              label: Status
              type: toggle
              default: true
              text:
                Inactive
                Active
          text_color:
              width: 1/3
              label: Text Color
              type: select
              default: Light
              required: true 
              options:
                light: Light
                dark: Dark
          slide_image:
              label: 'Image'
              type: files
              required: true
              multiple: false
          slide_image_mobile:
              label: 'Image Mobile'
              type: files
              required: true
              multiple: false
          slide_headline:
              label: 'H1 Headline'
              type: text
              required: true
          slide_second_headline:
              label: 'H2 Headline'
              type: text
              required: true
          slide_caption:
              label: 'Caption'
              type: text
              required: true
          button_caption:
              width: 1/2
              label: 'Button Caption'
              type: text
              required: true
          button_url:
              width: 1/2
              label: 'Button URL'
              type: text
              required: true

When I rename the toggle field, from ‘status’ to ‘toggle’. I get an error in the debugger.

Whoops \ Exception \ ErrorException (E_WARNING)
Array to string conversion

The error seems to be in the image conversion

<?= $slide->slide_image()->url() ?>

This wont work, files field values always need to be converted to a file object.

<?php if ($slideImage = $slide->slide_image()->toFile()): ?>
  <?= $slideImage->url() ?>
<?php endif ?>

The filter code I posted above should work, no matter if the field is called status or toggle. Make sure that when you change the fieldname in the blueprint, you change it for existing fields in your content files.

And make sure to use the correct field name to filter by in the filterBy method.

1 Like

Thank you!

Finally got it working!