Changing status from draft to listed in panel, does not seem to update json file in a hook?

I’m having some issues when writing a json file (for an article search index) from a hook but only when changing article status from draft to listed.

The ‘article’ is removed from the json file if I change from listed to draft (as expected) but it is not added when changing from back from draft to listed - which is what I would expect?

But if I edit the article and then save, it re-appears in the json file.
(The update hook - ‘page.update:after’ etc not shown in the code below for simplicity.)

What am I missing or is it a bug?

Summary of the hook below with file writing for ‘page.changeStatus:after’ hook

'hooks' => [
    'page.changeStatus:after' => function () {
      $search = site()->index()->filterBy('template','*=','article');

      foreach($search as $item) {!
          $search_results[] = [
              // Using relative paths not absolute
              'id'  => url::path($item->url()),
              'title' => $item->title()->value(),
              #'status' => $item->status()->value(),
          ];
      }
      // Write items to the file
      $json_data = json_encode($search_results, JSON_UNESCAPED_SLASHES);
      $fileoutput = kirby()->roots()->index() . '/' . 'search.json';
      f::write($fileoutput, $json_data);
  }
]

Hm, I can’t reproduce this in a 3.3.5 Starterkit. It works both ways. I first converted all listed pages to draft and then to listed again. What Kirby version are you using?

Sonja, firstly thanks very much for taking the time to have a look at my post. It is much appreciated, even more so in these trying times! I am on Kirby 3.3.5.

I had a look at the starterkit and of course it did work as you suggested and I then compared the starterkit with mine and the only relevant difference I could see was that the starterkit was using the default num: and I was using num: '{{ page.date.toDate("Ymd") }}'

So I then altered the starterkit with a date for albums and set the template to use

num: '{{ page.date.toDate("Ymd") }}'

The result is the same problem that I was experiencing - it does not work going from Draft to Published. The newly status changed item does not appear in the json file.

If I remove num: '{{ page.date.toDate("Ymd") }}' (e.g. back to default numbering) it works again. That is to say moving from Draft to Published, does add the entry to the json file.

So just to confirm this is what was happening, I altered mine to use the default numbering and then it would work as well.


So it would seem like a problem with num: using date at least with:
num: '{{ page.date.toDate("Ymd") }}'

Any ideas on how to fix it or am I doing something wrong?

Hm, it looks as if we have issues with setting num to a date like this. I will test again myself and check the issues.

Thanks Sonja, I look forward to the result of your investigations. Please let me know if I can be of any more help.

Ok, I could reproduce the issue with the date setting, but I found an error in your code (undeclared $search_results variable), and also a way to prevent the issue when setting num: '{{ page.date.toDate("Ymd") }}', by calling site() on $newPage.

       'page.changeStatus:after' => function ($newPage, $oldPage) {
          $search = $newPage->site()->index()->filterBy('template', '*=', 'article');
          $search_results = [];
          foreach($search as $item) {!
              $search_results[] = [
                  // Using relative paths not absolute
                  'id'  => Url::path($item->url()),
                  'title' => $item->title()->value(),
                  #'status' => $item->status()->value(),
              ];
          }
          // Write items to the file
          $json_data = json_encode($search_results, JSON_UNESCAPED_SLASHES);
          $fileoutput = kirby()->roots()->index() . '/' . 'search.json';
          F::write($fileoutput, $json_data);
      },

I’m not sure if this is a bug or intended behavior, but in any case it is inconsistent:

1 Like

Thanks Sonja, that works for me and I agree it is inconistant and should probably be changed unless there is a good reason not to.

Sonja, I seem to be having the same problems with 3.4.0 and status (draft to published) change it seems to trigger the change (if I throw an exception) but when i don;t trow an exception the file is not updated. I ran through the hooks update and added the changes and it now passes.

config.php

'hooks' => [
   'page.changeStatus:after' => function ($newPage, $oldPage) {
      require_once 'quotes_search.php';
      update_search_json($newPage, $oldPage);
      #throw new Exception('Change Status');
    }....
  ]

quotes_search.php

function update_search_json($newPage, $oldPage) {
  # Search creates search.json file in root- index search based on included templates or the whole site
  $includeSearchTemplates = option('search.includeSearchTemplates', null);

  #if includeSearchTemplates - include pages, all all listed pages
  if (!$newPage) {    
    (!empty($includeSearchTemplates) ?  
  $search = $newPage->site()->index()->filterBy('template','in',$includeSearchTemplates): $search = site()->index());
  } else {
    (!empty($includeSearchTemplates) ?  
  $search = site()->index()->filterBy('template','in',$includeSearchTemplates): $search = site()->index());
  }
  
Any ideas?
  foreach($search as $item) {
    $search_results[] = [
      // Using relative paths not absolute
      'id'  => url::path($item->url()),
      'title' => $item->title()->value(),
      #'text'  => $item->text()->value(),
      'parent'  => ucfirst($item->uid()),
      'date' => $item->date('l, jS F Y'),
      'datetime' => $item->date('Y-m-d'),
      #'img'  => url::path($item->image($item->cover()->image())->resize(600, null, 70)->url()),
      #'caption' => $item->image($item->cover()->image())->caption()->value(),
      'tags'  => str_replace(',' , ', ',$item->tags() )
    ];
  }
      
  // Write items to the file
  $json_data = json_encode($search_results, JSON_UNESCAPED_SLASHES);
  $fileoutput = kirby()->roots()->index() . '/' . 'search.json';
  f::write($fileoutput, $json_data);
}

Any ideas?

Just to confrim this I also tested this out using the starterkit with a date for albums and set the template to use:

num: '{{ page.date.toDate("Ymd") }}'

The result is the same problem that I was experiencing - it does not work going from Draft to Published. The newly status changed item does not appear in the json file.

If I remove num: '{{ page.date.toDate("Ymd") }}' (e.g. back to default numbering) it works again. That is to say moving from Draft to Published, does add the entry to the json file.

So just to confirm this is what was happening, I altered mine to use the default numbering and then it would work as well.

So it would seem like a problem with num: using date at least with:
num: '{{ page.date.toDate("Ymd") }}'

Seems like this has not been fixed, any idea how to solve this?

Bump - anyone idea how to solve this?

Is the hook called at all in this case?

I wonder if it is related to this issue: https://github.com/getkirby/kirby/issues/2555

Thanks pixelijn, it does seem very similar, I’ll add a note and a link to here.

Yes, it does actually seem to fire (if I throw an exception), but nothing seems to happen, or at least no new data is written to the files - which I guess could be right if the information is blank.