Global filters - Run it before template loads

I think the idea of filters that are global could be a good idea.

Current way

To every query on the whole site, with some plugins, we need to exclude some pages, like revisions or modules.

foreach($page->children()->not('revisions')->not('modules') as $child) {
  echo $child->title();
}

The future way

Global filter

It can be set with a plugin.

global::$filters['unique-id'] = function($collection, $field, $value) {
  // Some filtering
  return $collection;
};

Because a global filter is used, not all children will be listed. Some are sorted out (revisions and modules in this case) without the need to exclude them in the template.

foreach($page->children() as $child) {
  echo $child->title();
}

What do you think? If you see pitfalls, which are they? If you have other ideas of how to solve this (probably growing) problem, share your ideas. :slight_smile:

Unfortunately this won’t work. Filtering out pages completely means that even Kirby doesn’t see them anymore. They won’t be listed in the Panel, the Modules/Revisions plugins wouldn’t be able to access them anymore etc.
What we could do (just thinking out loud) is to offer some kind of “filter template”:

collection::$filterTemplates['no-modules'] = function($collection) {
  return $collection->not('modules');
};

foreach($page->children()->filterByTemplate('no-modules') as $child) {
  echo $child->title();
}

It works kind of like the existing $collection->filter($callback) method except that it isn’t called on every item but instead in a more natural “just return some kind of new collection” way.

Wouldn’t it be easier in that case just to add a custom pages method which filters out all “not real” pages? And also the shortest in syntax if you choose a short name?

pages::$methods['real'] = function($pages) {
    return $pages->filterBy('intendedTemplate', 'not in', ['module', 'revision']);
};

Or even combine it as page method:

page::$methods['realChildren'] = function($page) {
    return $page->children()->filterBy('intendedTemplate', 'not in', ['module', 'revision']);
};
4 Likes

Good point! It can’t be applied to collections, but for pages it’s an awesome solution.

It’s not the final solution as it has some pitfalls, but it’s the best workaround I’ve seen. :slight_smile: I had to add it to https://github.com/jenstornell/kirby-secrets/wiki/Global-collection-filter