6

How can I build a block in Drupal which is able to show the node ID of the view page the block is currently sitting on?

I'm using views to build a large chunk of my site, but I need to be able to make "intelligent" blocks in PHP mode which will have dynamic content depending on what the view is displaying.

How can I find the $nid which a view is currently displaying?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MrFidge
  • 2,107
  • 11
  • 40
  • 63
  • I am a bit confused concerning what you mean by 'view' here - do you mean views from the views module? If so, why do they only have one node ID? (Most views are collections of nodes, but maybe you have a special usage scenario) – Henrik Opel Nov 03 '09 at 19:07
  • Hiya - you're right - I'm using the views module to look up nodes and then format them correctly. All the information on these views relates to one node though - i just need to get that NID. – MrFidge Nov 04 '09 at 09:14

6 Answers6

14

Here is a more-robust way of getting the node ID:

<?php
    // Check that the current URL is for a specific node:
    if(arg(0) == 'node' && is_numeric(arg(1))) {
        return arg(1); // Return the NID
    }
    else { // Whatever it is we're looking at, it's not a node
      return NULL; // Return an invalid NID
    }
?>

This method works even if you have a custom path for your node with the path and/or pathauto modules.

Just for reference, if you don't turn on the path module, the default URLs that Drupal generates are called "system paths" in the documentation. If you do turn on the path module, you are able to set custom paths which are called "aliases" in the documentation.

Since I always have the path module turned on, one thing that confused me at first was whether it was ever possible for the arg function to return part of an alias rather than part of system path.

As it turns out, the arg function will always return a system path because the arg function is based on $_GET['q']... After a bit of research it seems that $_GET['q'] will always return a system path.

If you want to get the path from the actual page request, you need to use $_REQUEST['q']. If the path module is enabled, $_REQUEST['q'] may return either an alias or a system path.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mparker17
  • 413
  • 5
  • 14
  • 2
    On a related note, enabling the `path` module will give you access to a function called `drupal_lookup_path`, which you can use to find a system path from an alias and vice-versa. See the `drupal_lookup_path` documentation for more information: – mparker17 Nov 23 '09 at 16:59
  • 1
    Also, once you have a node ID, you can use the node_load function to get all information about that node: – mparker17 Nov 23 '09 at 17:00
  • 1
    Depending on what context you are pasting my code in, the `return` statements might not always make sense... you may want to replace them with `$displayed_node =` if you need to return something else; but you need to get the NID for something. – mparker17 Nov 23 '09 at 17:14
  • Nice one Mark - that'll be a big help! – MrFidge Nov 24 '09 at 09:25
7

For a solution, especially one that involves a view argument in the midst of a path like department/%/list, see the blog post Node ID as View Argument from SEO-friendly URL Path.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter Petrik
  • 429
  • 4
  • 5
2

In the end this snippet did the job - it just stripped the clean URL and reported back the very last argument.

<?php
    $refer= $_SERVER ['REQUEST_URI'];
    $nid = explode("/", $refer);
    $nid = $nid[3];
?>

Given the comment reply, the above was probably reduced to this, using the Drupal arg() function to get a part of the request path:

<?php
    $nid = arg(3);
?>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MrFidge
  • 2,107
  • 11
  • 40
  • 63
  • You should take a look at the arg() function for extracting arguments from a drupal path - see: http://api.drupal.org/api/function/arg/6 – Henrik Opel Nov 04 '09 at 18:54
  • Henrik - thats perfect! Worked a dream. – MrFidge Nov 06 '09 at 14:32
  • @hfidgen: I edited your answer to point to the 'arg()' function usage, as it would be the recommended way. Adjust or roll back, if that is not OK. – Henrik Opel Nov 06 '09 at 15:30
  • I'm curious what the solution to this problem is when the URL _doesn't_ contain the node id. EG - passing multiple nids from a view to a block. – starsinmypockets Apr 19 '11 at 18:03
1

There are a couple of ways to go about this:

  1. You can make your blocks with Views and pass the nid in through an argument.

  2. You can manually pass in the nid by accessing the $view object using the code below. It's an array at $view->result. Each row in the view is an object in that array, and the nid is in that object for each one. So you could run a foreach on that and get all of the nid of all rows in the view pretty easily.

The first option is a lot easier, so if that suits your needs I would go with that.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
theunraveler
  • 3,254
  • 20
  • 19
  • Option 1 didn't quite work i'm afraid - it could pick the argument up, but the argument was formatted incorrectly for what i needed - it kept using the alias rather than the nodeID – MrFidge Nov 04 '09 at 18:19
  • You can check the option under the argument to pass in the node ID from the URL if no argument is present. Or you can check the PHP code option and input something like: $url = explode('/',$_GET['q']); return $url[1]; – theunraveler Nov 04 '09 at 18:25
1

You should considder the panels module. It is a very big module and requires some work before you really can tap into it's potential. So take that into considderation.

You can use it to setup a page containing several views/blocks that can be placed in different regions. It uses a concept called context which can be anything related to what you are viewing. You can use that context to determine which node is being viewed and not only change blocks but also layout. It is also a bit more clean since you can move the PHP code away from admin interface.

On a side note, it's also written by the views author.

googletorp
  • 33,075
  • 15
  • 67
  • 82
0

New about Drupal 7: The correct way to get the node id is using the function menu_get_object();

Example:

$node = menu_get_object();
$contentType = node_type_get_name($node);

Drupal 8 has another method. Check this out:

arg() is deprecated

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fabrizio Sabato
  • 319
  • 3
  • 14