I have read many posts on different problems obtaining the $node nid. If you are on a node, in the view state, is there any way to get the current nodes nid? I see it in the URL, is there a way to get it from there?

This strikes me as overly difficult to load/find the current node's nid. Seems like there should just be some global object like the user object. Knowing the current node id is huge!, from there seems like you could do anything.

Any pointers? Thanks for your thoughts.

Comments

coreyp_1’s picture

if (arg(0) == 'node' && is_numeric(arg(1))) $nodeid = arg(1);

partially stolen from node_menu();

- Corey

M.J. Taylor’s picture

goose2000,

Thanks for asking this question, I've been trying to find out how to do this for the last week or so. And unfortunately coreyp_1's code doesn't work if you've assigned a URL to the view. Then arg(0) is the URL of the view and arg(1) is NULL...

You can see some of the stuff I've tried and failed with, in the thread http://drupal.org/node/160664 .

Anybody know how to always access the Node ID(s) from a View?

M.J. Taylor
Publisher
from Reason to Freedom
Wekly libertarian magazine promoting thinking for oneself, thus helping to create a free, benevolent society.

goose2000’s picture

This worked quite nice! Much better than my url hack below, and works on a regular php input type page:

<?php
// if we find an argument called 'node' , and it's is numeric then do some TRUE stuff
// something like that ?

if (arg(0) == 'node' && is_numeric(arg(1))) $nodeid = arg(1);
print $nodeid; // show me your nid!
?>

Thank you, works on D5 from here too.

francisexpress’s picture

Hi,

I need to write small php code to get latest 5 nid's from node and return nid's. This piece of code would be used as an argument in Views...

Does anyone have any suggestion. It would be most wellcome as I'm still a neubi in php.

Many thanks in advance..

Francis

mayur.pimple’s picture

// return '31'
print arg(1) ;

yelvington’s picture

As documented in the PHPtemplate handbook, $node is available to any page template that is displaying a full node, as of Drupal 5. No tricks are necessary. On previous versions of Drupal, $node was available only to node.tpl.php.

M.J. Taylor’s picture

Hi yelvington,

Pre D5, Views had to know what node it was dealing with, or it'd just return a blank page all the time...

So, maybe it isn't specifically $node, but there, by definition, has to be some variable in Views that contains the NID otherwise, well, Views just wouldn't work...

Now, somebody, please!, give us a hint as to what holds the bugger prior to D5,

MJ

dvessel’s picture

That's not true. 4.7 had $node available in page.tpl.php. Look inside phptemplate.engine > phptemplate_page() to see it load the node.

http://api.drupal.org/api/4.7/function/phptemplate_page

@M.J. Taylor: The original question was about getting the node id when on a single node page. Views works to display a collection of nodes based on filters. Have you checked out the handbook on theming views? http://drupal.org/node/42597 ..

M.J. Taylor’s picture

"If you are on a node, in the view state"

Sounds like he/she's using Views in some manner to display the node?

And yes, I've read Views front, back, and sideways. Most of the API pages are empty stubs. I am displaying a single, random, node page by using Views. I am not trying to theme anything, I'm just trying to identify the NID from inside the View, specifically the footer, but I really couldn't care what section of the View I stick the PHP in, as all I personally would like to do is update the total and day counts, since Views doesn't do it on it's own.

Also, there has to be some true way to identify the Node ID within D4, as quite frankly the code:

if ((arg(0) == 'node') ...

does not work if the site has something like pathauto enabled or the View is given a URL to use as the default front page.

I'm not trying to be argumentative, negative, or even an asshole. As I pointed out, the above does not reliably acquire the NID. Obviously Drupal has to have knowledge of the NID outside of the construct of arg as things like pathauto do work.

Potentially Views buries the NID inside itself, as it must being doing an internal database call. But without it being defined in one of the Views Handbooks or Views API manuals, we the peons just trying to use Drupal are stuck having to ask, again and again, until someone that happens to know the internals will do something more than replay with, "have you RTFM?"

So, Joon, I'm not trying to be pissy with you, I've just blown most of this last week trying to find the answer to something that arguably should be a five minute lookup in a reference book.

Hoping you have a great weekend,

MJ

coreyp_1’s picture

if ((arg(0) == 'node') ...

does indeed work, even with path auto enabled because of how path aliases work. When a page is requested, say www.example.com/foobar, then drupal immediately sees if there is an alias called "foobar". If an alias is found to "node/13", then then the query string variable that originally contained "foobar" is now overwritten to contain "node/13". Therefore, arg(0) will return "node", and arg(1) will return the node id (13, in this example).

[side point]
BTW, it is important to realize that Drupal looks for a URL alias first, before it does anything. This is a handy thing to know, because that means that you can override any module-generated page, simply by aliasing the url somewhere else. For example, suppose you don't like the way Drupal displays "node/add". You can create a node, give it the alias "node/add", and from now on your custom page will be displayed instead of Drupal's default page. Another usage would be to alias common Drupal paths (like "node") so that they point to a 404 page, to hide that you're using Drupal.
[/side point]

Now, the question remains, where are you trying to use this code? I assumed (probably shouldn't have) that it was being used in a block. I assumed this for two reasons:

  1. If the nid were needed in the page template, then the $node object is already made available by phptemplate, and you don't need any fancy code to get it.
  2. goose2000 wasn't asking about when the node shows up in a view, because he mentioned that the nid is visible in the url. When he mentioned the "view" state, I assume that that is in contrast to the "edit" tab or "revisions" tab.

Of course this would not work for a views page, because a View is not a node. It is a function call, so to speak, that returns a list of nodes. In that situation, you are probably wanting to know the nid of each individual node as it is rendered for styling purposes, which is a completely different problem.

Long story short, the method I described is a reliable, core-utilized method for dealing with node urls. In short, it is as stable as Drupal itself.

- Corey

M.J. Taylor’s picture

Corey,

Thank you for the information, especially the aside, which was helpful in accomplishing this goal with Drupal, and will also be helpful in my general future with Drupal. And specifically, thank you for the clarification on Views being functions, and in essence not following the rules of being a node, which since they aren't, one can't use standard arg logic with them.

Which allowed me to kludge together an effective, if exceedingly ugly, solution to finding NID(s) inside a View and then updating a single NID's totalcount and daycount. Which I'll share, right after I explore the Globals dump method given by Dvessel below. As, I'd rather not have to hack views.module, which is what I ended up doing in frustration late last night.

After testing, etc., I'll post the solution as a reply to Dvessel post below, and then write up a Handbook page with fuller explanations.

Again, Thank you Corey and Dvessel,

MJ

dvessel’s picture

MJ, unfortunately some parts of the documentation can be lacking. I found the best place to look is in the code itself. It's often commented and a deeper understanding can be attained. Yeah, it sucks for non-coders but most devs document while writing code and I learned PHP myself from doing it.

I glanced at your other thread. It's better to ask what your trying to accomplish than to go about it in your own way, especially if your not familiar with Drupals api.

It's true, arg() won't help you out here for Views.module. The original question wasn't about Views as coreyp_1 pointed out. Try print var_dump($GLOBALS); and look at a page with your custom View and search for the current nid. I'm not running 4.7 so I can't test.

Good luck.

M.J. Taylor’s picture

[Wrong place to post this, but doing so in answer to dvessel, and will expand all my current Views posts into Handbook pages. MJ]

Exceedingly ugly, but works...

Goal:
Find a NID(s) inside a View and then update a single NID's totalcount and daycount. (See above posts by me for additional info.)

Findings:
After exploring the Global dump given by Dvessel, there is no Global var that holds the displayed Node ID(s) accessible by PHP within a View. Both 4.7 and 5.1 have this same problem and the below solution works for both.

Constraints:
- Only tested for a View returning a single node in the Page format.
- has less than stellar error handling (actually none).

To find the NID(s):
a) hack views.module
- Add as the first two lines of "function theme_views_view_nodes("

  global $whatisthenodeid;
  $whatisthenodeid = $nodes;

b) create a single node View, such as the one in http://drupal.org/node/159198 , then:
== In your View's Page >> Footer
- set "Input format" to "PHP code"
- Add the code

<?php
    global $whatisthenodeid;
    $nodenid = $whatisthenodeid[0]->nid;
    db_query('UPDATE {node_counter} SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d', time(), $nodenid);
?>

# # #

Results:
- 4.7 has no errors in my log files.
- 5.1 has no errors in my log files related to this. (Errors logged are the same with or without above patches.)

Thanks Corey and Dvessel for giving me enough data to pursue this to conclusion,

MJ
Publisher
from Reason to Freedom
Wekly libertarian magazine promoting thinking for oneself, thus helping to create a free, benevolent society.

patrickespake’s picture

I read the content above and not thought very good, it has to add two lines of code in views.module in the
theme_views_view_nodes.

We found this very good solution, because it will update the Drupal have to move there. He was wanting something better and without touching on any other module or core of drupal.

But the way people have enough difficulties with this, it may be something to think in the next versions of drupal

Patrick Espake
e-mail: patrickespake@gmail.com
site: www.patrickespake.com

goose2000’s picture

Thank you all for the good responses, it's helping me and will others too.

from coreyp -

"goose2000 wasn't asking about when the node shows up in a view, because he mentioned that the nid is visible in the url. When he mentioned the "view" state, I assume that that is in contrast to the "edit" tab or "revisions" tab."

True. Not talking about views module here. I will try out these snippets today. I was also looking at this idea, getting nid from URL :

http://drupal.org/node/61463

This might work for some, this has an advantage that you don't need a custom template. You can just run it as PHP, use php as your input type, not html. I did mine to find the bit after 'node/' in the URL string. This code could be better, more acurate somehow:

<?php
$fs_refer= $_SERVER ['REQUEST_URI'];

$fs_refer = explode("node/", $fs_refer);
// echo "$fs_refer[0] is the first chunk of the URL.<br />"; 
// echo "$fs_refer[1] is the bit after 'node/'<br>";

return $fs_refer[1];
print $fs_refer[1];
?>

But will look at these others, probably smarter and safer.

Thanks, John A (goose2000)

lovermann’s picture

Simple solution, but it won't work when using url aliases. There'll be no node id in address bar, so no string to parse. I think in this case the funcion
drupal_get_normal_path()

could be helpful.

druwar’s picture

if url aliases are used on site so arg(0) solution will not work. Following solution is the better choice for all cases.
$nid = substr($_GET['q'],strrpos($_GET['q'],"/")+1);

phayes’s picture

I've got a form embedded in some nodes using drupal's form API.

Now I need to call the node function from inside of my drupal_submit_form callback function. But it's not there!

Even if it global $node, still nothing.

Help would be much appreciated.

Cheers

Patrick Hayes

KingMoore’s picture

Hello,

I realize this topic is rather old, but I am just wondering why Drupal doesn't provide any function like:

function current_nid(){
  if (arg(0) == 'node' && is_numeric(arg(1))) { 
    $nid = arg(1);
    return $nid;
  }
  else {
    return 0;
  }
}

This seems like it would be a simple, helpful function to have and I wouldn't have to constantly do searches for this thread so I can copy and paste:

if (arg(0) == 'node' && is_numeric(arg(1))) $nodeid = arg(1);
feo’s picture

 $nodeid = (arg(0) == 'node' && is_numeric(arg(1)))?arg(1):FALSE; 
agha_zair’s picture

Thanks Feo, it solved my problem of getting current node id in form api

CleanCutRogue’s picture

Simple solution: Create a currentnode module. It wouldn't take much... this should work:

1. in sites/all/modules create a directory called /currentnode

2. Create a file called currentnode.info and place the following text in it:

name=CurrentNode
description=Provides a function for easy access to current node
version=5.x

3. Next, create a file called currentnode.module and place the following text in it:

<?php
function currentnode_nid(){
    if (arg(0)=='node' && is_numeric(arg(1)))
        return arg(1);
    else 
        return 0;
}

function currentnode(){
    return node_load(currentnode_nid());
}

4. Then go to /admin/build/modules and enable the new module called "CurrentNode"

Now, in a block or page or whatever, you can use currentnode_nid() to return the nid of the currently-viewed node. For example, you might create a block with php-enabled visibility and use the code: return currentnode_nid(); so that the block is only visible on pages that are valid nodes. You can use the more versatile function currentnode() to return more important information about that node, such as currentnode()->title or currentnode()->uid. Heck, you could even return currentnode()->nid if you don't want to use the currentnode_nid() function.

Simple enough.

Warning: I composed the code above at-the-keyboard and didn't test first in a module. Let me know if it doesn't work and I can test it and figure out why.

KingMoore’s picture

Yeah I realize it would be easy to provide this function myself. I was just wondering if there was a reason Drupal didn't provide a function like this.

CleanCutRogue’s picture

Yeah... not sure. It would be simple enough for it to be provided in one of the include files...

acase’s picture

I was wondering about this too...I created the module posted above but I kept getting an undefined value. I am creating a content template using contemplate in Drupal 6.3 and I came across this option in the Body Variables section:

$node->nid

I am new to drupal so I am unsure whether this works site wide or just in templates (I assume it would work everywhere...looks global?) but I was able to use this piece of code in the body portion of my template to retrieve the current node's nid:

var nodeID =

$node->nid;
$tempnid=$node->nid;
print ($tempnid)

;
alert (nodeID);

Hope that helps! I appreciate feedback on whether or not this works for anyone else since I am definitely still a beginner and don't know how many things work in Drupal...thanks!

Summit’s picture

Hi You need to load the node first when you would like to use it.
Greetings,
Martijn

StephenRobinson’s picture

<?php
global $node;
print ($node->nid);
?>
seancr’s picture

It works, i had to change version to core for my Drupal 6.x install. Thank you for the good post. It was also a good crash course for me on how to create a custom module.

merakli’s picture

I created this custom module and used PHP to trigger this function for taxonomy redirect (D6). The function works fine on node pages but always returns 0 on pages, with listed teasers, such as term main pages. Any advice?

jessa_d’s picture

I'm struggling with this, too. Since this taxonomy page doesn't refer to a single node in the URI, this trick doesn't work. The php inside of a "php input" body field (or any other similar textarea field) doesn't appear to have any values passed to it whatsoever. I understand that extensive use of php code inside node content is discouraged and avoid it myself, but there are occasional times it is the right solution, and the lack of contextual data is a real problem.

Does anyone know how to pass data into that field in a way that can tell it what node it belongs to? I don't mind writing a small module for this, but I'm not sure where to start?

patacra’s picture

It's a shame I didn't find a Drupal core function to get the current viewed node...

Well, for the moment I've made myself the following function. I use this function to render blocks.

It checks if we are commenting or watching a revision of a node. But if the node is being edited, deleted or something else, this function will NOT return the current node, but simply null. It also checks access rights to avoid blocks showing node related data comming from unpublished or private nodes.

It may contain some cases I didn't really think at. Please post a comment if you find a bug!


/**
 * Used to get the current viewed node (works when viewed in page mode).
 * @param array $node_types[optional] A filter on the type of node you want to see.
 * @return object The node or null if not successfull.
 */
function helper_get_current_node($node_types = array()) {
  // Store the current node id, to avoid doing the URL testing
  // on every call to this function. I didn't store the node itself
  // because I was afraid of data changes during page processing.
  // Normally node_load() already does some static caching and I think
  // it handles cache updates correctly.
  static $nid;

  if (!isset($nid)) {
    $arg = arg(); // Get URL splitted.

    // What type of URL is it?
    switch ($arg[0]) {
      // Viewing a node or a revision of a node :
      case 'node':
        // If the node id is missing, null or not numeric
        if (!isset($arg[1]) || is_null($arg[1]) || !is_numeric($arg[1])) {
          $nid = false;
        }
        // Look at the 3rd part of the URL ('edit', 'view', 'revisions', ...)
        if (isset($arg[2])) {
          switch ($arg[2]) {
            case 'view':
              break;
            case 'revisions':
              // If we are not viewing a revision
              if (!isset($arg[4]) || $arg[4] != 'view') {
                $nid = false;
              }
              break;
            default: // 'edit', 'delete', etc...
              $nid = false;
          }
        }
        // If $nid has not been set, it means we where viewing a node.
        if (!isset($nid)) {
          $nid = $arg[1];
        }
        break;

      // Commenting a node :
      case 'comment':
        // If the URL just has /comment, or if the node id is missing or not numeric
        if (!isset($arg[1]) || !isset($arg[2]) || !is_numeric($arg[2])) {
          $nid = false;
        }
        // If $nid has not been set to false, it means we should be commenting a node.
        if (!isset($nid)) {
          $nid = $arg[2];
        }
        break;

      // URL doesn't start with something relative to node viewing
      default:
        $nid = false;
    }
    
  } // end if $nid is not set.

  // Return null if we are not viewing a node.
  if (!$nid) return null;

  // Load the node.
  $viewedNode = node_load($nid);

  // return null, if node not loaded, if node isn't the desired type
  // or if the user isn't allowed to see this node.
  if (!$viewedNode ||
      !node_access('view', $viewedNode) ||
      (count($node_types) > 0 && array_search($viewedNode->type, $node_types) === false)) {
    return null;
  }

  return $viewedNode;
}

gregoiredavid’s picture

'menu_get_object()' (drupal 6 and 7) works fine for this, just set the $type and $position :

$type default is 'node' but could be any of these : aggregator_feed, aggregator_category, contact, filter_format, forum_term, menu, menu_link, taxonomy_vocabulary, user.

$position default is '1' (for node/%node), you can use '2' (for 'comment/reply').

source and more details here :
http://api.drupal.org/api/function/menu_get_object

cigotete’s picture

$node = menu_get_object();
echo $node->nid;

spineless’s picture

I attempted to extract the nid from a node a couple of ways using Drupal 7.8. I am always getting an error for the statement: $node->nid.

Here is the code:

function get_nid_action() {  
  $node = menu_get_object();
  $get_nid = $node->nid;
  drupal_set_message("Nid is:" . print_r($get_nid));
}

Notice: Trying to get property of non-object in get_nid_action() (line 35 of ..sites\all\modules\my_rules\my_rule.rules.inc).

I attempted using node_load() or If ((arg(0) =='node') &&(is_numeric(arg(1))) but for each different way I attempted to print the nid of the current node I still need to declare $node->nid and I am always getting this error....it is just not working for me.

Any help would be greatly appreciated.

cigotete’s picture

hi Spinless,

my post was related with Drupal 6. for Drupal 7 I saw that just is needed:

$node->nid

so is not necessary $node = menu_get_object();.
Note: I am using $node->nid inside a custom node template.

spineless’s picture

I removed the menu_get_object().

I think I figured it out why it did not like $node..... I forgot to pass the $node into the function.

opps.

bmango’s picture

menu_get_object() doesn't work when you have clean URLs enabled. To get it to work you will first need to use drupal_get_path() to convert the aliased URL to drupal's internal path.

I spent half a day finding this out!

Ben

Drupal Website Design

Ayesh’s picture

print arg(1); works for me everytime.

dan.mantyla’s picture

If you want to get the URL alias and/or node/nid string, you can try this:

<?php $my_nid = substr($_SERVER['REQUEST_URI'], 1); ?>

georgechenley’s picture

Strange, but didn't help. Maybe something in my arms(

dan.mantyla’s picture

sorry, I have a weird server setup (lighttp with lots of enhancements, vhosts, custom configs, etc.) so maybe that's the difference

sumaiyajaved’s picture

$node = $form['#node']; $nid = $node->nid;
This worked with Drupal 7 when dealing with form_alter function

Regards,

Sumaiya Javed
Web Developer
www.sumaiyajaved.com
www.phpjavascript.com

Carly987’s picture

Its works! Thanks alot

Jamiesor’s picture

echo $row->_field_data['nid']['entity']->{'nid'};

knalstaaf’s picture

I think this thread is mainly about D6.

A D7 approach would be

  if ($node){
    $mynodeid = $node->nid;
  }

or

<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
mikeparker’s picture

if ($node = menu_get_object()) {
  // Get the node ID
  $nid = $node->nid;
}