Theme colour switcher

Show content on author's user profile, limited by viewing user's Group membership - Drupal 8 & 9

See also how to do this with a view of Group content

Someone contacted me asking for help with the following:

I am trying to look at the particular user profile, and below that profile contains a stream of content nodes which I will be able to see only content created by that particular user in group that I am a member of.

Example. If A is a user who created 2 Group’s and has added me to one of his group, When I logged in as a current user I should be able to see in my profile only the content which I have created. And when I view user A’s profile I should be able to see only those group content’s which I am a member of and which user A has created.

Group module structure

Creating Views of Group content or members can be complicated because of the structure of the Group module. A very important concept to understand is the relationship between Groups and their content. There are two types of Group content: users (enabled by default), and content entities such as nodes or Webforms.

Users and nodes that are added to Groups are not "moved" into those groups. Rather, a relationship is created between the Group and that user or piece of content. These relationships represent the user or content in the Group. They are themselves entities, as is everything in Drupal, and, like other entities, are fieldable, viewable, customizable, and have their own permissions, controlled in the Group permissions settings.

This structure can be represented visually like this:

Box with the label "Group" and an arrow pointing to a second box labelled "Relationship: fieldable, viewable, customizable". This second box has an arrow pointing to a third labelled "Entity: Drupal user or node belonging to group."

When creating Views of content or users in groups, you often need to add a long chain of relationships to the Group content relationship entities as well as the Group itself, and then the actual entity (the user or node) (or vice-versa, or some combination of the above). Often you want to show or hide content to users based on the Groups they're in, so the View needs to know about all of that.

Creating the View

So let's get on to the requirement my blog reader asked me about. They need to show content on each user's profile, which is authored by that user. When users view their own profile, they should see any content they've created. When viewing another user's profile, they should only see content which is in Groups they are a member of.

View base table

So where do we start? I incorrectly assumed the questioner wanted a view of nodes, rather than Group content (the entity that represents the content in the group). So that's how I built my view. I later wrote about how to do it with Group content.

Limit the view to the type(s) of content you want to show, if applicable. In this case since we're displaying the info on the user profile, we add a block display.

Tell the View which user's content to show

Next, we add the "content author" relationship (in the Content category). This is how we get information about the user into the View, and can limit it to content authored by the user whose profile we're viewing. We do that by adding a User ID contextual filter. You'll notice it automatically has the "author" relationship we just added. Under "When the filter value is not available" select "Provide default value", then under "Type", select "User ID from route context". The route context is the URL, and when viewing a user profile, their user ID is in the system URL. This is how the view knows which user to limit the display by.

Limit the view to content that belongs to a group

Next, we need to tell the View whether the content is in a Group. We add the "Group content for content" relationship (in the Group content category). Notice its description: "Relates to the group content entities that represent the Content." We are basically checking if our content has this relationship, and if it doesn't, it means it's not in a group and we don't want to show it.

In the relationship options, under "filter by plugin", you can limit the content by content type, although if you already did that when you created the view, this shouldn't be necessary. However, you do want to check "Require this relationship". This will exclude any content that does not have a Group content entity relationship, meaning it is not in a Group.

IMPORTANT: here is where you can get tripped up (I did) if you don't set the correct Group permissions. In the Group type(s) which hold the content, for each content type you want to show, you need to give the "Relation: View any entity relations" permission to any user role which should see this View. If not, they will see nothing. Because we are not simply showing content, we are including the Group content relationship, users have to be able to see those relationships for the View to show them the content. (If you as a site admin want to see it, give this permission to the Administrator role in "Advanced outsider permissions").

Limit the display to content in groups the viewing user is a member of

Next, we need to show only content which belongs to Group(s) the viewing user is a member of. Add the Group relationship in the Group content category. This will tell us about the Group(s) containing the content. It will automatically have the Group content relationship we previously added.

Next, we need to tell the View about which users are in those parent Groups. So we have to add a relationship to the Group content once again, but this time for users. We will add the Group content relationship, in the Group category. Note its description: "Relate to the group content entities. From there you can relate to the actual grouped entities."

In this relationship's settings, under "filter by plugin", select "Group membership". We want it to tell us only about which users are in the group.

We then add one more relationship, "User from group content", in the User category. This is what it means by relating to the actual grouped entities. We've jumped from the content, to the group content relationship, to the parent group, to the group user content, to the actual user entities. We'll use this to limit the view based on the Groups the current viewing user belongs to.

In this relationship's configuration, under "Relationships", select "Group content" (not Content group content, yes, it's confusing).

Next, we add another User ID contextual filter to filter the view based on the viewing user. In the filter settings, under "Relationships", select "Group content User". Again, we'll provide a default value, this time "User ID from logged in user".

Test the view

Now, you can test your view by entering the User IDs of different users in the "Preview with contextual filters" field, in the #/# format. The first number represents the first contextual filter - the user who is the author of the content and whose profile is being viewed - and the second is the ID of the user who is viewing the content. You can also add the block to user profile pages to test it out.

We can represent the entity relationships in the view we've created like this:

Chart with a series of boxes and arrows going between them from left to right, representing the entity relationships in this Drupal view. From left to right, the boxes are labelled: "Content: Drupal nodes"; "Group content relationship: represents the content in the group"; "Group: The group(s) the content has been added to"; "Group content: relationship between the parent group(s) and their content, limited to users"; "User: Drupal users".

Tags:

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.