52

I've found that there are times I have a node that simply contains content that will be displayed somewhere else, but shouldn't be viewed directly. That is, no one should ever go to node/1234, but the content in node 1234 should be displayed somewhere else. For example, I create an about page with tabbed content using views. So there are "About Me", "About Us" and "About Them" pages. All of these are displayed in a single page with tabs using Views. So I don't want people to get directly to the "About Us" node because then they wouldn't see the tabs for the other pages. At the same time, I don't want Google giving people a direct link to this node, I want to limit access so users can only get to it through the View (i.e., the tab).

So I need to restrict access to the node, remove it from the Drupal search results, and make sure Google doesn't pick up on it. Any suggestions?

  • I'm currently using drupal 6, but if it's different between 6 and 7, I think it would be useful to answer for both – Chaulky Mar 4 '11 at 5:21
  • If you are concerned about just a few nodes, why not add them to the robots.txt file to exclude them from Google searches? – Tangurena Mar 5 '11 at 17:10
  • This is a common misconception. robots.txt does not prevent search engines to index your site, it prevents search engines from crawling your site. If someone links to a page on your site, Google will follow the link and index the page if it wants to. If you want to prevent indexing you need to use the ROBOTS meta tag, i.e: <meta name="ROBOTS" value="NOINDEX"/> – René Jul 4 '12 at 8:22

13 Answers 13

28

This sounds to me like a good use case for the Panels module because you can create panels that will override node pages, and can set the context for the panel in a way should guarantee users see the page you want them to see it as well as access rules for panel pages if you need them. For further details, see this post on d.o.

  • this looks to do exactly what I want, and in a clean, simple way... even comes with a tutorial (nice link)!! – Chaulky Mar 25 '11 at 13:14
  • Isn't this an overkill compared to the Rabbit Hole module solution? Are there extra benefits to this that makes it the chosen answer? – Mario Awad Oct 29 '13 at 18:12
  • 1
    @MarioAwad Well, for one the Rabbit Hole module didn't even exist until over a year after I answered this question. At the time, Panels was the best solution, I still think it's the best solution if someone already has panels installed, if not then Rabbit Hole may be a better lightweight solution. – coderintherye Oct 30 '13 at 2:00
  • @nowarninglabel Sounds like a good tip. Thanks. Maybe you should add this clarification to the answer to make it better for future comers. Cheers. – Mario Awad Oct 30 '13 at 9:17
33

The Rabbit Hole module provides this feature.

Rabbit Hole is a module that adds the ability to control what should happen when an entity is being viewed at its own page.

Perhaps you have a content type that never should be displayed on its own page, like an image content type that's displayed in a carousel. Rabbit Hole can prevent this node from being accessible on its own page, through node/xxx.

  • There is now a Drupal 6 version. – mpdonadio Mar 27 '12 at 2:39
  • Excellent, a clean and simple solution. – jamix May 14 '13 at 13:13
  • 1
    Nice, this one is better than the panel module (for this use case) if you only want to prevent the direct access to a content_type node as it does only that! – Larzan Jan 23 '15 at 13:09
13

One option may be to never publish the node but have the consumer page ignore their publication status. So in your example, your "About" view may just ignore the publication status of your "About-xxx" nodes. Since the nodes are not published, un-authorized user cannot access them and they shouldn't be indexed by the search engine.

Another solution is to use an hook_nodeapi('view')/hook_node_view() implementation to issue a drupal_goto() or drupal_access_denied() when the node page is visited by an un-authorized user. Be aware that hook_nodeapi()/hook_node_view() are used in many cases and not only when viewing a node page.

hook_menu_alter() can also be used to alter the access callback of the node pages to deny access to the hidden nodes.

The best is probably not to base the filtering on hard-coded node ID but to use either a custom field on the node (using CCK/Field API or a custom table) or a list of hidden nodes stored in a variable.

  • @mongolity404 nice post, good information. Gave me ideas for a few other things. But why community wiki? – Chaulky Mar 25 '11 at 13:14
  • I made my answer community wiki in the case somebody feels like providing code sample for the options I suggested... – Pierre Buyle Jun 22 '11 at 20:06
7

For Drupal 7, the Rabbit Hole provides this feature.

Rabbit Hole is a module that adds the ability to control what should happen when en entity is being viewed at its own page.

This works by providing multiple options to control what should happen when the entity is being viewed at its own page. You have the ability to

  1. Deliver an access denied page.

  2. Deliver a page not found page.

  3. Issue a page redirect to any path or external url.

  4. Or simply display the entity (regular behavior).

How to :

Enable Rabbit Hole nodes submodule Then we will get config section associated with every form in Drupal CODE

6

