views:

389

answers:

4

I'm running into problems trying to pass absolute URIs as parameters with clean URLs enabled.

I've got hook_menu() set up like this:


function mymodule_menu() {
  return array(
    'page/%' => array(
      'title' => 'DBpedia Display Test',
      'page callback' => 'mymodule_dbpedia_display',
      'page arguments' => array(1),
    ),
  );
}

and in the page callback:


function mymodule_dbpedia_display($uri) {
  // Make an HTTP request for this URI
  // and then render some things
  return $output;
}

What I'm hoping to do is somehow pass full URIs (e.g. "http://dbpedia.org/resource/Coffee") to my page callback. I've tried a few things and nothing's worked so far...

  1. http://mysite.com/page/http%3A%2F%2Fdbpedia.org%2Fresource%2FCoffee
    Completely breaks Drupal's rewriting
  2. http://mysite.com/page/?uri=http%3A%2F%2Fdbpedia.org%2Fresource%2FCoffee
    Gives a 404
  3. http://mysite.com/page/http://dbpedia.org/resource/Coffee
    Returns just "http:", which makes sense

I could probably use $_GET to pull out the whole query string, but I guess I'm hoping for a more 'Drupal' solution. Any suggestions?

+1  A: 

If the source of the urls is something you control, why don't you use a reversible encoding, like base64, to encode the string and therefore remove any tricky characters, then decode when you execute your menu callback. Eg:

$link = 'http://www.example.com?uri='. base64_encode($uri);

...


function mymodule_dbpedia_display($uri) {

$uri = base64_decode($uri);
// Make an HTTP request for this URI
// and then render some things
return $output;
}
cam8001
Thanks, this will do the job if it comes down to it. However, I would like to avoid encoding to something illegible if possible.
wynz
+1  A: 

I have had this problem before, trying to do the same thing (RDF browsing). I got round it by using rawurlencode and rawurldecode on the URI.

So when creating link do

l('Click Here', 'page/' . rawurlencode($uri));

and when using your $uri variable do a rawurldecode();

$uri = rawurldecode($uri);

It will give you a URI something like

http://mysite.com/page/http%253A%252F%252Fdbpedia.org%252Fresource%252FCoffee
Jeremy French
This almost works. I think the key is not the use of rawurlencode() (versus just urlencode()) but the fact that it's getting double encoded when used with the l() function. However, SOMEHOW Drupal still sees the first slash and arg(1) returns only "http:". How did you get around that?
wynz
It just seemed to work for me. I have checked again and it still seems ok. I am using D7 on a lamp stack, don't know if it would make any difference.
Jeremy French
I should have mentioned that I'm working with D6. Seems argument handling may have changed.
wynz
A: 

This should just work; it's a known bug in Drupal. You could try the patches in that thread, but your best bet may be to just do a different encoding on top of URL encoding, as others have suggested.

Scott Reynen
A: 

Instead of using page/%, use page/%menu_trail. %menu_trail will pass the rest of the URL as a single string that in your example will be passed to the menu callback as $uri.

kiamlaluno
Thanks. The %menu_trail method doesn't work as simply as you described, but it lead me in the right direction and I got it working. I found the solution [here](http://drupal.org/node/109153#load). I used a %wildcard_load() function to implode the argument map back to a string. Too bad it's not simpler, but it works.
wynz
What I reported is written in http://drupal.org/node/109153#to_arg. I am actually using it in one of the modules I am developing (http://drupal.org/project/opensearch), and it works.
kiamlaluno
Your usage is different. The %menu_tail portion never gets passed to the callback. The opensearch module and the core search module both pull arguments directly from $_GET using search_get_keys(). From what I can tell, %menu_tail mainly allows links on a page to be written properly when there's an extra slash in the URL. The situation [hasn't been resolved](http://drupal.org/node/600424) for D7 yet either. Thanks for pointing out the opensearch module though, looking forward to trying that out with some upcoming projects.
wynz