Struggling with Blueprint: Custom header data form in Admin area

Hi All,
I’m struggling with some header data, that I want to save for a custom content type - and I’m not sure where the problem lies.

Error message on Admin page, after attempting to save: Failed to save entry: Bad form data for field collection 'site': string used instead of an array

Context:
Based on the Learn Grav cookbook recipes I’m establishing a private area on my site. I’ve created a group “Private”,

Private:
  access:
    site:
      private: true
  readableName: Private
  description: 'Private User'
  enabled: true

Pages, that are exclusively for this group, then have this in their frontmatter - and it works fine.

access:
    site.private: true

Reproducing the problem
Now, for each page created I want to make sure, the editors can choose in the backend, whether the page is Private or not.

I’ve created a blueprint for the content type:

extends@: default

form:
  fields:
    tabs:
      fields:

        newtab:                        # Create new tab
          type: tab
          title: Custom Settings        
          ordering@: content    # attaching it right to the content tab
          fields:
            privacy:
              type: section
              title: Privacy Settings
              underline: true

              fields:
                header.access.site.private:
                  type: toggle
                  toggleable: true
                  label: Test - access.site.private
                  highlight: 1
                  options:
                    1: PLUGIN_ADMIN.YES
                    0: PLUGIN_ADMIN.NO
                  validate:
                    type: bool

This results in a form, that works fine.

Ticking the box results in this frontmatter entry, which seems fine for me.

---
title: 'Privacy Test 2'
access:
    site:
        private: true
---

Now - anytime I try to save the file again, edits or not, I get shown the error code above and the file is not saved again.

Any pointers? Where is my mistake? What am I missing? (Also, is this a Admin Plugin issue? Where would be the right place to ask?)

Super grateful for any help - thanks a lot!!!

@Flop, Unfortunately I can reproduce the behaviour. I would suggest to add an issue at the repo of Admin

1 Like

Done, here is the issue on github for those interested to follow: Header data causes error on saving · Issue #2334 · getgrav/grav-plugin-admin · GitHub

Thanks for the pointer

@Flop, this happened because header.access: already exist in the security tab (Page Access - which is quite new) with validate: type: array
for the test purpose you must remove a field (unset@: true) first.
so, @anon76427325 no :beetle: here.

1 Like

@b.da, You might be right. My suggestion to create an issue is not because I’m saying it is a bug. I just had no clue where the problem might stem from and suggested to create an issue:

  • because the team might help,
  • the team might improve the error message shown,
  • it might be a bug after all,
  • etc.

To increase the value of your solution for the benefit of the community, would you mind adding how one can unset the header.access field in the security tab?

Thanks for the pointers, certainly something to play around with.
I’ve added the following to my blueprint, but it still throws the same error.

        security:  # existing security tab
          type: tab
          title: PLUGIN_ADMIN.SECURITY
          fields:
            header.access:
              unset@: true

Any suggestions how to properly unset the header.access value?
Or - why does a sub-arrary field (?) access.site.private, that was previously undefined an error?
In that case, wouldn’t it make more sense to use a custom header entry to organise access, e.g. header.private_site : true or similar? Would that work?
Thanks already!

@Flop ok, working solution, but I haven’t figured out yet how to make it safe when updating the admin plugin. The idea is to add an option site.private to field type acl_picker (with data_type: access)

  1. modify permissions.yaml file in admin plugin folder (user/plugins/admin/permissions.yaml) by adding actions: private
actions:
  site:
    label: PLUGIN_ADMIN.ACCESS_SITE
    actions:
      login:
        label: PLUGIN_ADMIN.ACCESS_SITE_LOGIN
      private:
        label: Private Area

this will add to the Page Access field in security tab what you are looking for.

The second part (about @unset)

i won’t dig in that direction, but @unset not working as i expected
but again for the test purpose you can (i did that + @unset and thought it worked):

  1. copy security.yaml
  2. create folder partials in blueprints ( <yourtheme/blueprints/partials> ) and paste the file there
  3. delete header.access

Alright, more to fiddle with /// thanks so much for trying and putting forward possible solutions.

Re unset@:
I’ve only managed to make it NOT throw out error messages by unsetting@ the entire Security tab.

form:
  fields:
    tabs:
      fields:

        security:  # existing security tab
          type: tab
          title: PLUGIN_ADMIN.SECURITY
          fields:
          unset@: true # TODO Do I really need to unset the whole thing?

I don’t like that solution though, so I will take some of yours and try around a little. thanks!

I wanted to find a solution that didn’t remove built-in functionality, finally got it to working :sweat_smile: So, we are registering a new permission in our theme.

1. <YourTheme>.php
<?php
namespace Grav\Theme;
use Grav\Common\Grav;
use Grav\Common\Theme;
use Grav\Events\PermissionsRegisterEvent;
use Grav\Framework\Acl\PermissionsReader;
class <YourTheme> extends Theme
{
    public static function getSubscribedEvents()
    {
        return [
            PermissionsRegisterEvent::class => ['onRegisterPermissions', 100],
        ];
    }

    public function onRegisterPermissions(PermissionsRegisterEvent $event): void
    {
        $permissions = $event->permissions;
        $actions = PermissionsReader::fromYaml("theme://permissions.yaml");
        $permissions->addActions($actions);
    }
}
2. add permissions.yaml (in theme root folder)
actions:
  site:
    label: PLUGIN_ADMIN.ACCESS_SITE
    actions:
      login:
        label: PLUGIN_ADMIN.ACCESS_SITE_LOGIN
      private:
        label: Private Area
types:
  default:
    type: access

@Flop, if you still want to use @unset

  • create folder partials in your theme blueprints (<YourTheme>/blueprints/partials)
  • create security.yaml file
  • add the following code
extends@:
  type: partials/security
  context: blueprints://pages

form:
  fields:
    _site:
      fields:
        header.access:
          unset@: true

In any case, i would prefer to register the permission first, as it allows you to manage the user’s permissions through admin panel.