Changing page date based on date of first child


#1

Hi all,

I’m working on developing a new structure for my site, and I’ve hit a wall with a date-based question.

I’m building a list of articles, some of those articles have subpages that will be added to (sort of sub-articles if you will). I would like to change the date of the parent article based on the date of the most recent child.

The goal here is that all the parent articles would be ordered by date even if they don’t have children (some types of articles in the main list do, some don’t), and that when a new child is added to one, that child’s date becomes the sorting date.

I don’t want to use the modified() option, as the parent article also contains content that may get changed even without adding a new child.

My current blueprint for the parent article does not contain a date, what I was hoping to do was populate a date for the parent article based on the date field of the most recent child, as that would keep my logic clean in the main list.

Thanks for any help!


#2

If you want to display this date in the Panel (and use it for sorting in the Panel), then I’d use a [hook] (https://getkirby.com/docs/developer-guide/advanced/hooks) , to be precise a panel.page.create hook, that updates the date when a new child is added.

If it is only important on the frontend, you could use either the hook solution described above, or the map() method to create a virtual date if the page doesn’t have its own date.


#3

Thanks! I will look into the hooks and see if I can get it working that way.


#4

So I’ve gotten the hook activating but ran into a few issues.

Here’s is where the hook started, but this threw a few errors my way:

<?php
kirby()->hook('panel.page.create', function($page) {

if($page->isChildOf(template('series_visual'))) {
	$newPage = $page;
}
// this is the page which has the structure field type
$seriespage = $page()->parent();

// add a new entry to the array
$dateupdate[] = ['sortdate' => $newPage->date()];

// update the structure field type
$seriespage->update(yaml::encode($dateupdate));

});

And my blueprint code is currently this:

  sortdate:
  	label: Most Recent Date
  	type: structure

I initially set the field to be date but it told me that was reserved so I switched the field to be sortdate.

Once I then created a new page under a page with the ‘series_visual’ template it threw me an error that the childOf couldn’t be a template - I am hoping to do this whenever I create a new child of any page that has that template rather than a specific page.

I changed that to be just page specific and I’m getting this error when I try to create a new subpage:

Call to a member function id() on boolean in file: /nfs/c01/h03/mnt/11800/domains/test.randy-gibson.com/html/kirby/core/page.php on line: 807

If I switch the hook to be panel.page.update I get the same error when I try to save the subpage.

I’m sure there’s a myriad of things wrong with this, but I couldn’t find any solid documentation of the methodologies for these hooks so I’m working from this post: Kirby 2.1 Hook Usage- Creating Subpages

Many thanks for any help figuring this out!!


#5

Updated. I have tried some new things with the hook and, while it’s not working, it is also not throwing me any errors.

Will attempt to install the debugger plugin and see if I can sort it, but appreciate any help.

kirby()->hook('panel.page.create', function($page) {

if($page->parent()->template() == 'series_visual') {
	$newPage = $page;
}
// this is the date source
$newdate = $page->date();

// this is the page to be updated
$seriespage = $page->parent();

$seriespage->update(array(
  'date' => function($newdate) {
    return str::lower($newdate);
  }
));

});

#6

Your code should look like this:

kirby()->hook('panel.page.create', function($page) {

    if($page->parent()->template() == 'series_visual') {
        $parent = $page->parent();
        if($page->date()) {
            $date = $page->date('Y-m-d'); // use format you use in date field of other pages
            try {
                $parent->update([
                'date'  => $date               
                ]);
            } catch(Exception $e) {
    
                echo $e->getMessage();
                
            }
        }

        
    }
    
});

If you update the date on page create like in this hook, it requires to set a default date in your blueprint (today) that is then used to update the parent page.

If the date is only selected by the user after the page is created, then you would have to use a panel page update hook. However, in that case you would have to be careful, because then the hook would also be triggered for older pages and you need an if statement that checks if the page is the one with the newest date. Let me know if you need more help.

This would be the update hook:

kirby()->hook('panel.page.update', function($page) {

    if($page->parent()->template() == 'blog') {
        $parent = $page->parent();
        $lastSibling = $parent->children()->sortBy('date', 'desc')->first();       
        $date = $lastSibling->date('Y-m-d'); // use format you use in date field of other pages
        try {
            $parent->update([
            'date'  => $date               
            ]);
        } catch(Exception $e) {

            echo $e->getMessage();
            
        }
        
    }
    
});

It just get’s the latest date of all siblings and uses that to update the parent. Probably the best way to go about this.


#7

Amazing. Thank you so much, this is all so clear and helpful.

I’ll implement this and see how it works. Thank you again!


#8

This works fantastically. Thank you again!