Adding Argument code to Views using the Node:nid

Sometimes you want to get something quite specific into Views and its not easy with the standard filters. This is where arguments come in:

For instance I wanted to make a view show recordings for a particular composer.
I've 2 node types: Recording and Composer.
Each Recording has a node reference CCK field to select Composer(s) - there can be multiple composers

Heres an easy way to get at that data:
Firstly look at where the node reference CCK is storing the data, in my case its in a table called content_field_recording_composer, i'm interested in 2 fields within this table, the nid field and the field_recording_composer_nid field. They're fairly self explanatory - as this CCK field is on the Recording node as you've probably guessed the nid field is the nid of the Recording node I want, the field_recording_composer_nid field is the nid of the composer.

So i can make a really simple Drupal database statement like this to get all the nids of the Recordings:

<?php
$result
= db_query("SELECT DISTINCT c.nid FROM {content_field_recording_composer} c WHERE c.field_recording_composer_nid = %d", $nid);
?>

Now to make the view:

  • Go to views and create a new view of node type
  • Under arguments add a Node:nid argument
  • Under "Action to take if argument is not present:" select "Provide default argument"
    Under "Default argument type:" select "PHP Code" and you'll see a box appear where you can enter your PHP code

views expects arguments separated by either commas or plus symbols so we need to make the PHP code spit that out - here's how i've done it:

<?php
// Get related info
       
if(arg(0) == 'node' && is_numeric(arg(1))){
           
// counter
           
$i = 0;
           
// current node id
           
$result = db_query("SELECT DISTINCT c.nid FROM {content_field_recording_composer} c WHERE c.field_recording_composer_nid = %d", arg(1));
                while (
$node = db_fetch_object($result)) {
                    if (
$i > 0){ $nids .= ',';}
                   
$nids .= $node->nid;
                   
$i++;
                }
            return
$nids;
        } else {
            return
'';
        }
?>

In the code above you can see i'm checking a couple of things too though you don't always have to. The second line of code has an if statement to check that we're on a Node page and the second argument is numeric, i.e. the url looks something like this: "mysite.com/node/2". The first argument - arg(0) is "node" the second argument - arg(1) is "2" in this case.

We then set a variable to 0 to act as a counter. Then make a query - looking for any nids where the field "field_recording_composer_nid" is equal to arg(1) the node id of the current coposer.

Then we go through the result of that query and make a comma separted list of any nid's that are returned.

The line "return $nids;" sends the list of nids for views to work with.

Other things to check:

  • If you want to work with more than one nid then check the "Allow multiple terms per argument." checkbox
  • Any further filtering can be done with the normal views filters - this keeps your code to a minimum and makes it less specific and more easily reusable
  • Its worth saving the code in a php file somewhere to store and check - to test it out its quite useful to make a block, either in a module or just add one at http://YOURSITE.com/admin/build/block/add - and stick in the php code there
  • I found that the preview function in Views doesn't work properly when using argument code like this - so test it like above to make sure its all working, then create a block, or whatever in views and test it in the correct area