Accessing `$layout→columns() … column()→span()` inside image block to set `sizes`-attribute

TLDR—I’m rendering a layout-field, and to set the sizes-attribute of an img-element correctly, I need access to the current column’s ‘span()’-value. Is there a way to access this value from inside the image-block?


To render a layout-field with 1/1 and 1/2+1/2 columns, I added this code to my template:

<?php foreach ($page->layout()->toLayouts() as $layout): ?>
<div class="grid-row">
	<?php foreach ($layout->columns() as $column): ?>
	<div class="column" style="--span:<?= $column->span(2) ?>">
		<?= $column->blocks() ?>
	</div>
	<?php endforeach ?>
</div>
<?php endforeach; ?>

I also replaced Kirby’s image-block with my own, so I could make use of srcset and sizes. Here are the relevant lines of PHP:

<figure<?= Html::attr(['data-ratio' => $ratio, 'data-crop' => $crop], null, ' ') ?>>
	<?php $sizes = "(max-width: 38rem) calc(100vw - 2rem), calc(100vw - 6rem)"; ?>
	<picture>
		<!-- shortened: removed <srcset>-elements for brevity -->
		<img alt="<?= $image->alt() ?>" src="<?= $image->resize(576)->url()?>" srcset="<?= $image->srcset('column') ?>" sizes="<?= $sizes ?>" width="576" height="<?= $image->resize(576)->height() ?>"/>
	</picture>
</figure>

The problem is that users might add an image to a layout of unknown column-span/width and the sizes-attribute must always assume the largest option, which is full-width (1/1). This quadruples the number of pixels the browser has to download, compared to the single-column width (1/2).

To fix that, the image-block would need to have access to the result of $column→span(2) from the template-file, so it can adapt the $sizes-variable.

Is there a way to access the span(2)-result from inside the image-block or to pass it into the image-block as an argument?

Looking at the code of LayoutColumn I am afraid it creates the blocks collection only passing the field and the parent model (page/site/file/user) but not itself. I would agree that we should change this - could you add an issue in the kirby repo (or I’ll try to add myself one later)?

1 Like

I could file it as a bug report, although it feels more like a feature request, which I can’t file on GH. Should I file it as a bug?

Hey,
you can also pass it to the block snippet if you manually load the snippets.

I’'ve solved this exact problem doing what David pointed out in the doc and it’s pretty straight forward. When i first read your statement i agreed that not having to propagate this info manually would be very nice, but i’m having second thoughts about it because of the potential added complexity on your side.

But i can’t wait to see your implementation if you go for it, might be super trivial somehow!