Jump to content

Allow Editors to only add or edit their pages


Recommended Posts

Hi, have a site where I set up a news category, then under that I have different regions where editors in those regions can add news stories.  I'm trying to figure out how to allow each editor to only add/edit stories in their region, and not allow editors from other regions to edit them.

example:

News  (template:news-category)

     Washington County (template:news-region)

               My First News Story for Washington County by Editor 1 (template:news-article)

     Jefferson County (template:news-region)

               A News Story by the jefferson county editor (template:news-article)

      Taylor County (template:news-region)

              A news story by a Taylor county editor (template:news-article)

 

I really don't want to create 3 different news-region templates along with 3 different news-article variations, and 3 different types of Editor roles.

Is there a way / module that will let me say, "jane which is an editor can only add and edit to Washington County" and "bill which is an editor can only add or edit to Taylor County", etc?  Also, it would be nice to allow the "home office" editor to add/delete/modify contents created by the other editors, a "Super Editor" if you will.

 

Thanks mucho!

  • Like 1
Link to comment
Share on other sites

You can achieve this with hooks to Page::addable and Page::editable.

1. Define access controls for the news-region and news-article templates so that users with the news-editor role can add children under news-region pages and they can edit and create news-article pages.

2021-07-08_101832.thumb.png.4588eef07a0f813974f38da3d5018d47.png

2021-07-08_102057.thumb.png.ae6c8f313980787a317569d1d6a4e4ad.png

2. Create a news_regions Page Reference field which allows pages with template news-region. Best to make it a "multiple" AsmSelect field so it covers the potential case that a user needs to add/edit within multiple regions. Add this field to the user template.

3. Edit the news-editor users and set the regions they are allowed to add/edit within.

2021-07-08_102008.thumb.png.3e04d14731be733f184304edbe989d3b.png

4. In /site/ready.php:

$wire->addHookAfter('Page::addable', function(HookEvent $event) {
	/** @var Page $page */
	$page = $event->object;
	$user = $event->wire()->user;
	// Return early if PW has already determined that the user is not allowed to add
	if(!$event->return) return;
	if($user->hasRole('news-editor') && $page->template == 'news-region') {
		// Addability depends on if the news_regions Page Reference field has the page
		$event->return = $user->news_regions->has($page);
	}
});

$wire->addHookAfter('Page::editable', function(HookEvent $event) {
	/** @var Page $page */
	$page = $event->object;
	$user = $event->wire()->user;
	// Return early if PW has already determined that the user is not allowed to edit
	if(!$event->return) return;
	if($user->hasRole('news-editor') && $page->template == 'news-article') {
		// Editability depends on if the news_regions Page Reference field has the parent page
		$event->return = $user->news_regions->has($page->parent);
	}
});

The result for user "ringo":

ringo.gif.27c8515ad55df18878c806f827fecd0f.gif

 

7 hours ago, John W. said:

Also, it would be nice to allow the "home office" editor to add/delete/modify contents created by the other editors, a "Super Editor" if you will.

