Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I'm using the ajax_links_api module to "ajaxify" a certain menu. When a menu button is clicked, the corresponding node loads into a specified div via ajax. This works well.

The problem is that the nodes I want to load in this way should not be accessible as pages. I often create Drupal content that is only designed to appear in views, or as related content on other pages and is not supposed to be displayed by itself. My method is to use .htaccess to block these pages. But when I do that, the ajax can't access them either.

Is there a way to block access to pages in a browser but to allow requests coming from Drupal itself? Localhost access is not really an option since the site may well end up spread across different servers and virtual machines.

If not, then can someone recommend an alternative to the ajax links module - perhaps I need to write some custom ajax that triggers Drupal to serve up a node "directly" rather than via a page - but I am confused about this and could use some pointers in the right direction. I must admit I find the "example" modules confusing!

EDIT: I've tried making a custom module as David Thomas suggests below and using hook_node_access. However this stops the ajax call from returning the content.

share|improve this question
    
Can you post some of your code? –  David Thomas Feb 18 at 2:00
    
Thanks David but I think the problem is that the ajax_links_api module is not flexible enough for what I want to do. I've had another look at some ajax examples and will try rolling my own ajax stuff. –  naomi Feb 18 at 9:02
    
Edited to make it clear that the problem I had was with a specific contrib module, not the core Drupal ajax functionality –  naomi Feb 19 at 13:16
add comment

2 Answers

You can control access to nodes with

hook_node_access

For example, to restrict node viewing on node/[nid] pages:

/**
 * Implements hook_node_access
 */
function MYMODULE_node_access($node, $op, $account) {

  // If viewing node and URL path is node/[nid]
  // where [nid] is current $node->nid
  if($op == 'view' && arg(0) == 'node' && arg(1) == $node->nid){
    // Deny access to view current node page
    return NODE_ACCESS_DENY;
  }

}

You can add your own conditions to get more specific about access control there.

If you want to deny access to all node/%node/view pages, you can do it quite simply with:

hook_menu_alter

For example, set the access callback to FALSE

/**
 * Implements hook_menu_alter
 */
function MYMODULE_menu_alter(&$items) {
  // Disable the node view page at node/%node
  $items['node/%node']['access callback'] = FALSE;
}
share|improve this answer
    
yes,good and suitable solution (y) –  zhilevan Feb 17 at 10:55
    
Sorry, this does not seem to work. The ajax call just returns "You are not authorized to access this page". –  naomi Feb 17 at 15:00
    
You haven't specified any code or how you're making the ajax calls. You'll need to add the appropriate conditional check in hook_node_access. It's core functionality. It will work. –  David Thomas Feb 17 at 19:44
    
Hi, it seems you misunderstood my question. I am using a contrib module called ajax_links_api that allows you to ajaxify links without writing any code. –  naomi Feb 19 at 13:15
add comment

You could use RabbitHole module:

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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