I’ve got this snippet defined in snippets/blocks/cta.php:
<div class="container">
<a class="btn" href="<?= $data->content()->url() ?>">Join us!</a>
</div>
Is there any way to re-use this snippet from a different page? I know that I can pass data via the snippet
function (e.g. snippet('blocks/cta', array('data' => $page)
), but in this case I’d have to add a url field to the $page
object I’m passing along? Is there any better way?
Start over: Ok, you are using content
here because of the conflict with the url()
method, right?
And you want to use the snippet with content from the current page, but use $page->url()
of course, and not the content of a url()
field. Wondering if you have to use content()
here at all, since $data
is not a page object.
Awesome, this works:
<?php snippet("blocks/cta", ["data" => $page]) ?>
or even
<?php snippet("blocks/cta", ["data" => page("join-us")]) ?>
and the snippet:
<div class="container">
<a class="btn" href="<?= $data->url() ?>">Join us!</a>
</div>
Now, if I want to be able to change the link text as well, is there a way to pass it along as well, even if $page or page(“join-us”) don’t have that field?
Yes, you can make it dynamic, but then you have to pass the variable every time you call the snippet:
Snippet:
<a class="btn" href="<?= $data->url() ?>"><?= $linktext ?></a>
In template:
<?php snippet("blocks/cta", ["data" => $page, 'linktext' => 'Join us']) ?>
or when using it in the builder loop:
<?php snippet("blocks/cta", ["data" => $block, 'linktext' => $block->linktext()]) ?>
Right. But that won’t work if I use a specific field from my builder blocks, e.g. $data->headline()
. Is there a way to add this field to $page
and just passing the data
array/page object?
Why not? That’s why I posted the second example above.
But of course you can also add a field to your pages. You can even use a different fieldname, if you make the fieldname dynamic and pass it to the snippet.
Because I can’t add additional variables to my builder loop. No other block makes use of these variables:
foreach($page->builder()->toBuilderBlocks() as $block) {
snippet('blocks/' . $block->_key(), array('data' => $block));
}
<?php snippet("blocks/cta", ["data" => page("join-us")]) ?>
works however and I was wondering if I could add fields to the data
object/array?
Yes, you can, by adding a condition:
foreach($page->builder()->toBuilderBlocks() as $block) {
$data = ['data' => $block];
if ($block_key() === 'name_of_block_with_linkfield') {
$data['linktext'] = $block->linktext()->value();
}
snippet('blocks/' . $block->_key(), $data);
}
Or shorter:
foreach($page->builder()->toBuilderBlocks() as $block) {
snippet('blocks/' . $block->_key(), [
'data' => $block,
'linktext' => $block->linktext()->exists() ? $block->linktext()->value() : null
]);
}
It is irrelevant if the $linktext
variable is used in the snippet or not.
Oh right, now I get it. Thanks for the explanation!
I was just wondering if there is a way to do the same thing without modifying the builder loop. Like modifying the data object before using the snippet as usual. Something like (not working):
$data = page("join-us");
$data['linktext'] = "Join us";
snippet("blocks/cta", ["data" => $data]);
Not like that, but like this:
// add filters
$data = ['data' => page("join-us")];
$data['linktext'] = "Join us";
snippet("blocks/cta", ["data" => $data]);
Yeah, that was what I thought as well, but it gives me this error:
Call to a member function url() on array
site/templates/session.php:
[...]
<?php
$data = ['data' => page("join-us")];
$data['linktext'] = "Join us";
snippet("blocks/cta", ["data" => $data]);
?>
[...]
site/snippets/blocks/cta.php:
<a class="btn" href="<?= $data->url() ?>"><?= $data->linktext()->escape() ?></a>
Oh, yes, right, because it you then would have to use $data['data']
.
You can modify it like this:
snippet("blocks/cta", [
"data" => page("join-us"),
'linktext' => 'join us'
]);
1 Like