Get nodes as an array for greater flexibility

Last modified: August 27, 2009 - 00:34

By default, in your page.tpl.php you have $content which contains all the nodes and other things like pagination..etc. The snippet below tries to give more flexibility by breaking down $content, and breaking down nodes themselves into an array of nodes. Precisely, what happens is:

  • In page.tpl.php: You get a new array (YES!) called $nodes, contains the XHTML for each node.
  • In page.tpl.php: $content now does NOT contain the nodes. It contains some other things like pagination..etc

Be aware that this snippet doesn't really give you any difference if you didn't adjust your page.tpl.php to exploit the extra flexibility of having nodes as an array. Some examples of doing neat things with $nodes array can be found after the snippet below.

Here comes the PHP snippet, place this in your template.php:

<?php
  
function yourtheme_node($node, $teaser = 0, $page = 0) {
 
set_themed_node(phptemplate_node($node, $teaser, $page));
}  
 
function
set_themed_node($node = NULL) {
  static
$themed_nodes;
  if (
$node) {
   
$themed_nodes[] = $node;
  }
  else {
    return
$themed_nodes;
  }
}    
     
function
_phptemplate_variables($hook, $vars) {
 
$myvars = array();
  switch (
$hook) {
    case
'page':
     
$myvars['nodes'] = set_themed_node();
      break;
  }
  return
$myvars;
}
?>

Then in page.tpl.php, add

<?php
print implode($nodes);
?>
just before
<?php
print $contents;
?>

Just to be sure, here is how page.tpl.php should look...
      <snip>...

      <div id="main">
        <?php print $breadcrumb ?>
        <h1 class="title"><?php print $title ?></h1>
        <div class="tabs"><?php print $tabs ?></div>
        <?php print $help ?>
        <?php print $messages ?>
        <?php print implode($nodes);  // <<< this is our new line ?>
        <?php print $content; ?>
      </div>

      <snip>...

So now the result is not different from before. But it's different in your page.tpl.php, as you have the new $nodes array. If you are reading this, it's likely you know what you want to do with this already :-)

However, here are some example(s). All examples assumes you have added the snippet above to your template.php of course. And oh, If you did something useful with this snippet, post it in comments and it will be added as in example below.

Example: two-column node listing

Let's try to do a two-column listing of nodes. We have $nodes as an array, so our approach will be to divide this into two halfs, and print each in a column. We will use <div class="nodes-left">..</div> to contain our left column nodes. And <div class="nodes-right">..</div> to contain right column nodes. A few lines of CSS will be added, to actually style these divs right and left.

Here is how we do this, in page.tpl.php, remove the line <?php print implode($nodes); ?> and add the following instead:

<?php
$nodes_left
= '';
$nodes_right = '';
foreach (
$nodes as $key => $mynode) {
  if (
$key % 2) {
   
$nodes_left .= $mynode;
  }
  else {
   
$nodes_right .= $mynode;
  }
}
?>


<div class="nodes-left"><?php print $nodes_left; ?></div>
<div class="nodes-right"><?php print $nodes_right; ?></div>

That's it, now we just need the CSS to actually align each div on both sides. So add this to your style.css:

div.nodes-left, div-nodes-right {
  float: left;
  width: 50%;
}

This gave me an error in DP6.x

Jay August - June 17, 2009 - 10:51

I'm pretty sure i've done something wrong and will update this when I solved it, for future reference.

warning: Invalid argument supplied for foreach() in /XX/XX/sites/all/themes/XXXX/page-front.tpl.php on line 78.

-= Jay August =-
Freelance Web Designer, Drupal Fanboy and WordPress Expert

DP6 how?

gadehans - October 4, 2009 - 21:00

How is this done in DP6? I tried overriding the function phptemplate_preprocess_page() in template.php but had no luck getting the nodes into an array.

 
 

Drupal is a registered trademark of Dries Buytaert.