Solved. First I tried Pierre Buyle answer, but if you unpublish a node, it can't be propper accessed and those nodes become useless. In my case I have parent and child nodes, only child nodes (for admin purposes) are the ones to be hidden and NOT be indexed by crawlers. What I did it with page manager made a url redirect (hiding these nodes to all users but admin) with a http response according to this tuturial by http://www.wunderkraut.com/1 and no-index nodes by crawlers is handleled by Node no-index module. This will work even if you don´t have paret-child node relationship. Link to tutorial:

4

In Drupal 7, it should also be possible to use hook_node_access(), this is a normal hook in D7 which can be implemented by all modules for all node types. Then you can deny access if the user is trying to view the node on his own node/nid.

You probably also need to implement hook_query_node_access_alter() and add a check there to hide the node in search results. This might even be enough on it's own and you don't need hook_node_access(). And it might even work in D6 because you can alter the query there too but it's much easier in D7 because of the query builder.

3

Simply set those node as 'unpublished', then, in the view add the filter 'node published: no'.

As seo note, is a good practice to create a custom content type for those 'ghost' nodes, and tell pathauto to give them specific urls (i use /dev/null/[title-raw] ;): even if the node is unpublished, it will have its own url alias, so in your example if you create first the ghost node 'about us', and then the view page 'about us', the second's url will be example.com/about-us-0 becose example.com/about-us has been taken from the ghost one (however, you can set the paths manually)

3

You could use any kind of node-access system and use views3. There you can't disable sql rewrite on the query settings and so you can disable the node access system on this view.

3

You can do by using the rules modules.
+ Create new rule with "Content is viewed" event.
+ Add a couple conditions for example: User has role(s) : anonymous, Path has URL alias : node/xyz (this is the node that you want to limit for anonymous user). Remember add "and" or "or" condition if it is needed.
+ Create action for redirect to another page or do something else. This is the sample code that i exported for you

{ "rules_limit_viewing_some_nodes" : {
  "LABEL" : "Limit viewing some nodes",
  "PLUGIN" : "reaction rule",
  "REQUIRES" : [ "rules", "path" ],
  "ON" : [ "node_view" ],
  "IF" : [
     { "user_has_role" : {
       "account" : [ "site:current-user" ],
       "roles" : { "value" : { "1" : "1" } }
      }
     },
     { "AND" : [] },
     { "path_has_alias" : { "source" : "node\/28" } }
   ],
   "DO" : [ { "redirect" : { "url" : "error" } } ]
 }
}
2

I think the easiest way to accomplish what you want is to use Page manager (Ctools), is really simple to use, all you have to do is to specify which node to redirect where (in this case, from one node to another)

2

Try out Content Access module.

allows you to manage permissions for content types by role and author. It allows you to specifiy custom view, edit and delete permissions for each content type. Optionally you can enable per content access settings, so you can customize the access for each content node.

  • Thank you @monymirza Re: Are you sure you want to rebuild the permissions on site content? Is it safe to do this, just after I've enabled the module??? – kine456 Mar 25 '13 at 5:34
  • just check "Access" tab on node – monymirza Mar 25 '13 at 5:45
  • Thanks @monymirza Got it!!! Does hiding a parent page automaticaly hides all its chindren? From anon users that is. – kine456 Mar 25 '13 at 6:15
2

The Content Access module will suite your requirement perfectly.

This module allows you to manage permissions for content types by role and author. It allows you to specifiy custom view, edit and delete permissions for each content type. Optionally you can enable per content access settings, so you can customize the access for each content node.

It also has a good documentation to help you get started.

2

If your "included content" nodes need to stay inaccessible, then consider blocking /node/* on the webserver "location = /node/*" level. Default deny access to all /nodes. Default allow access to nodes that received a path-auto path like /pages.

(The basic .htaccess password for subdirectories is a decent way of blocking accidental search indexing by external crawlers, too.)

You can never guarantee that a node will not become accessible via a contributed module that happens to be installed in the future, or one that you do not fully understand yet. (Search results, listings, default views, taxonomy category overview ...)

It is what nodes are for.

Is the privacy of your "included content" that important to you? If so, then ...

  1. Everything that has an URL will eventually be hit by google.

    Because search engines do not rely on link spiders alone. They also evaluate browser feedback etc. No robot.txt, or pathauto, globalredirect, rabbithole module will help you sleep in peace. If the node can be accessed, then it will be indexed. Maybe by your own browser/addons.

  2. Reconsider if "content that is to be included" should really be a node, if noone should access it as a page?

    If your "included content" would be stored inside a mini-panel/block/snippet/bean/..., then you are at a much lower risk of it ever being listed, or ever appear as a page with an automatic URL you don't know about, yet. (taxonomy overview pages, search, views ...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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