You could add all the regions to that user's page, but personally I would create a different news-supereditor role and just not make them subject to the restrictions in the hooks.

  • Like 12
  • Thanks 2
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.
  • Similar Content

    • By SwimToWin
      BACKGROUND
      SEO matters and so hiding pages behind a "section" is not necessarily good - example:
      Current practice is to show the pages "Foo, Bar, Baz" in a section. https://www.example.com/resources/foo https://www.example.com/resources/bar https://www.example.com/resources/baz For SEO reasons, it's better to show the page at root level like so: https://www.example.com/foo https://www.example.com/bar https://www.example.com/baz PROBLEM: LACK OF ORGANIZATION WHEN ALL PAGES ARE PUBLISHED AT ROOT LEVEL
      This design is fully possible today. However, the root folder becomes disorganized when all pages are published in the root - and the pages tree structure is not of much use when all pages are published in the root.
      SOLUTION: VIRTUAL PAGES TO THE RESCUE
      As a publisher, when publishing many pages that have a root level url, I want to organize my pages below a Virtual Page (that doesn't have a url), so that pages are organized in a Pages Tree Structure (using "Virtual Pages").
      What is a "Virtual Page"?
      Virtual Page can never have a name (Admin -> Page -> Settings -> Name). The Name field is simply blank The Name field is never used in the url for child pages. Virtual Page is a container used to organize other pages. Virtual Page is never shown in the front-end. Virtual Page is shown in the Editing interface only. Virtual Page might have a Template - but the template can only be used in the Admin interface. Virtual Page might have fields (Title, Summary, Text etc.) - but the contents cannot be shown online.
    • By Peter Troeger
      Hello Community 🙂
      Has anyone ever tried having multiple elements on one page that get their info with $pages->find('selector, limit=n') and tried using pagination on one of these elements without effecting the other?
      I have a slider on a page where I display content with pagination. But when I go to page two, the slider content also goes to page two, which I don't want it to do 🙂
      Any tips are greatly appreciated!
      Thanks!
      -Peter
    • By Liam88
      Hi All,
      New user over at Processwire and have been rebuilding my site based on this CMS.
      I have been able to find so many answers through Google but I'm a little stuck on this one.
      I have my services page -> services categories -> category children.
      An example of those would be - domain -> services -> ppc -> management
      I also have a set of tags which have different names - services-tag -> grow-your-traffic
      Under these tags I would have multiple links to pages such as ppc, seo, social media and so on.
      A second example would be - services-tag -> convert-your-traffic
      Under here i would have multiple links to pages such as CRO
      Now the set of tags are not visible on-site as they are only created to give overview content to the main services categories.
      Using the categories and the tags I am looking to produce a layout such as (i have also attached an image as an example:
      Tag_1 headline
      Pull all services categories linking to Tag_1
      Tag_1 snippet
      Tag_2 headline
      Pull all services categories linking to Tag_2
      Tag_2 snippet
      So far I have this snippet which is pulling in the tag content but unable to get the posts to show under each of the tags. 
      If i change the if and statement to "tags" instead of "tag" then all posts show under all tags. Where as i want it to show only the posts which are linked to that tag.
      <?php namespace ProcessWire; $tags = $pages->get("/categories-services/")->children(); // Gets the tags $posts = $pages->get("/services/")->children(); // Gets the services categories $link = $tags->ref_6; // Gets the tags and services categories link - under here you have pages_id (services cat id) and data (tags id) // Tag header and summary foreach($tags as $tag) { // This breaks down the tags into sections echo '<section id="services"> <div class="container"> <div class="row"> <h2 class="heading-1"><span>'. $tag->headline.'</span></h2> <p class="mb-5">'. $tag->summary.'</p> </div> <div class="row justify-content-around services">'; // Main services categories that link to the above tags if ($posts->id === $link->pages_id && $tag->id === $link->data){ foreach($posts as $service){ // This pulls in the services categories under the tag header. echo '<div class="card flex-card" id=""> <div class="card-img"> <a href="/'. $service->name.'" title="'. $service->name .'"> <img class="card-img-top" src="../assets/files/'. $service->id.'/'. $service->img_1.'" alt="'. $service->img_1.'" title="'. $service->img_1.'"></a> </div> <div class="card-body"> <h3 class="card-title">'. $service->headline.'</h3> <p class="card-text">'. $service->summary .'</p> <div class="card-action"> <a href="" title="'. $service->name .'" role="link" class="link">View service<span></span></a> </div> </div> </div> '; } } // Grey snippet text echo '</div> </div> </section> <div class="snip-2 light-grey"> <div class="container"> <div class="row text-center">'. $tag->get('grey') .'</div> </div> </div>'; } ?> I appreciate this is a long post but i'm trying to be clear as I appreciate everyone's time.
      Any insight into where I am going wrong is greatly appreciated.
      Liam



    • By Peter Knight
      Hi guys
      Is it possible to have a PW site display content from another PW site?
      I've been reading about ProcessWire's Multi-site options and I don't think either is a way forward for me.
      Both PW sites are separate installs with separate databases but crucially they are on the same VPS. So I'm hoping that's a good thing.
      Basically, Site A has approx 100 reviews consisting of these fields
      Reviewer name Review Date Instead of setting up the fields onto Site B and duplicating work and creating 100 pages, I want to *somehow* get site B to use a selector to fetch the necessary content from Site A.
      In future, if I need to update the reviews, I can goto the 'source' Site A to do this.
       
    • By celfred
      Hello,
      I'm facing an issue trying to restrict access to a field so front-end edition is possible in an easy manner for the user. Let me explain :
      I have a field 'group' which is a Page list of group names. I want the user to be able to front-end edit a 'player' page in which this group field appears. I'd like the user to have a list of groups limited to his or her own groups (so he or she doesn't see all groups created by other users). In the back-end, I use this selector string : template=group, created_users_id=[user], sort=title This works great ! BUT here's my issue :
      If I back-end edit a 'player' page as 'Admin', the 'group' is empty (since admin is not the created-users-id and the group field is then empty... In other words, I must choose between all groups shown to all users (which may be scary for a user having only 2 or 3 groups whena list of 60 shows up) OR having a correct list for the front-end user, but empty for the back-end 'admin'.
      Can anyone think of another way I could get the expected result ? I have a feeling the simplest way would be to have a "Ignore for superusers" checkbox next to the 'selector string'. 
      Thanks !
×
×
  • Create New...