Parsing data from parents based on template

Hi all - I have an unique site setup where I am storing a variable in a page blueprint and need to fetch this in subpages.

department.yml

fields:
      primaryColour:
        type: text

header.php snippet

<style>
:root {
<?php if ($page->template() == 'department'): ?>
  --primary: #<?= $page->primaryColour() ?>;
<?php elseif ($page->template() == 'blocks'): ?>
  --primary: #<?= $page->parent()->primaryColour() ?>;
<?php else: ?>
  --primary: #53A9B2;
<?php endif ?>
}
</style>

As you can see I am parsing a hex colour value to global stylesheet variables. My site page structure uses the ‘department’ template as parent pages and the ‘blocks’ template as a child template. The above works in an instance where the blocks child page is only 1 layer deep, but if it has another child then the parent it calls is just the block template, and I’m only storing the value in the department template.

Is there a function that allows me to pull a variable from the last instance of a template in a page url. So for example,

<?php if ($page->template() == 'blocks'): ?>
// get primaryColour field from last parent that uses the 'department' template
<?php endif ?>

Thanks so much

$page->parents()->last()

gives you the “root” ancestor.

Thanks for the reply. So I’ve got that working when on a page that has a parent with the chosen template in the path:

<?= $parentDepartment = $page->parents()->findBy("intendedTemplate", "department");?>
<?= $parentDepartment->title() ?>

But I’m struggling to use this with some login, which i’m sure is very rudamentry

<?= $parentDepartment = $page->parents()->findBy("intendedTemplate", "department");?>

<?php if ($parentDepartment->title()->isEmpty()): ?>

note: there is no department template in this url path

<?php endif ?>

Any help appreciated, thank you

What are you trying to check here? This will result in a PHP error when there is no parentdepartment page (calling title on null)

If you want to check if the page exists, then that would be

if ($parentDepartment) {
  // exists
}

Thanks so much, I didn’t realise that the page didn’t exist it would error, I thought it would just return as empty. That’s working now.

However another cheeky question, is there a way to make the below also cover the current page.

So specifically, find intendedTemplate within parents AND current page.

<?= $parentDepartment = $page->parents()->findBy("intendedTemplate", "department");?>

Thanks again for the invaluable help

To understand this, it is important to learn that Kirby is based on objects. A page, a pages collection, a field etc. are all objects and these objects are instances of their. class. Each class comes with a set of methods/properties. Put the other way round, when calling such a method, this in turn of course requires an object of this class. This means you cannot call such a method on anything else (not a string, not an array, not another type of object and of course also not on null). Further introduction: A brief intro to object oriented programming in PHP | Kirby CMS

You can use an or statement

<?php if $page->intendedTemplate()->name() === 'department' || $parentPage = $page->parents()->findBy('intendedTemplate', 'department')): ?>

<!-- do stuff -->
<?php endif ?>

That makes sense, so much to learn and thanks so much for that it’s so helpful!