In some contexts, site()->index(true) returns no drafts

Interesting observation, and I’m wondering what might be the reason:

When calling site()->index(true) from within a Site Method, it returns all pages including drafts, as expected; however, when calling the same from within a page.update:after hook, it only returns listed pages, despite the true boolean.

Would a kind soul be able to shed some light on why site()->index(true) behaves different when it is called within a hook? …and: How can I get an index of all pages including drafts from within such hook? (I tried kirby()->site()->index(true) as well - same result, drafts missing). Thank you! :pray:

I can’t reproduce the issue, following code snippet works for me :thinking:

return [
    'debug' => true,
    'hooks' => [
        'page.update:after' => function ($newPage, $oldPage) {
            var_dump(site()->index(true)); // i can see all pages that included drafts

Thank you for your reply! I can confirm that your snippet works fine in a fresh Starterkit.

However, in my project this barebone hook, too, returns only listed pages while using var_dump(site()->index(true)) elsewhere (e.g. calling that in a template) keeps returning everything incl. drafts :worried:

…there must be something in my setup that affects how ->index(true) behaves.

I tried comparing var_dump(site()) in both contexts (the hook and a template) to see whether there is a difference in the site object returned. There are slight differences (like the homePage property being null in the hook context etc.), but these are also present when I make the same comparison in that fresh Starterkit where everything works; i.e. these all seem to be as they should and are not the cause of my issue.

I’ll keep investigating and report back if I ever find out what causes this. If you have any pointers as to where to look (something in a site configuration that might affect how site()->index() or more specifically the $drafts = true boolean behaves) that would of course be most welcome, but I currently consider this not a Kirby issue, but something messed up from elsewhere. I “just” need to figure out where :male_detective:

Ok, I found the culprit, but not the true reason (that’s beyond my technical understanding of Kirby’s inner workings):

After meticulously debugging my project, it turned out that calling site()->index(true) from within a page.update:after hook would not contain drafts for one particular page type only. I then went through the entire blueprint (by removing small portions, one at a time) and eventually learned that this field caused the odd behaviour:

  type: tags
  label: Tags
  options: query
  query: site.index.pluck("tags", ",", true)

When the page.update:after hook is triggered after updating a page where above field is present in the blueprint, site()->index(true) would only contain listed pages. Triggering the same hook from any page whose blueprint does not include that field, drafts are included in the collection returned. As soon as I remove this field, site()->index(true) returns the complete index of the site, including drafts, also for the blueprint in question.

I was able to narrow it down even further: the problem seems to stem from the query: site.index.pluck("tags", ",", true) – as soon as I replace that with any query that does not involve index (e.g. query: site.children.pluck("tags", ",", true), which is of course nonsensical, but just for proof-of-concept), the index call from within that hook works as expected.

Did I just encounter a very odd bug here, @ahmetbora ? To summarize: it appears that the collection returned by site()->index(true) does not include drafts as specified if called by a page.update:after hook for a page whose blueprint includes an option query that makes use of index.

Could you create an issue on GitHub please, that sounds like something nasty…

Sure, I’ll be happy to do that!

…just wanted to first give it a moment for somebody to chime in here and point out that I’m overlooking something completely obvious :upside_down_face:

1 Like