0

On my page I have a block that reads a variable in the URL. The page that it reads it on is a node. When I pass an argument through the URL to the node, it causes a 404 error. ex:

www.example.com/experience //This is the node, it works
www.example.com/experience/asia //Asia is the argument, I get 404

I've tried configuring the URL Alias to "experience/*", but this obviously didn't work and only accepts '*' as the argument. What do I need to configure to make this work?

I've heard of some modules that automatically add the aliases to the configuration table, but I would prefer a more straight-forward solution.

3
  • What kind of page is this? A node-view page, something declared via hook_menu, a panel page, a view page, etc?
    – mpdonadio
    Commented May 30, 2012 at 19:08
  • It's not a hybrid page or anything, just simply a content node which has the alias 'experience'. You could also view this with 'node/4', etc. Commented May 30, 2012 at 19:15
  • I think describing what the block is going to do with the argument will help others to brainstorm solutions... because passing an argument to a node is not really a normal Drupal function, more likely than not there is probably a module which can help you here depending on what you're trying to do. Commented May 30, 2012 at 21:25

4 Answers 4

2

There are four points to consider:

It is better if such parameter is passed as query string, for example in a URL like http://example.com/node/4?continent=asia. If you really like better to use a URL like http://example.com/experience/asia, then with Drupal 7 you can implement the following hooks.

function mymodule_url_outbound_alter(&$path, &$options, $original_path) {
  if ($path == 'node/4') {
    $path = 'experience';

    if (!empty($options['query']['continent'])) {
      $path .= "/{$options['query']['continent']}";
      unset($options['query']['continent']);
    }
  }
}

function mymodule_url_inbound_alter(&$path, $original_path, $path_language) {
  if (preg_match('|^experience(/(.*))?|', $path, $matches)) {
    $path = 'node/4';
    $_GET['continent'] = $matches[2];
  }
}
0
2

There are modules to accept subpath aliases.

If you're on Drupal 6 then look into the subpath_alias module.

Drupal 7 has subpathauto which does the same thing.

What they do is expand Drupal's path matching to work with subpaths, so no extra aliases are added. I've used it in the past when embedding views within nodes and it worked a treat.

So if you have node/4 aliased to path/test then it will recognise path/test/argument as node/4/argument

1

If you changed your url from

www.example.com/experience/asia

to

www.example.com/experience?type=asia

you should be able to access asia and any other "type" from your block like this:

$types = drupal_get_query_parameters();
foreach ($types as $key => $value){
  switch ($key) {
     case 'asia':
       // code for asia goes here...
       break;
     case 'europe':
       // code for europe goes here...
       break;
     // etc
  }
}

Otherwise, as the comments suggest, www.example.com/experience/whatever is going to fail because drupal hasn't declared a menu item for that path. However, variables can be passed in practically anywhere without drupal needing to know about them all as they don't change the base url.

If you still wanted the "cleaner" looking url, I suppose you could create a hook_menu() item like:

 $item['experience/%'] = array(
   'title' => 'Experience',
   'page callback' => 'experience_type',
   'access callback' => TRUE, 
   'type' => MENU_CALLBACK,
 );

and then function called experience_type that returned the contents of node/4 or whatever experience is aliased to. Then, in your block you could do something like:

switch (arg(1)) {
   case 'asia':
     // code for asia goes here...
     break;
   case 'europe':
     // code for europe goes here...
     break;
   // etc
}

and if all is good in the world, www.example.com/experience/asia would work.

0

It is better to implement hook_menu() and make a custom callback by placing a placeholder after your URL.

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.