I'm trying to hide a specific set of pages from anonymous users and I would like to return a 404 for them. To be more precise, the set of pages I'm trying to hide are ECK entity pages (info blocks I guess), taxonomy term pages and a few node types. But I would like to still have them visible in the pages they are part of.

To be more clear, let me give you an example : I would like to have itinerary/gallery/1 hidden from anonymous users, but I would still like for the gallery itself to be visible in the blog pages it's embedded in.

I tried using the Rabbit Hole module and it works great for taxonomy terms and the node types, but not for the ECK stuff. I tried extending the module but it doesn't seem possible the way Rabbit Hole works unless I create an extension for each of them.

I also tried pulling a hook from hook_entity_view() but the problem with it is that it also triggers when the elements are loaded in the page, not just on their own pages. Does anyone have any idea how to do this?


You could use the Rules module to get this to work, by using the "Drupal is initializing" event. That will ensure that the rule gets triggered BEFORE the actual content is shown.

The links that you want to "intercept", should be formatted in some type of regular expression, which you then use as your Rules Condition. So that you have a rule that corresponds to "before showing the actual content of something that matches a specific path ...". After you get that part to work, your Rules Action should specify the actual redirect to be performed.

Sample rule

Refer to the "Option 1" part of my answer to the question about "How to restrict access to a node via node/12 and allow access via a path like content/sometitle?", which contains this rule in export format:

{ "rules_check_url" : {
    "LABEL" : "Disallow node/* access",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
    "DO" : [
      { "drupal_message" : {
          "message" : "Sorry, URLs like [site:current-page:url] are not allowed around here ...",
          "type" : "error"
      { "redirect" : { "url" : "no_access" } }

Here are some suggested tunings of the above sample, to make it work for your case also:

  • machine name and label.
  • replace the node/* by your path(s) (in the regular expression).
  • possibly you may want to add an extra Rules Condition to only perform the Rules Actions for selected user roles (eg: only for user who are not administrators).
  • replace the path in the action part of the rule by your target path, and check if you do want some type of error message to be shown (if not remove that part of the action).
  • @SorinLascu merci for the feedback, and accept/+1. May I say "what else did you expect?" Apr 3 '18 at 14:42
  • Well one small problem is that it doesn't scale very well. My ECK entities are mapped to /{entity_name}/{bundle}/{id} but your solution is fine for now and much better than what I initially came up with. So thank you for the help. Apr 3 '18 at 15:00
  • @SorinLascu not sure I fully understand your remaining challenge, but how about posting a new question about it, if you want with a reference to this one (as a kind of "followup" question). If you ever do, please drop me a small comment around here about it. I'd be happy to try to help you on such new question also ... Apr 3 '18 at 15:08

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.