I am building a page with a project thumbs section.
The home page looks like this:
<?php snippet('home-header') ?>
<?php snippet('projects') ?>
<?php snippet('home-footer') ?>
The projects snippet looks like this:
<?php $n = 0; foreach($page->children()->visible()->flip() as $project): $n++; ?>
<?php snippet(r($n%2==0, 'project-even', 'project-odd')) ?>
<?php endforeach ?>
And the individual snippets the odd even snippets look like this:
<section class="project-section">
<figure class="project-side project-side-left">
<?php if($image = $project->image('home-page.jpg')): ?>
<img src="<?php echo $image->url() ?>" alt="<?php echo $project->title()->html() ?>">
<?php endif ?>
</figure>
<article class="project-side project-side-right">
<h2><?php echo $project->title()->html() ?></h2>
<p><?php echo kirbytext($project->intro()) ?></p>
<ul>
<?php foreach($project->tags()->split() as $tag): ?>
<li><?php echo $tag ?></li>
<?php endforeach ?>
</ul>
<a href="<?php echo $project->url() ?>" class="project-section-button">View project</a>
</article>
</section>
The error Iām getting is
PHP Notice: Undefined variable: project in project-odd.php line 5
PHP Fatal error: Call to a member function image() on a non-object in project-odd.php line5
Following this example $page->children() | Kirby CMS I donāt see how $project is not defined
The snippet doesnāt know the variable $project, which is only defined in the template. You need to hand it over from the template to the snippet, Iām not quite sure how it works with the short notation above, but usually it is works like this:
<?php snippet('project-odd', array('project' => $project)); ?>
where $project is the variable defined in the template, āprojectā the name by which you want to refer to it in the snippet.
2 Likes
I see! so this is how it is fixed now:
<?php
$n = 0;
foreach($page->children() as $project): $n++; ?>
<?php
if($n%2 == 0) {
snippet('project-even', array('project' => $project));} // code as above, i.e. with article first
else {
snippet('project-odd', array('project' => $project)); //.i.e. with image first
} ?>
<?php endforeach ?>
Ok, and here the short version:
<?php $n = 0; foreach($page->children() as $project): $n++; ?>
<?php snippet(r($n%2==0, 'project-even', 'project-odd'), array('project' => $project)) ?>
<?php endforeach ?>
1 Like
So, what happens if I want to call this variable in the template after modifying it in the snippet. Letās say I want to do something like this:
<?php $color = "used to be black"; ?>
<?php snippet('palette', array('color' => $color)); ?>
<?php echo $color; ?>
Where my āpaletteā snippet contains this:
<?php $color = "now is red"; ?>
I want the echo in the template to return ānow is redā, but it keeps on giving me āused to be blackā. I tried using global
before variables in many different ways, but I couldnāt succeed.
this should work:
in your snippet:
<?php $GLOBALS['color'] = "now is red"; ?>
in your template:
<?php echo $GLOBALS['color'] ?>
2 Likes
Hola, thats quite an old post, but i would like to know, if this is still the way to go, to get variables from snippets in templates in Kirby V3? The following is working, but i was wondering, if there is another solution?
i need the variable $images from my snippet into a template for a json-output.
Thanks!
// example-template.php
<?php
snippet('cover');
$data = [
'coverImages' => $GLOBALS['coverImages'],
'h1' => $page->h1()->text()->value(),
];
echo \Kirby\Data\Json::encode($data);
?>
// cover.php
<?php
$quality = 80;
$images = [];
if($imageMobile = $page->coverMobile()->toFile()) {
$images["mobile"] = $imageMobile->crop(768, 768, $quality)->url();
}
if($imageDesktop = $page->coverDesktop()->toFile()) {
$images["desktop1920"] = $imageDesktop->crop(1920, 768, $quality)->url();
}
$GLOBALS['coverImages'] = $images;
?>
Why do you define the variables in the snippet instead of in the controller?
hmm, i think i would like to avoid having a controller for each template using a cover.
apart from that i just tried your proposal, but unfortunately the snippet could also not access the variable from the controller (why not?). it also only works with a globals variable 
did i make a mistake?
/* controllers/home.php */
<?php
return function ($page) {
$images = [];
$images["testfromcontroller"] = 'testfromcontroller';
return [
'images' => $images
];
};
/* templates/home.php */
<?php
snippet('cover');
$data = [
'images' => $images,
'globalImages' => $GLOBALS['globalImages'],
];
echo \Kirby\Data\Json::encode($data);
?>
/* snippets/cover.php */
<?php
$quality = 80;
$images['testfromsnippet'] = "testfromsnippet";
if($imageMobile = $page->coverMobile()->toFile()) {
$images["mobile"] = $imageMobile->crop(768, 768, $quality)->url();
}
if($imageDesktop = $page->coverDesktop()->toFile()) {
$images["desktop1920"] = $imageDesktop->crop(1920, 768, $quality)->url();
}
$GLOBALS['globalImages'] = $images;
?>
The whole idea was to get get rid of the snippet and move the logic to a different place, either a controller or to a page method, so that you donāt have to move your variables back and forth from the snippet.
If you need this code in all templates, then the method approach is of course the better option.
Your JSON template would then look like this:
<?php
$data = [
'coverImages' => $page->getImageThumbs(),
'h1' => $page->h1()->text()->value(),
];
echo \Kirby\Data\Json::encode($data);
With your getImageThumbs()
method defined in a plugin.
If you want to make the method more versatile, you could extend it with arguments you can pass to it (e.g. thumb sizes).
1 Like
Page Methods works like a charm!
Thank you! @texnixe @pixelijn
<?php
Kirby::plugin('my/page-methods', [
'pageMethods' => [
'getCover' => function () {
$quality = option('my.cover.quality', 80);
$images = [];
if($imageMobile = $this->coverMobile()->toFile()) {
$images["mobile"] = $imageMobile->crop(768, 768, $quality)->url();
}
if($imageDesktop = $this->coverDesktop()->toFile())
$images["desktop1920"] = $imageDesktop->crop(1920, 768, $quality)->url();
}
return $images;
}
]
]);
<?php
$data = [
'cover' => $page->getCover(),
'h1' => $page->h1()->text()->value(),
];
echo \Kirby\Data\Json::encode($data);
?>