Hi,

I have recently created a new website for which I had to choose between Drupal and Mambo, I'm very glad I chose the former, but there is one thing that was straight forward with Mambo that I've not been able to do with Drupal yet: personalize how lists of nodes are being presented. Note that I do not necessarily want to change the template of each node.

For example, I would like to present the first item highlighted with a background behind, the next four would be shown in two columns and for all others I just want to show a list of its titles instead of the whole teaser.

I've developed a PHPTemplate theme and have reviewed several example themes for inspiration. I've also read all the documentation about it that I have been able to find, including the discussions about the new theme system. As a result I think I understand how it should be done, but browsing through the list of themeable functions[1] I don't find any of them which allows me to control how the list of nodes is iterated. So my questions are: is there such a function? If not, is it possible to obtain information about the iteration context within node.tpl.php? If so, how? If not, is it possible to achieve what I want in Drupal in any other way?

Thanks in advance,
Jorge

BTW, I'm using Drupal 4.6.3 with Apache and MySQL

[1] http://drupaldocs.org/api/head/group/themeable

Comments

nevets’s picture

It would depend on the context, the list generated from the path node is different from the one generated by taxonomy/term/1 for example.

For the case of the path = node, you would need to modify the code in node.module, not sure about taxonomy.

If you control the context, i.e you can create a page to do what you want, you could do this will some custom code. If you look at http://thesavvyshopperclub.co.uk/savvy/ under 'latest updates' this is similiar to what you are looking for. It could be modified to do what you want.

jferrer’s picture

Thanks nevets, that's exactly what I needed. I've been looking through the code of node.module but I'm not sure where I should add my custom code. There is a function that says:

function theme_node_list($items, $title = NULL) {
  return theme('item_list', $items, $title);
}

which seems the right place, but it uses the item_list themeable function which I think is not really being called when listing nodes. I'm confused, could you help me some more? Which is the function I should modify?

BTW, is there any good reason for not having a themeable function or it is just that nobody has coded it yet?

nevets’s picture

The function that produces the default from page is node_page_default() and is found in node.module. Note this does not cover all lists of node content. The taxonomy module for example also produces lists of node.

To some degree the list is already themed, but at a higher level than you want. It themes each node separately and "pastes" the resulting them togther. What you really want is theming at the level where the theme function gets a list/array of nodes and formats the list from there.

In terms of the code where it combines node_view() and node_load(), you will probably want to use node_load() to load the node and then decide to use node_load() if printing the teaser/content or just build a title link from the node date.

Simon Lehmann’s picture

That's exactly the same thing I wanted to do in my theme.

I did a lot of code digging before I found out that theming of node lists isn't possible without modifying the code.

The modification I did so far is only in the taxonomy.module. I did it somewhere around line 850 where the function taxonomy_render_nodes() starts. This function is responsible for the node list generation, but it doesn't provide any theme hooks. So I just modified it and added a theme hook, which resulted in this code so far:

/**
 * Accepts the result of a pager_query() call, such as that performed by
 * taxonomy_select_nodes(), and formats each node along with a pager.
*/
function taxonomy_render_nodes($result) {
  if (db_num_rows($result) > 0) {
    while ($node = db_fetch_object($result)) {
      $nodes[] = node_load(array('nid' => $node->nid));
    }
    $output = theme('taxonomy_node_list', $nodes);
    $output .= theme('pager', NULL, variable_get('default_nodes_main', 10), 0);
  }
  else {
    $output .= t('There are currently no posts in this category.');
  }
  return $output;
}

/**
 * THIS FUNCTION WAS ADDED TO MAKE THE LISTS THEMEABLE
 * Formats the listing of nodes generated by taxonmy_render_nodes()
 */
function theme_taxonomy_node_list($nodes = array()) {
  foreach ($nodes as $node) {
    $output .= node_view($node, 1);
  }
  return $output;
}

With this, you have the whole node objects availible to your templates, which gives you great control about how the list will look.

This solution doesn't break any existing themes, it just separates the display from the logic. This is not hard to do, but I think it might be useful for anyone who is trying to theme these lists.