50

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?

2
  • 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
    Commented Mar 5, 2011 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é
    Commented Jul 4, 2012 at 8:22

12 Answers 12

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.

4
  • this looks to do exactly what I want, and in a clean, simple way... even comes with a tutorial (nice link)!!
    – Chaulky
    Commented Mar 25, 2011 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
    Commented Oct 29, 2013 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. Commented Oct 30, 2013 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
    Commented Oct 30, 2013 at 9:17
32

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.

3
  • There is now a Drupal 6 version.
    – mpdonadio
    Commented Mar 27, 2012 at 2:39
  • Excellent, a clean and simple solution.
    – jamix
    Commented May 14, 2013 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
    Commented Jan 23, 2015 at 13:09
12

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, they shouldn't be indexed by the search engine.

Another solution is to use hook_nodeapi('view')/hook_node_view() to issue a drupal_goto() or drupal_access_denied() when the node page is visited by an unauthorized users. 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.

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

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

0
5

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:

0
3

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.

2

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)

2

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.

2

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" } } ]
 }
}
1

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)

1

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.

1

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 and acknowledge you have read our privacy policy.

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