Q: Is it possible to programmatically change a Drupal path without resorting to a url_alias? The issue:

Suppose I'm building a site for car enthusiasts, in which they can create entries for their cars -- what kind, what they've done to them, and so on. I'd probably build a module for cars, and create a database table to hold the stuff about the cars that doesn't fit into the node table. The paths to these entries would presumably be something like /node/123, where 123 is the node id of the car we're looking at. It's also easy to imagine that I might offer actions on those nodes which, via the menu system, would exist at paths like /node/123/action1, /node/123/action2, and so on. So far, so good.

Now, suppose that, because of possibly misguided ideas about design or user experience, I don't like the fact that the URL contains the word "node" -- I'd rather have the URLs be of the form /car/123. I can of course do this by defining a url_alias, but, carrying this idea to its necessary conclusion, I also have to create aliases defining /car/123/edit, /car/123/delete, and then car/123/action1, /car/123/action2, and so on. I can again handle these paths with url_aliases, but, when my car site becomes incredibly popular and has thousands if not millions of cars in it, the url_alias table will get painfully huge and will be getting used a lot.

This gets me thinking about whether there's a better way to do this, perhaps through some use of hook_nodeapi or something that would catch the URL, note that its arg(0) is "car", and simply replace it with "node". This would be enough for my situation, since the URLs in question are all a direct replacement of "car" with "node", and it would replace a database hit with a bit of string replacement. Any thoughts out there? Is this possible? Or maybe I'm worrying too much about the cost of the url_alias lookup? Thanks much.

Comments

jim_at_miramontes’s picture

I just noticed this post, which went up while I was writing mine --

http://drupal.org/node/188263 (How do i remove "node" from page urls?)

These are certainly related -- maybe the answer for me is to do the "car" -> "node" renaming in my apache configuration? Will that properly handle the actions defined via the menu system?

jtjones23’s picture

Check out the Pathauto module - http://drupal.org/project/pathauto

jim_at_miramontes’s picture

I'm already using pathauto, but it doesn't seem to be giving me what I'm looking for. That is:

* It seems to be a handy mechanism for setting up the /car/123 -> /node/123 url_alias, but I'm trying to handle the URL naming issues without url_aliases.

* It creates /car/123, but not /car/123/action1 -- I have to build that alias separately.

Or am I missing something? (That's quite possible...)

Anonymous’s picture

Every site I've worked on that does this sort of thing accomplishes it with pathauto. I'd go ahead and use it, and monitor the performance. As far as adding the /action1 to the end of the path, you can use hook_menu in a custom module.

/**
 * Implementation of hook_menu().
 * This is just for the sake of example. I haven't tested this code.
 */
function oogabooga_menu($may_cache) {
  $items = array();

  if ($may_cache) {
    // Insert default menu items here.
  }
  else {
    // Insert menu items specific to the current request here.
    $items[] = array(
      'path' => 'node/'.arg(1).'/action1',
      'title' => t('Menu item'),
      'description' => t('The description of the menu item.'),
      'callback' => 'oogabooga_action1',
      'type' => MENU_LOCAL_ITEM,
    );
    
  }
  return $items;
}

function oogabooga_action1() {
  return $something;
}

This (or something like it) will add an 'action1' path to the end of every node.

Doug Gough

ImageX Media

jim_at_miramontes’s picture

If anyone is still following this thread (or finds it in the future), I just discovered the custom_url_rewrite function -- http://api.drupal.org/api/function/custom_url_rewrite/5 (there are comparable versions for 4, 6, etc.). This did the trick for my exploding url_alias problem, and may be useful to others.

katdc’s picture

Hi! I was wondering if I could do this also, but I am not well versed with PHP. this seems to be the answer I am looking for, but I have no idea how to implement it. Any help will be appreciated.

logan.H’s picture

my suggestion is you can create a vocabulary , example "category"
then add you list of option as terms inside that vocabulary like and make it available to node, by checking the option in the edit vocabulary.
Car
-123
--action
-124
--xxxxx

then using path auto you can make the path like car/123/action , when you choose "action" when you add or edit node.

I am not sure this what you want. May help you.