Image-Block Counter & display number

I’m looking for a way to let kirby count how many Images are in a foreach-loop and then display the specific number underneath them.

I’m using Kirby Blocks and some Blocks contain just text and one block contains an Image. But when an Image-Block is placed, I want to display the number under it in order to refer to them in a footnote.

Currently I’m displaying my blocks like this:

        <?php foreach ($page->blocks()->toBlocks() as $block): ?>
            <div id="<?= $block->id() ?>" class="block block-type-<?= $block->type() ?>">
                <?= $block ?>
            </div>
        <?php endforeach ?>

I’ve found something on the forum for a similar case and implemented it in my Image-Block-Snippet (although I think it’s completely wrong to place it into the block-template):

<figure>
  <ul>
    <?php $index = 0; foreach ($block->images()->toFiles() as $image): $index++; $next = $index + 1; ?>
      <li>
        Image <?php echo $index ?>
        <?= $image ?>
      </li>
    <?php endforeach ?>
  </ul>
</figure>

Maybe someone could help me to use it the right way…
(In the end it should be possible to put Images between other blocks and the counting should work nevertheless)

Thanks in advance! :slight_smile:

You can use a counter variable which you update whenever the block type is image:

<?php
$imageCounter = 1;
foreach ($page->blocks()->toBlocks() as $block): ?>
     <div id="<?= $block->id() ?>" class="block block-type-<?= $block->type() ?>">
                <?= $block ?>
                <?php if ($block->type() === 'image') {
                  echo $imageCounter;
                  $imageCounter++;
                } ?>
    </div>
<?php endforeach ?>

That works for me, thanks!

I have two different image-blocks, the first is named “image-1” and the second “image-2”, so I had to change the

if ($block->type() === 'image')

to

if ($block->type() === 'image-1')

But how is the syntax for "equals ‘image-1’ or ‘image-2’ ?
I’ve tried

if ($block->type() === 'image-1', 'image-2')

and

if ($block->type() === 'image-1' 'image-2')

but it’s not working yet.

solution underneath
And last question: How can I now insert html stuff in order to display the number under the image with css styling?
In my image-1-blueprint I had:

<li>
   Abb. <?php echo $index ?>
   <?= $image ?>
</li>

, but this won’t work with $imageCounter
solution underneath

Thank you!

Just solved my last question by simply putting the html stuff underneath the script
(Complete code):

        <?php
            $imageCounter = 1;
            foreach ($page->blocks()->toBlocks() as $block): ?>
                <div id="<?= $block->id() ?>" class="block block-type-<?= $block->type() ?>">
                    <?= $block ?>
                    <?php if ($block->type() === 'image-1') {
                        echo $imageCounter;
                        $imageCounter++;
                    } ?>
                    <li>
                        Abb. <?php echo $imageCounter?>
                    </li>
            </div>
        <?php endforeach ?>
<?php if (in_array($block->type(), ['image-1', 'image-2'])) {
 echo $imageCounter;
 $imageCounter++;
} ?>

Thanks, that works.

Is there an option to echo the number for each Image in an image-block?
My Image-2-Block has two images and it should therefore echo both numbers for each image…

Wouldn’t you have to do that inside the block then?

Yes but then every image-block would only count their images in itself and not the other images on the page, right?

That’s right, you would have to pass the current count to the block snippet, and of course update your counter by 1 for one image, and by 2 for two images. It would make sense to use two if statements for each use case.

1 Like

yes that sounds good, but I don’t have any idea how to do that as I just started using Kirby and php, would you mind to show that as a code snippet? :slight_smile:

Something like this:

<?php
$imageCounter = 1;
foreach ($page->blocks()->toBlocks() as $block): ?>
    <div id="<?= $block->id() ?>" class="block block-type-<?= $block->type() ?>">
        <?php if ($block->type() === 'image-1') {
            snippet('blocks/' . $block->type(), ['imageCounter' => $imageCounter]);
            $imageCounter++;
        } elseif ($block->type() === 'image-2') {
          snippet('blocks/' . $block->type(), ['imageCounter' => $imageCounter]); // add + 1 for the second image inside the block
          $imageCounter = $imageCounter + 2; // this will only work correctly if you make sure that this block always has 2 images
        } else {
          echo $block;
        }
        ?>
    </div>
<?php endforeach ?>

Then echo the counter inside those snippets.

1 Like

Wow looks great, thank you so much!

Is there maybe also an option for looking for images inside a block? My second block will probably sometimes have just 1 of 2 images filled.

Maybe something like this?:

$blocks->has(string|object $id): bool
<?php
$imageCounter = 1;
foreach ($page->blocks()->toBlocks() as $block): ?>
    <div id="<?= $block->id() ?>" class="block block-type-<?= $block->type() ?>">
        <?php if ($block->type() === 'image-1') {
            snippet('blocks/' . $block->type(), ['block' => $block, 'imageCounter' => $imageCounter]);
            $imageCounter++;
        } elseif ($block->type() === 'image-2') {
          snippet('blocks/' . $block->type(), ['block' => $block, 'imageCounter' => $imageCounter]); // add + 1 for the second image inside the block
          $up = $block->imageField()->toFiles()->count();
          $imageCounter = $imageCounter + $up;
        } else {
          echo $block;
        }
        ?>
    </div>
<?php endforeach ?>

You might have to do the same for the image-1 block in case there is no image.

1 Like

That’s very smart, thanks! :slight_smile:

Hey @pixelijn, thanks again for the piece of code which will definitely help me a lot.

Nevertheless I am kind of stuck with coding the snippets correctly. You said that I now have to echo the counter inside the snippets.

I think by that you mean that I have to count the images inside a snippet, then pull the updated “up-value” out of the snippet and finally add it to the $imageCounter. Is that correct?

I am also a little bit confused about this part - is this pulling the amount of images inside the snippet?:

['block' => $block, 'imageCounter' => $imageCounter]

I’d be more than happy if you could show me what I have to write inside a snippet so everything works.

Thank you very much in advance! :slight_smile: