Working on a membership site built on Drupal and am aiming to hide the content of certain views pages on the site unless the user has a specific (membership) role.

However, setting view page access control hides the entire page — including title and its very existence (page disappears out of nav menus, etc.). My goal is to show the page is still there (almost as a teaser), allow anonymous users to click on it, but hide all of the body content (fields, etc.) if the user does not have the correct role. That body content should then be replaced by a message to subscribe to the membership.

Is that doable with views or another module ? If so, how? Any suggestions?

Note: I'm already using the Field Permissions module to hide some of the same fields on other pages using roles. As such, I can't apply that module for this use.

Edit: We're using views to generate 800+ pages automatically (tokenized paths, etc.). That adds a layer of complexity — any solution has to be able to scale easily.

3 Answers 3


Thanks to those who replied! I've found a solution using only the Views module that so far appears to do the trick in a light way. This combines elements of Geoff's response with some Views module trickery.

Views allows multiple views to have the same path, simply showing them according to display order (in the generic view admin, this would be horizontally left to right). Knowing that, the basic steps are:

  1. Clone the page display and rename it. I cloned the page display that already has the fields and page info in place, leaving url (and title settings) the same. Renamed the admin name to reflect that it is for "Non-Subscribers", or similar. All publicly visible information remains the same.
  2. Change the filters to ensure no content is displayed. There are a variety of options when doing this. I changed the filters on the new page to select "Content Type: Is not one of:" and selected all of the existing content types. Note that this particular selection will not add newly-created content types to the exclusion list automatically, so may not be ideal for all sites. Taxonomy might be another way to address this — whatever will ensure no content shows for your site at all times.
  3. Set "No Results" message. Under Advanced, I set up a No Results unfiltered text message that tells people that they have to subscribe to see this content, what they are missing, and how to subscribe. (I use unfiltered to put custom HTML in there, but unfiltered isn't required.)
  4. Set access permissions on both pages. I set my "full content" view page to only show for the subscriber role, as well as any other internal "admin" type roles that should see full content. I also set my new "non-subscribers" page to only show for roles that will never see full content by themselves (anonymous, authenticated, etc.). However, setting "non-subscribers" page to specific roles may be unnecessary, because of the display order. See below.
  5. Make sure display order is set correctly. The "full content" view page should be higher (i.e. farther left) in the display order than the "non-subscribers" view page.

Because views prioritizes based on display, it will show the "full content" view whenever it can (for views with the same url). Thus, in my scenario an admin role user (who is also ultimately an authenticated user) will see the full content view page because it is the higher priority. The lower priority page (with promo text) will not appear for that user at all. However, for users who don't have the role to access the "full content" view page, they will see the next display (at that url) they have access to: the "non-subscribers" view page.

Note: I haven't fully tested this long-term, yet. If anyone has comments on this approach (like where it might not work so well), feel free to add!

  • in the comments to my answer you said you were creating 600+ of these view pages, so are you going to clone each one individually? This answer doesn't seem to match the impression I got from the question and comments
    – Geoff
    Jul 3, 2015 at 21:16
  • @Geoff Sorry, I may not have been clear. A single set of views creates all of those 600+ pages — about three or four individual "view pages". So those three or four would need to be cloned, but that's it.
    – Rob
    Jul 3, 2015 at 23:57
  • that definitely did not come across in your comments - my first answer would have worked nicely given this information, but since your edit specifies it has to be easily scalable, it slants the direction of answers - and this answer definitely is not easily scalable. Im glad you got something to work, but in the future please be more clear and include as much info as you have in a question to avoid such confusions
    – Geoff
    Jul 4, 2015 at 3:37

For a quick and easy solution use panels.

  1. Use panels to display your view on the page for that specific user role.

  2. Inside the variant portion, swap the panels to a general text area for anonymous users.

very useful links:

Creating Different Versions of Same Page Variants (watch all the free videos)

Can one apply a panels layout to a view page?


it can be done without large modules such as Panels, in fact depending on how you do it, it can easily be done without any extra modules:

  • create a content type, 'Dummy Page' for our example - remove the body if you want (or use it to create a page header) and set everything else you want as you want the View Page to encompass

  • limit permission to only Admin for creating this content

  • create a node for the View, using the Title you would want the View to use


  • use a module such as Empty Page to create an empty page

The Empty Page module is a simple empty page solution. It provides an interface that assists in managing "empty" menu callbacks, mostly used for pages that only consist of blocks.

  • either case, set a path alias ('ViewPage' for this example)

  • build your View as a block - in the block UI limit it the roles you want, and limit it to the ViewPage page

  • if you go the Empty Page way, you can also create a block limited to that page with the title or header information.

  • you can also create a block on the same page (with either approach) set to only show for Anonymous that shows information about what the page is and that it is limited to authenticated users, maybe with a link to login (or a login block)


If you want to restrict users from accessing the content universally (not being able to manually input the url), then it's even simpler:

  • use Node Access to restrict access of the content types to the preferred roles

Nodeaccess is a Drupal access control module which provides view, edit and delete access to nodes. Users with the 'grant node permissions' permission will have a grant tab on node pages which allows them to grant access to that node by user or role. Administrators can set default access controls per content type, and also define which roles are available to grant permissions to on the node grants tab.

  • set up the View as normal, under Advanced, add a NO RESULTS BEHAVIOUR

Because Views honours the access control, all of the content will be hidden from an anonymous user, so the No Results Behaviour will be shown. However, if there is no content to show to an authenticated user, it will also be show. Therefore, you may want to include a block for the group of content that only shows for anonymous users instead, but the access control would remain the same. Because this acts on the nodes, they can be created however you want and it will still maintain functionality, whether there's 1 node or 10000


Based on the comments, you would need to override the display hook for the View.

function THEME(OR MODULE)_views_pre_render(&$view)
    global $user;
    if($view->name == 'VIEWS_MACHINE_NAME' && $user->uid == 0)
        $view->empty['area']->options['content'] = 'ENTER NO RESULTS HEADER TEXT HERE!';

This function runs after the view is ready to go, but before it is displayed. It checks if the current user is anonymous, and then removes all the results, and sets a NO RESULT BEHAVIOUR which displays as a header. You can also create the NO RESULTS BEHAVIOUR in the Views UI, but it would show for authenticated users if no results were found as well - this provides an anonymous only header.

Because you will have many Views and this hook runs on all Views, you need to adapt the IF statement depending on the naming convention you are using for the Views, for example:

if($user == 0)
  for($i = 0; $i < NUM_VIEWS; $i++)
    if($view->name == ('VIEWS_BASE_NAME' . $i))

This could similarly be done at the Field level using hook_views_field_data_alter, but you would still want the above to set the anonymous header information

  • One additional bit of info: we're using views to generate about 600+ pages dynamically (using dynamic paths, etc.). Would this solution require manually setting up all those pages?
    – Rob
    Jul 2, 2015 at 17:37
  • @Rob do you mean you are creating 600+ pages, each expected to contain a view with a teaser heading? If so, I don't think you'll find anything already made, you'll likely have to create something custom
    – Geoff
    Jul 2, 2015 at 17:50
  • Our views configuration is set up such that it generates the 600+ view pages automatically (assigning the right paths and content). In the scenario I'm aiming for, each of those pages would contain the title of the page, normal menu presence, and a teaser of sorts for a membership subscription. I was wondering if that would be custom, but thought it was worth asking.
    – Rob
    Jul 2, 2015 at 20:09
  • @Rob see my edit...
    – Geoff
    Jul 2, 2015 at 20:52
  • That's a good suggestion, but unfortunately not sure if it will work in our case. The nodes we are displaying in the views should be accessible to all users (content within those nodes are limited using Field Permissions). The value we're offering with the view pages isn't as much access to the nodes themselves, but that the view provides summary information of them in one place. That is, I want to limit access to this view of the nodes without limiting access to the nodes themselves.
    – Rob
    Jul 3, 2015 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.