Permissions on subpage only

I’m hoping someone can help me with permissions. I have a site with a structure like

Root Page (root template)
	-Parent Page (parent template)
		- Subpage1 (sub1 template)
		- Subpage2 (sub1 template)
	-Parent Page (parent template)
		- Subpage3 (sub2 template)
		- Subpage4 (sub1 template)
Root Page (root template)
	-Parent Page (parent template)
		- Subpage5 (sub3 template)
Root Page (root template)	
	-Parent Page (parent template)
		- Subpage6 (sub2 template)
		- Subpage7 (sub4 template)

I am trying to set up permissions to allow a user access to only Subpage3 and not allow them to see other pages in the panel.

What I have tried is:

<?php
// site/roles/editor.php
return [
  'name'        => 'Editor',
  'default'     => false,
  'permissions' => [
    '*'            => true,
    'panel.site.*' => true,
    'panel.user.*' => false,
    'panel.page.*' => false,

'panel.page.read' => function() {
  return $this->target()->page()->template() == 'sub3';
}
]
];
?>

But that does not work. It does not show any page.

Using User permissions templates and their child as a guide I tried:

'panel.page.read' => function() {
  return $this->target()->page()->template() == 'root' || 
$this->target()->page()->template() == 'parent' ||
$this->target()->page()->template() == 'sub3';

Which does allow access to sub3 but also allows all root, and parent pages to be shown and edited. Is there a way to show only Subpage3 in the panel?

Root Page (root template)
	-Parent Page (parent template)
		- Subpage3 (sub2 template)

And allow only the contents of Subpage3 to be edited? I am new to Kirby but am finding Kirby to be a very flexible I hope there is some solution.

This is just an untested guess, but maybe it works …

'panel.page.read' => function() {
  return $this->target()->page()->template() == 'sub3' || $this->target()->page()->index()->filter(function($child){
    return $child->template() == 'sub3';
  });
}
1 Like

To allow updating of subpages, the parent pages must at least be readable, otherwise there is no way to access them. You can then limit editing to only the “sub3” template:

<?php
// site/roles/editor.php
return [
  'name'        => 'Editor',
  'default'     => false,
  'permissions' => [
    '*'            => true,
    'panel.site.*' => true,
    'panel.user.*' => false,
    'panel.page.*' => false,

    'panel.page.read' => function() {
      return $this->target()->page()->template() == 'root' ||
        $this->target()->page()->template() == 'parent' ||
        $this->target()->page()->template() == 'sub3';
    },
    'panel.page.update' => function() {
      return $this->target()->page()->template() == 'sub3';
    }
  ]
];

You can try to narrow the read function down a bit:

<?php
// site/roles/editor.php
return [
  'name'        => 'Editor',
  'default'     => false,
  'permissions' => [
    '*'            => true,
    'panel.site.*' => true,
    'panel.user.*' => false,
    'panel.page.*' => false,

    'panel.page.read' => function() {
      if($this->target()->page()->template() == 'sub3' || (($this->target()->page()->template() == 'root' || $this->target()->page('parent')) && $this->target()->page()->index()->filterBy('template', 'sub3')->count() > 0)) {
        return true;
      }
    },
    'panel.page.update' => function() {
      return $this->target()->page()->template() == 'sub3';
    }
  ]
];


This should grant read access to parent pages only if they actually contain a descendent with template sub3, but not to ancestors that contain only children with templates of types other than sub3.

1 Like

texnixe, this worked perfectly.

Thanks for the awesome support.