0

How do you pass an argument from a menu to an existing node? I've read many articles on hook_menu but they seem to all talk about creating a page which references the arguments.

for example:

function myModule_menu(){
  $items['node/123/%'] = array(
    'page arguments' => array(1),
    'access callback' => TRUE,
  );
  return $items;

In my Navigation menu, I'd want to use a menu item with: node/123/option1

How would I get the argument 'option1' available to me in for example, the node.tpl.php file to manipulate the rendering of node/123 ?

At the end of the day, I'm trying to do is execute some jquery code based on a menu's argument, but the initial hurdle, how do I get access to these optional arguments on the url?

1 Answer 1

3

The easiest way is to use $argument = arg(2) but more formal and much better way will be to create new menu item based on node/%node:

function yourModule_menu() {
  $items['node/%node/%'] = array(
    'page arguments' = array(1, 2), // Here you can specify which parts of url are page callback arguments (starting with 0)
    'page callback' = 'yourModule_node_with_option',
    'access arguments' => array('content access'), // Try to avoid access callback = TRUE
    'type' => MENU_CALLBACK,
  );
  return $items;
}

function yourModule_node_with_option($node, $option) {
  // build your new page here.

  // $option is your extra parameter.
  $output = $node->nid . ' ' . check_plain($option);

  // This will show you node id and value of parameter
  return $output;
}
5
  • 1
    The %node will load an entity with the given id using the [entityname]-load() function. For %node this will be node_load(). This saves you from having to load the node manually and your callback function will receive the entire node object. Commented Jan 26, 2015 at 8:29
  • 2
    Thanks for adding that comment. In fact it doesn't have to be entity sensu strico. Drupal will look for [name]_load() function (based on %_name_ from menu item path) and if that function exist returns its value as a page callback argument. So you can have $items['node/%node/%yourModule_preprocess_argument'] and function yourModule_preprocess_argument_load($argument) where you can do something with this argument (for example load data from DB based on it).
    – zaporylie
    Commented Jan 26, 2015 at 8:48
  • I guess this is where my understanding falls apart. Above "build you new page here"... yup I've got ok, but how do you get the existing node + the argument variable? return $node crashes. You did mention this would give the callback function the entire node object.
    – Dubya
    Commented Jan 26, 2015 at 12:29
  • 1
    $node variable in yourModule_node_with_option containing node object (all node data fetched from DB) and you can't render it just like this, you need to do something with this data (process it). If you'd like to render this set of data as a full node (like on example.com/node/123) you must load node object to node_view() which generates renderable node array (processed data ready to display). Try to return node_view($node); for beginning and see what will happen than change it to return node_view($node, 'teaser'); and see how it looks.
    – zaporylie
    Commented Jan 26, 2015 at 13:55
  • Than you can decide to display specific field only using field_view_field() or use your optional parameter passed in url and available for you in $option to render that page dynamically.
    – zaporylie
    Commented Jan 26, 2015 at 13:57

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.