Kirby Builder Plugin - Display assets from files field within template


I’m currently building a website and am using the Kirby Builder plugin to create modules which I can setup within the panel, this is now all working really nicely (blueprint below), however I’m struggling to get the images from the gallery module(s) to display on the page.

Here is the blueprint which defines the gallery module:

title: Case Study
icon: 🖼
  draft: true
  listed: true

# Fields
    label: Modules
    type: builder
        name: Gallery
            label: Assets
            icon: image
                label: Assets
                type: files
                layout: cards
                size: small
                info: "{{ file.dimensions }}"
                  ratio: 4/3
                  cover: false
                  back: white
            label: Style
            icon: cog
                label: Style
                type: radio

The template itself is using the below code to pull through a snippet for each module:

    foreach($page->mybuilder()->toBuilderBlocks() as $block):
      snippet('blocks/' . $block->_key(), array('data' => $block));

Within the gallery snippet / block I’ve tried various things to try and get the images to display however I’m not having any luck - Can someone advise on how to go about accessing and outputting the images? Here is what I have so far:

<?php foreach($page->mybuilder()->gallery() as $gallerymodule): ?>
        $images = $gallerymodule->assets()->toFiles();
        foreach($images as $image):
        <img src="<?= $image->url() ?>" alt="">
    <?php endforeach ?>
<?php endforeach ?>

Any help / advice on what I’m doing wrong would be much appreciated!

Thank you,

Should be

        $images = $data->assets()->toFiles();
        foreach($images as $image):
        <img src="<?= $image->url() ?>" alt="">
    <?php endforeach ?>

Wow, thank was quick and working perfectly, thank you Texnixe :+1:.

Just so I can learn and figure out where $data comes from, is that defined within the array in the template? I presume $data stores the input from the fields so I then use $data to access all of the modules and their contents? Any explanation of what this doing would be so helpful:

array(‘data’ => $block));

Thank you,

Here you store the $block variable in $data in the snippet. I personally don’t know if this is such a happy decision and would myself use the $block variable inside the snippets and therefore store $block in block:

snippet('blocks/' . $block->_key(), array('block' => $block));

but that is completely up to you, you can freely define what variable you want to use inside the snippet. data is not set in stone. However, if you copy stuff from examples, you have to keep in mind that these examples might use different variables.

In any case, inside the snippet, the variable you use refers to an individual block, which has a set of fields that you can call by $data->fieldname()- do not call the main builder field again inside your snippet.

On a side note: If your block contains a nested builder field, you would then have to call the toBuilderBlocks() method again on that field inside the snippet-

Understood, that makes perfect sense - Many thanks for taking the time to help me understand, I would have never of figured that out and agreed $block would make more sense over $data so I’ll update that now.

Noted re: nested fields, will remember that moving forward! :+1:

Thank you!

For some more background information:

This works the same way for all snippets, not only the ones used for the builder blocks. And you can of course pass more variables to snippets if needed

snippet('my-super-snippet', ['article' => $page, 'class' => 'superclass', 'color' => 'blue']):

With this setup, you can use the variables $article, $class and $color` in your snippet and they will have the values you assigned to them.

Of course, you can also set default values inside the snippets in case a variable is not defined:

E.g. in snippet:


$color = $color ?? 'red';

If $color in not passed to the snippet, the default value red will be used.

Amazing, thank you for the extra information Texnixe, that makes perfect sense, thank you!