Where are we ?

Say we are in a block. Or say we are in a node’s body or teaser. We may ask ourselves : where am I ? On this page, whichever page, is there a node displayed ? If so, which node is it ? Or is there a list of nodes displayed ? If so, what kind of list is it ? Is it a list of nodes who share the taxonomy term “news” ? To answer these questions, one needs to understand Drupal’s path system. A brief recap :

In this article, I go into the details of Drupal’s concept of internal path and url alias. Note that 'system path' is another expression used for 'Drupal internal path'.

We use Drupal’s function arg() to know the internal path of the page which is currently displayed. If the path to the page displayed is node/37/edit (corresponding to query http://myWebSite.com?q=node/37/edit), then arg(0) returns "node", arg(1) returns "37", and arg(2) returns "edit". The function arg() considers Drupal’s internal path, not the path alias you may see in the browser’s address bar. Say the web page displays one node with this path alias (pretty link) : "articles/how-to-scrub-your-bath", then what is shown in the browser’s address bar is http://myWebSite.com/articles/how-to-scrub-your-bath. However, arg(0) won’t be equal to "articles" and arg(1) to "how-to-scrub-your-bath" : instead, arg(0) will return "node" and arg(1) the node id (nid) of the node displayed, for example "24".

While we are writing and executing php code in a node’s content or in a block, we have no concept of the current node(s) displayed on the page. We have no clue. It may seem strange that from the body of a node, we do not have direct access to the node id. As a matter of fact, a node doesn’t know itself, from its “body” (or teaser). The most direct approach to know where we are is to always use the function arg(). Say we, as a node, i.e. node with nid 22, want to do something when we are displayed in full view (not just our teaser). Then, we, as a node, have to determine if we are indeed shown in full view, as convoluted as this may seem.

<?php
if (arg(0) == "node" && is_numeric(arg(1)) && arg(2) == NULL) {
  echo
t('We are viewing node %nodeNumber.',
    array(
'%nodeNumber' => arg(1)));
  if (
arg(1) == 22) {
   
// do stuff
 
}
}
?>

Say I am in a block (I am writing code in a block), and I want to do something whenever a node is displayed in full view and is of the type book_review, I will go about finding out when I have to do my thing the following way :

<?php
if (arg(0) == "node" && is_numeric(arg(1)) && arg(2) == NULL) {
 
$thisNode = node_load(arg(1));
  if (
$thisNode->type == 'book_review') {
   
// do stuff
 
}
}
?>

You want to know what’s in a node object ? Examine one when it’s in full view. Create a block and, in it, type the following code snippet, and don’t forget to set the input format to php (and do not forget the php tags).

<?php
if (arg(0) == "node" && is_numeric(arg(1))) {
 
$thisNode = node_load(arg(1));
 
drupal_set_message('<pre>' .
   
print_r($thisNode, TRUE) .
   
' </pre>');
}
?>

We get the following information, and a lot more :

Property Description
type the type of node, for example story
created timestamp of creation time
changed timestamp of last time it was edited
sticky TRUE if it is sticky
title the title
path the path alias
uid user id of author
name name of author
body the content
comment_count the number of comments in it
files an array of file objects (file attachments)

Here is a handy Drupal function that helps us determine if we are on the front page :

<?php
if(drupal_is_front_page()) {
  echo
t('We are on the front page.');
}
?>

We may need an abrupt redirect from where we are to somewhere else, if a certain condition evaluates to TRUE. For example, from a node’s body, we may want to redirect the user to the login page if he’s not logged in (that is a strange example, but no other comes to my mind right now).

<?php
global $user;
if(!
$user->uid) {
 
drupal_goto('user');
}
?>

We may want to determine which menu item is currently active, if any. If we are viewing or previewing a node, the following function will return view ; if we are on the front page, it will return, oddly enough, Content. Getting the name of the current active menu item can be useful.

<?php
echo menu_get_active_title();
?>

We may want to set or get the page’s title. That will either be/become the title of the node or the title of the list of nodes... displayed on the page.

<?php
drupal_set_title
('This page will change your life.');
?>

<?php
echo drupal_get_title(); // will return Content on the front page
?>

Say we want to determine if the current node displayed (if one is displayed) has, among its taxonomy terms, politics. We would like to set a block’s visibility with PHP, so that this block is visible whenever the current user is reading/viewing an article/blog about politics. In the 'Show block on specific pages settings', we will use the mode “Show if the following PHP code returns TRUE (PHP-mode, experts only)”. We have to return TRUE if the current node is about politics.

How do we accomplish this? We have to determine if the page is displaying a node in full view; if that’s the case, then we have to determine if the node has in its taxonomy the term politics. We look at the database tables and realize that the information we need is in 2 tables, one table containing relationship info between tid (term id, a numerical value) and nodes — {term_node}, and another table providing information (including name) about terms — {term_data}. What connects both tables is the term id, i.e. tid. So, we’ll use a JOIN. In plain English, the following mySQL query does the following : trying to get a nid that is the one I am interested in (returned by arg(1)) from the table {term_node} to which is associated the tid that has name politics, a name specified in table {term_data}.

SELECT column
FROM table1
JOIN table2
ON table1.foreign_key = table2.primary_key
WHERE table1.value = x AND WHERE table2.value = y

<?php
if (arg(0) == "node" && is_numeric(arg(1))) {
 
$result = db_query("SELECT tn.nid
        FROM {term_node} tn
        JOIN {term_data} td
        ON tn.tid = td.tid
        WHERE td.name = '%s'
        AND tn.nid = %d"
,
       
'politics', arg(1));
  if(
db_fetch_object($result)) {
    return
TRUE;
  }
  else {
    return
FALSE;
  }
}
?>