Add custom site permission to admin plugin (permission selection)

Hi all,
we need a custom site permission to make some pages only be visible for the group of students. This is configured in the pages frontmatter/header like so:

site.student: true

So far, everything works. But our pages will be mainly edited by using gravs admin plugin from not so “IT-based” people. And the plugin’s gui does know about our custom permission. And thus it does not list it in the available options/perms under “Page Access” (“Security” Tab). I already found out, that this list is populated from the plugins …/plugins/admin/permissions.yaml file. If I add the custom permission to that file, it gets actually listed as wanted in the gui. But editing plugin files directly seems to be bad practice, since my changes get lost when updating grav or the plugin. It there a way to extend or overwrite the permissions.yaml e.g. within /user - in a similar way as plugin main configurations can be overridden?

Thanks a lot in advance and best regards!

@Sven, Tip: try some backtracking in Admin plugin:

  • search for permissions.yaml, you’ll find function onRegisterPermissions.
  • then search for onRegisterPermissions and you’ll find a subscription for event PermissionsRegisterEvent::class

Duplicate the same logic in your own plugin…

  • Create a custom blank plugin using $ bin/plugin devtools new-plugin.
    Let’s assume we named it ‘myplugin’.
  • Copy ./plugins/admin/permissions.yaml to ./plugins/myplugin/
  • Edit permissions.yaml in your plugin to your liking
  • In ./plugins/myplugin/myplugin.php:
    • Add the following imports:
      use Grav\Events\PermissionsRegisterEvent;
      use Grav\Framework\Acl\PermissionsReader;
    • Add a listener to event PermissionsRegisterEvent::class:
      if ($this->isAdmin()) {
              // Put your main events here
              PermissionsRegisterEvent::class => ['onRegisterPermissions', 0],
    • Copy the callback from ./plugins/admin/admin.php into your own plugin:
      public function onRegisterPermissions(PermissionsRegisterEvent $event): void
          $actions = PermissionsReader::fromYaml("plugin://{$this->name}/permissions.yaml");
          $permissions = $event->permissions;

@pamtbaau: Thanks a lot for your fast and really helpful feedback!!

Even through the above solution worked out as promised, I finally tweaked it a bit. Reading permission as shown above from yaml and bulk-adding them using addActions method had the backside, that I had to re-define all permissions (already defined by admin plugins permissions.yaml again). But I ideally wanted my plugin to only add the new custom perms and leave everything else unchanged. This I finally got using the following adaption of the above:

    public function onRegisterPermissions(PermissionsRegisterEvent $event): void
        $permissions = $event->permissions;

        $customSitePermissions = $this->config()['site']['permissions'];

        foreach($customSitePermissions as $p) {
             $action = new Action("site.".$p["name"], ["label"=>$p["label"], "type"=>'access']);

…this way my custom actions are read into from my plugins config, e.g.:

enabled: true

    name: student
    label: 'Student'

…and I do not need to re-define all site permissions (login etc.).

May be there is an even more elegant solution of achieving the same, but so far that one worked out for me. :slight_smile: