2

I am wondered if the following is possible: I need to display some XML data on the fly; these should only be created temporarily (ie not nodes or entries in a database and therefore not readable by Google). The URLs for these and the other XML files I import into nodes have the same structure, generated by a third-party system; so I need the page to be generated if the node doesn't exist (so I guess on the 404 page you will be redirected to).

I thought something like this might work. Any pointers?

<?php
  $hdr = $_SERVER['HTTP_REFERER']; //Format of http://example.com/item/######
  $idnr =  substr($hdr, -6);
  $file = simplexml_load_file('http://api.service.com/customerID/item/'.$idnr);

  if (file_exists($file)) {
    // Put my XML fields here.
  } else {
    //Echo 404 message
  }
?>

EDIT After reading Alfred Armstrong's and develkar's answers I guess what I could think about is something like this: In the module_menu callback function: Look for a node with that URL alias. If that doesn't exist, load the XML. If THAT doesn't exist, return a 404.

2

In hook_menu you define your page:

function MODULE_menu() {
  $items['page-not-found'] = array(
    'page callback' => 'MODULE_page_not_found',
    'access callback' => TRUE,
  );
  return $items;
}

function MODULE_page_not_found() {
  $hdr = $_SERVER['HTTP_REFERER']; //Format of http://example.com/item/######
  $idnr =  substr($hdr, -6);
  // return an object : http://php.net/manual/en/function.simplexml-load-file.php
  $file = simplexml_load_file('http://api.service.com/customerID/item/'.$idnr);   

  if($file) {  
    //Put my XML fields here
  }
  else {
    drupal_set_title('Page not found');
    $cust_err = "";
    $cust_err = $cust_err . "The requested page " . current_path() . " could not be found";
    return $cust_err;
  }
}

Then go to admin > settings > error-reporting, and enter page-not-found, the path you defined in hook_menu.

snapshot

  • 1
    +1 for how to do it on the drupal side of things (admin settings, menu, etc) but I would look into the rest of the logic. A quick glance suggests, for example, that simplexml_load_file() returns an object, not a path to a file. – Jimajamma Apr 29 '13 at 12:21
  • @Jimajamma I didn't check the manual for the return type of the function, just copied it from the OP. I've made the changes that should work. Thank you! – AjitS Apr 29 '13 at 12:26
  • 1
    Using request uri instead of http_referer, this is working so far! – ytrewq May 3 '13 at 13:29
2

Drupal let you specify custom 403 and 404 error pages:

admin->settings->error-reporting

Your custom error page may be PHP, so you can place any logic in it you want, including the one you suggest.

Edit: As already stated by develkar, if you do not want this indexed by Google or other search engines, you disallow it in you robots.txt.

  • How would I make that page not indexable by Google? Wouldn't there still be a node for it to pick up on? – ytrewq Apr 29 '13 at 6:22
  • 2
    @ytrewq You could exclude this page from getting indexed by adding it to your robots.txt file. – AjitS Apr 29 '13 at 6:24
2

If the URLs follow a pattern, then what you probably want is a custom menu entry and load function, eg:

mymodule_menu() {
  $items['somepath/%xml'] = {
    'page callback' => 'mymodule_callback',
    'page arguments => array(1),
     //... rest of menu definition ...
  };
  return $items;
}

mymodule_xml_load($xml_name) {
  // reads the xml and returns an object or returns FALSE
}

See http://drupal.org/node/224170

In other words, the Drupal menu system can already do what you want and all you need to do is code for it.

Edit: If there's truly no means by which you can distinguish Drupal paths from the XML ones, the only route I can see is to use custom_url_rewrite_inbound to some checking upfront. But you'd have to effectively duplicate Drupal's own menu logic with some differences when it comes to these cases.

Or you could hack core to the same end. Hint: please don't.

Or you could request an exhaustive list of all the XML paths so you could add them as aliases into the Drupal database. In this case you would map each xml path to something like xml/ORIGINALPATH, then in your module use the logic I suggested above.

  • Problem is is that the 'somepath' in that would be the XML path... And I have nodes with the same URL pattern. I attempted to use Views/Views XML Backend for this first time around, but for some reason it never gets called and you are instead sent to the 404. Probably because there is no arg[0], it's just www.example.com/######. – ytrewq Apr 30 '13 at 5:39
  • Can you not decide on the URL structure yourself to meet your needs? So all these urls would be of the form eg. www.example.com/xml/someident, the someident part being used to identify the XML file. – Alfred Armstrong Apr 30 '13 at 7:53
  • Nope. The structure is determined via a third party system. I have been told it can't be changed. – ytrewq May 2 '13 at 9:17

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.