50

So far, I came across these 3 functions in Drupal 7, but I am not really sure what the difference between them is, and which is more appropriated to get the node ID in a block preprocess function.

Can you give me any insight?

2
  • Are you doing this in node.tpl.php or something like that? If yes, you could use $node->nid.
    – Bart
    Jul 8, 2011 at 12:23
  • No i am doing this in a block preprocess function, though the block does get printed on the node page.
    – silkAdmin
    Jul 8, 2011 at 14:12

5 Answers 5

67

I am not really sure what the difference between them is

  • menu_get_object() returns the object associated with the page currently shown. If the code is executed when Drupal is showing the page example.com/node/1, then menu_get_object() will return the node object for the node whose ID is 1; if the page being shown is example.com/user/1, then menu_get_object('user') will return the user object for the user whose ID is 1.
  • menu_get_item() returns an array containing an index for each field contained in the "menu_router" table. This includes:
    • path: the current path of the menu callback
    • load_functions: an array of function names (like node_load) to be called to load an object corresponding to a part of the current path
    • access_callback: the callback that checks if the currently logged in user has access to the menu item
    • page_callback: the name of the function that renders the page
    • title: the title for the page associated to the menu item
  • drupal_lookup_path() is the function that returns you the internal path associated with the alias passed as argument. If "homepage" is the alias associated to example.com/node/1, then drupal_lookup_path("homepage") will return "node/1". Path aliases can be associated to any internal paths, not only to node paths.

and which is more appropriated to get the node ID in a block preprocess function.

If all you want to get is the node ID of the node currently shown, then you just need to use the following code:

if (arg(0) == 'node') {
  $nid = arg(1);
}

If you need to get the node object, then you can use the following code:

if ($node = menu_get_object()) {
  // Use the node object.
}

Of those snippets, the second is better, as it returns the correct node object for internal paths such as node/1/revisions/3/view.

Keep in mind that some preprocess functions, such as the ones for the page, or the node, have already a $variables['node']. This means that in those cases, you just need to use the following snippet in your preprocess function, without worrying about which function to use.

if (isset($variables['node'])) {
  // Check the node ID or other properties.
}

For other preprocess functions, check the documentation to see if there is any variable containing the node object. For example, that is the case for template_preprocess_comment() which makes $variables['node'] available to the preprocess functions for comments.

0
8

How it's done in Drupal Core's template_preprocess_page:

Line 2267 of theme.inc and onwards:

if ($node = menu_get_object()) {
    $variables['node'] = $node;
}

template_preprocess_page uses menu_get_object. After that it's just a matter of checking if the node is defined and getting $node->nid.

5

In Drupal 8, you can get url arguments based on what's in the routing.

To get the id alone:

$nid = \Drupal::routeMatch()->getRawParameter('node');

If you plan to load the node object, you can simply get it this way:

$node = \Drupal::routeMatch()->getParameter('node');

To find the parameter names, you can use:

$possible_parameters = \Drupal::routeMatch()->getParameters();
4

One thing you have to be careful of is path alias.

drupal_get_normal_path($path)

to get the current path use the system variable $_SERVER["REQUEST_URI"]

(If you are on the node page you can call $node->uri['path'], this will return a non-alias path. Then again if you are on the node page, you can just use $node->nid.)

this will return node/XXXX

so try something like

  $node_path = explode('/', drupal_get_normal_path($path));
  $nid = $node_path[1];
3
arg(1);

Is not a bad way of doing it. arg() works on the internal path, so it won't be affected by path aliases.

5
  • This is true, it won't be affected by path aliases. But if you are on node/XXXXX, then you can just use $node->nid. @French, where else would you use arg(1) and it would return what you want?
    – iStryker
    Jul 8, 2011 at 13:29
  • if you are in a module hook you won't have access to node. Views arguments may be an example as well. Jul 8, 2011 at 13:51
  • thanks jeremy and istryker, i have updated my question it might be clearer.. Though i ll try both of your solutions, thanks
    – silkAdmin
    Jul 8, 2011 at 14:16
  • 1
    It is a very bad idea to use arg() , you are binding yourself to a path, use menu_get_object (which just wraps around menu_get_item so that's equally good).
    – user49
    Apr 1, 2014 at 22:18
  • if (arg(0) == 'node' && is_numeric(arg(1))) then arg(1) will to nearly 99% return you a node ID. But a solely arg(1) could also return you a lot of other IDs.
    – leymannx
    May 6, 2017 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.