Conditional loading of javascript libs

I try to load javascript libs that I use in Kirby blocks. I want to load these libs only if this type of block is used on the page.

I look for a way to say:

‘If one of the blocks on the page has the field ‘parallax’ to ‘isNotEmpty()’ then: (load javascript)’

Now I am using this code, which is not very pretty, and not the way to do this, I am sure.
Who can enlighten me? Thank you in advance!

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
    <?php foreach ($layout->columns() as $column): ?>
      <?php foreach ($column->blocks()->filterby('parallax', '!=', '')->limit('1') as $block): ?>
         (load javascript lib, I know how) 
      <?php endforeach ?>
    <?php endforeach ?>
<?php endforeach ?>

What I would suggest is create a field method that loops through the layouts and columns and adds all blocks to a new Blocks object. That way, you get a plain collection of blocks that you can then filter as you like.

<?php
Kirby::plugin('texnixe/field-methods', [
	'fieldMethods' => [
		'layoutToBlocks' => function($field) {
			$blocks  = new Kirby\Cms\Blocks();
			$layouts =  $field->toLayouts()->map( static function($layout) use($blocks){
				return $layout->columns()->map( static function($column) use($blocks){
					$blocks->add($column->blocks());
				});
			});
            return $blocks;
		}
	]
]);
if ( $page->layout()->layoutToBlocks()->filterBy('parallax', '!=', '')->isNotEmpty() ) {
  // load stuff
}

Or you could even do the filtering in the method but make it more versatile by using arguments to filter by.

I try that but now the
//load stuff
appears if there is at least one block.
I want it to show when inside at least one of the block, the field ‘parallax’ is not empty.

I changed the code slightly. Does that matter?

<?php if ( $page->layout()->layoutToBlocks()->parallax()->isNotEmpty() ) : ?>

TEST

<?php endif ?>

Your code is not valid, I’m afraid.

What I posted above worked in my test. Did you really copy it 1:1? Do you use the parallax field in multiple blocks? Then you should probably filter by block type first.

Maybe post your complete resulting code…

Hi texnixe,

I have been struggling with this issue for a while but I cant get it to work.
Maybe you have an idea??

What I would like to achieve is this:

‘If the page uses blocktype lottie
or if any of the children of the page with notTemplate ‘default’ have a blocktype lottie
then…’

I want to load javascript libs only when they are used.

This works for the page itself but how to get the blocks from the children?

    if ($layouts->hasBlockType('lottie') == true):?>
        <script  src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
        <script src="https://unpkg.com/@lottiefiles/lottie-interactivity@latest/dist/lottie-interactivity.min.js"></script>
    <?php elseif($page->children()->notTemplate('default')->layout()->layoutToBlocks()->hasBlockType('lottie') == true): ?>

Is there a way to merge the blocks from the page and the blocks from the children notTemplate(‘default’)? so I can filter by type?

Thank you in advance.

Merge page and children into a collection then call the map method assigning a prop hasLottieBlock.

Or create page metod hasLottieBlock, then filter the collection by this method

It would be best to have a page method with an argument being the block type, so that it could filter with any blocktype, but I wouldnt know where to start with this page method. How or where can I extend my knowledge?? Thanks!

Page methods are registered in a plugin, see Page methods | Kirby CMS

You can create is so it accepts arguments that you can use to pass the name of the blocks field or the block type to filter by.