Views: Making a view show different content to different users based on role

greggles showed me how to make a view show different content to different users by role the other day, so I thought I'd write it down.

The goal: Displaying different nodes to administrators than I show to just authenticated users and that different than what anon users see. (In this case, I'll show pages to administrators, stories to authenticated users who are not administrators, and articles to anonymous users.)

The strategy: Create three different displays in the view, each of which is limited to a particular role, and each of which has its own filter. The administrator display has a filter that chooses pages, auth user one that chooses stories, etc.

The devil's details: The displays must be ordered by most restrictive to anonymous. The displays are apparently attempted in the order they're shown on the views edit screen. So we need the most restrictive (administrator) first. On that one only administrators will succeed. The next display has the authenticated users, etc.

I've attached a feature that demonstrates this. It provides a page, story, and article content type (provided in the feature) and a demonstration view. And some content in them. You'll need Features Module to try it out. But if you haven't tried out features yet, your life is draining away before your very eyes, so use this as a chance to try it out.

Thanks to all of you who pointed out on Twitter other ways to do this (with other tools):

  • Panels knows how to do this easily using the CTools context system.
  • Content Access and all related node access modules can do it by denying access to content (which we're not doing here; we're just affecting the display).

(And thanks Greggles for this great working solution.)

I don't think Context module knows how to change the primary content for a URL. It can do everything with the rest of the stuff on the page. Please correct me!

9 Comments

Great info!

I didn't realize views quite worked that way. I feel pretty confident in what I know about views and this is something new I've learned! Awesome!

There are ways the context module could solve this, but not quite as elegant as this.

Hmm, Randy, I want to add

Hmm, Randy, I want to add some comments to this quote of yours: "But if you haven't tried out features yet, your life is draining away before your very eyes, so use this as a chance to try it out."

We didn't actually speak with each other in the past, but I saw 2 presentations of you at DrupalCON CPH. You seemed to me a brilliant developer, but I can't understand why you are so happy with Features.

I have 2 problems:
a) if you want to update your Feature (because you did a change to a CT, view, ... whatever), you have to use drush to update your feature. I like drush, but I have colleagues who are not really willing to work with it. And the problem is: there's no UI action to update your Feature :-/ ...

b) if you change a setting on a CT like "Workflow settings: Multilingual support: Enabled, with translation" => this setting isn't picked up by Features. This settings DOES get picked up with the EXPORT function of a CT. So I'm missing the point why Features fails in this ...

So, as a conclusion: I do see advantages in Features, but I also see some disadvantages :-) ...

Features

Thanks for the nice compliment...

On features:

a) Updating from the GUI: You can update from the GUI, it's just awkward. You have to re-save the file. Drush can do it in place. I have to say that if I couldn't use drush to update I might not like features either. The UI cannot update the feature directly for the very reason that features exists: Drupal can (mostly) only update the database from the GUI. It can't update its own modules. In D7 there's a workaround for this for a little bit of relief (updates from the gui, but they require you to put in an ftp password.)

b) Content Type settings: I'm surprised. I think that's a bug or at least a missing feature and encourage you to take it up in the features issue queue, at least as a support request.

The biggest disadvantages to features to date, IMO, are 1) that it doesn't cover everything and 2) it doesn't cover ever database tables that are driven by numeric indexes instead of machine names. That leaves out a lot of things.

(I am a Features fanboy. You can see it in the presentation on features I sometimes give.

Hi Randy, I did post this in

Hi Randy,

I did post this in the issue queue of Features. Check this comment: http://drupal.org/node/792472#comment-3265134

So eventually, this issue got moved to Strongarm and solved by a patch in Strongarm. But I don't like the idea to install Strongarm, just to export my content type. Therefore, I replied with this comment: http://drupal.org/node/792472#comment-3502682

So ... it's not a bug, it's by design. But I don't like the idea to install 3 modules to keep track of DB changes. I want to keep my contrib modules as less as possible

strongarm is an essential part of features

I really don't understand why strongarm is a separate module. It's required for most "real" uses of features. So that's probably just one of those Drupal things :-)

I didn't installed Strongarm,

I didn't installed Strongarm, so that could be the reason why I ran into this bug?

Fixed by installing Strongarm

Fixed by installing Strongarm and CTools. But I still have my doubts using 3 contrib modules, to control Content Types ... :-)

How to get working with node_access

Great info, but unfortunately I can't get this working for my situation. I am trying to display different views based on whether or not the user has node access on a node on a node passed as a contextual filters argument. I tried changing the Access Control to Permission -> View published content and doing the access checking in the contextual filter with no luck. I also tried changing the Access Control to PHP with return node_access('update', node_load(arg(1))); with no luck either. It seems like this might only work if Access Control is set to Role.

Any ideas of how to get something like this to work without using context or panels?

simple and elegant

...and I would never have had any idea it could be done if I hadn't happened on this post. In my case I wanted to use parameterized links from the summary page view to get to 'detail' views - with all fields for auth users, some private fields removed for anon. users. Clone page, remove field(s), change role access - done. Thanks!