Jump to content

hide backend pagination for certain roles


torf
 Share

Recommended Posts

I have a long list of pages in my backend that uses pagination to be less confusing for my editors. Works great.

Now I have another role, where every user with a specific role can edit only his own page out of this list. Thanks to Page Edit Per User and Admin Restrict Branch that works great as well. Additionally I added a small part to my ready.php to hide all the other pages this user cannot edit:

if($this->user->hasRole('specificRole')){
	$ap = $user->editable_pages[0]->id; //there is always only one page
	$wire->addHookAfter('Page(id!='.$ap.'|1058)::listable', function($event) { //1058 is the id of the parent page
		$event->return = false;
	});
}

But my problem is that the pagination still works. So a user with editing rights on a page named "zzzzz" for instance has to klick on the last page of a set of empty pages to see his link. Is there any way I can turn of pagination just for this specific role? 

pw1.jpg

pw2.jpg

Edited by torf
added screenshots
Link to comment
Share on other sites

I do not think that this would help. It's not so much about handling the pagination. I'd need to turn it off for certain roles.

I added two Screenshots to the original post to make it more clear. There are 127 pages under "Zweigvereine", but the user is only allowed to see the one he's able to edit.  So he has 2 empty pages before his link appears on the third one. If I could turn of pagination for his role his page would be listed directly.

Link to comment
Share on other sites

Ah yes I see. I remember a discussion about it. I cant confirm it’s possible with a simple hook.
From mobile right now - but you can try to hook ProcessPageLister ___find, the goal is to remove unwanted pages from the JSON result.

Adrian might have an answer here.

Link to comment
Share on other sites

Test the solution below if it fit your needs :

if ($user->hasRole('testrole')) {
  // $ap = $user->editable_pages[0]->id; //there is always only one page
  // $wire->addHookBefore('Page(id!=' . $ap . '|1023)::listable', function ($event) { //1058 is the id of the parent page
  //   $event->return = false;
  // });
  // 👇
  // get the parent id of the user's editable page
  $parent_id = $user->editable_pages[0]->parent_id; //there is always only one page
  $this->addHookBefore('ProcessPageList::execute', function (HookEvent $event) {
    // hide root (/) page in list (optional)
    $event->object->showRootPage = false;
    // limit number of pages shown - that's the trick to avoid pagination in the lister
    $event->object->limit = 100; // you might need to adjust this value
  });
  $this->addHookAfter('ProcessPageList::execute', function (HookEvent $event) use ($parent_id) {
    // run only on ajax requests
    if ($this->config->ajax) {
      // manipulate the json returned
      $json = json_decode($event->return, true);
      // remove any pages that are not editable or addable and not the parent page
      foreach ($json['children'] as $key => $child) {
        $p = $this->pages->get($child['id']);
        if (!$p['editable'] && !$p['addable'] && $p['id'] !== $parent_id) {
          // remove the page from the json
          unset($json['children'][$key]);
        }
      }
      // set the json back to the event
      $json['children'] = array_values($json['children']);
      $event->return = json_encode($json);
    }
  });
}

Clipboard01.png.e0d373b4ba712e0e2d6ed454c4a67aa0.png

  • Like 2
Link to comment
Share on other sites

Another way you could do it...

In my example the parent template is "countries" and the child template is "country", and there are 195 child country pages.

Using the PageEditPerUser module the user is only allowed to edit country pages "Zambia" and "Zimbabwe":

image.png.4e053b40f39d4c0d42d743f072391a27.png

Page List before:

image.png.5c32e40b10c032b86cacda3d2dec7608.png

The problem being that lots of uneditable pages are included, with the two editable pages being at the end of the 4th pagination. I'm not using Admin Restrict Branch here so (presumably) that's why all the non-editable pages are listed, but that doesn't matter for the purposes of this example.

A solution is to add the following hook to /site/ready.php:

// Only for a particular role
if($user->hasRole('editor')) {
	$wire->addHookBefore('ProcessPageList::find', function(HookEvent $event) {
		$selector = $event->arguments(0);
		/* @var Page $page */
		$page = $event->arguments(1);
		$user = $event->wire()->user;
		// If the parent template is "countries", restrict the children list to only the pages that the user may edit
		if($page->template == 'countries') {
			$selector .= ", id=$user->editable_pages";
			$event->arguments(0, $selector);
		}
	});
}

That fixes it so that only the editable child pages are shown, but the incorrect child count and unnecessary pagination controls are still visible:

image.png.ce32b66caddc7957a6c1233f9b420dcd.png

So the simplest thing is just to hide those things with some custom admin CSS only for the relevant role (if you're not sure how to do that something like this should work, with a check first for the user role).

/* Adjust the parent template name to suit */
.PageListTemplate_countries > .PageListNumChildren  { display:none; }
.PageListTemplate_countries + .PageList > .uk-pagination { display:none; }
.PageListTemplate_countries + .PageList > .PageListActions { display:none; }

End result:

image.png.dcde3b4e934558225ec414ee1c150598.png

  • Like 2
Link to comment
Share on other sites

@flydev Wow. Thanks a lot. That absolutely does work and I'm positive that I'd never figured that out on myself. Thanks again.

@Robin S That's a cool approach too. Especially as it is very short. But I'm unsure about the CSS parts. Am I right that those CSS files need to be called directly inside admin.php rather than from site/ready.php ?

Link to comment
Share on other sites

2 hours ago, torf said:

But I'm unsure about the CSS parts. Am I right that those CSS files need to be called directly inside admin.php rather than from site/ready.php ?

There are a number of ways you could conditionally add CSS to the PW admin, but one simple way is to add this to /site/templates/admin.php (before the line that requires controller.php)

if($user->hasRole('editor')) $config->styles->add($config->urls->templates . 'styles/admin-custom.css');

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...