torf Posted March 31, 2023 Share Posted March 31, 2023 (edited) 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? Edited March 31, 2023 by torf added screenshots Link to comment Share on other sites More sharing options...
flydev Posted March 31, 2023 Share Posted March 31, 2023 I don't get the whole idea, but you might be able to achieve it using path-hooks to handle pagination. Look there if it can help: https://processwire.com/blog/posts/pw-3.0.173/#handling-pagination Link to comment Share on other sites More sharing options...
torf Posted March 31, 2023 Author Share Posted March 31, 2023 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 More sharing options...
flydev Posted March 31, 2023 Share Posted March 31, 2023 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 More sharing options...
flydev Posted March 31, 2023 Share Posted March 31, 2023 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); } }); } 2 Link to comment Share on other sites More sharing options...
Robin S Posted March 31, 2023 Share Posted March 31, 2023 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": Page List before: 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: 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: 2 Link to comment Share on other sites More sharing options...
torf Posted April 1, 2023 Author Share Posted April 1, 2023 @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 More sharing options...
Robin S Posted April 1, 2023 Share Posted April 1, 2023 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'); 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now