hi,

I have module that is working quite well, but I want to enhance some of the features. I have this in hook_menu:

	if (arg(0) == 'node' && is_numeric(arg(1)) && user_access('edit own qcodo_application')){
		// Only add application specific tabs to the right nodes
		$result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.type = 'qcodo_application'"), arg(1));
		if (db_num_rows($result) > 0) {
			$items[] = array(
				'path' => 'node/'. arg(1) .'/drafts',
				'title' => t('Drafts'),
				'callback' => 'qdrupal_drafts',
				'callback arguments' => array(arg(1)),
				'access' => user_access('edit own qcodo_application'),
				'type' => MENU_LOCAL_TASK,
				'weight' => 8);
<snip>

I have three questions.

1) Is there a better way to implement the logic above? essentially I want use the MENU_LOCAL_TASK items only on my custom node type pages. the code above is sample code form somewhere. It works, but maybe there is a better way? right now it looks for a path that starts with node and then has a numeric node number, then it queries the db to see if node is a the node type I'm looking for.

2) How can I make this work with URL path aliases? I can alias myapp to node/9 which works fine, /myapp brings up my node and the local tasks like defined in my code snippet are displayed. Hovering over them shows the links to be /node/9/drafts and clicking on them works. However, I can't go to myapp/drafts. Is there a way to make /myapp/drafts work? ( or whatever someone may use as a alias to the node, ie /path/alias/to/my/node/drafts )

3) the callback function specified above 'qdrupal_drafts' acts as a front controller too, so it can see node/9/drafts/list and use 'list' as an operator. Similar to question 2), is there a way, if /node/9 is reached via an alias alias that the qdrupal_drafts function can still reliably get the args that come after it?

thanks,

Comments

panis’s picture

1. you could consider instead doing a - however yours would be faster. The general approach is correct

if( $may_cache ) {
  $node = node_load(arg(1));
  if( $node && $node->type == 'qcodo_app' ) {
    //create menu here
  }
}

2. not sure your approach will be reliable for aliases if individual users can have their own "myapps", also which node do you pick if you have multiple qcodo_apps? assuming each user can have only one qcodo_app you can do the following in your hook_menu(). If you are using the path module to alias - have you tried aliasing myapp/9/drafts to myapp/drafts?

$menu[] = array(
'path' => 'myapp/drafts',
'callback' => 'myapp_drafts',
'type' => MENU_CALLBACK,  
);

//repeat for the myapp_drafts path with a different callback function
function myapp_drafts() {
  global $user;
  $nid = db_result(db_query("SELECT nid FROM {node} WHERE type='qcodo...' AND uid=%d", $user->uid));
  if($nid) {
    qdrupal_drafts($nid);
  } else {
    drupal_not_found();
  }
}

//repeat for myapp...

3. yes - aliases will map to the actual path.