So I am trying to get some customize aggregator content on my site, howver I am having some problems theming the module. The aggregator module has a theme_aggregator_page_item hook, which allows me to create an aggregator_page_item.tpl.php file in my theme folder. I am using PHPTemplate by the way. I activate this theme file by modifying my template.php file. Everything works fine, except for the fact that now each time the theme_aggregator_page_item function is called in the aggregator.module, I get a new date. So my page looks like:

Date1
News Item
Date1
News Item
Date1
News Item
Date2
News Item

Instead of :
Date1
News Item
News Item
News Item
Date 2
News Item

I know why this is hapening. It is because in my aggregator_page_item.tpl.php file there is a bit of code that isn't working. Here is the file:

  static $last;

  $date = date('Ymd', $item->timestamp);
  if ($date != $last) {
    $last = $date;
    $output .= '<h3>'. date('F j, Y', $item->timestamp) ."</h3>\n";
  }

  $output .= "<div class=\"news-item\">\n";
  $output .= ' <div class="date">'. date('H:i', $item->timestamp) ."</div>\n";
  $output .= " <div class=\"body\">\n";
  $output .= "  <div class=\"title\"><a href=\"$item->link\">$item->title</a></div>\n";
  if ($item->description) {
    $output .= "  <div class=\"description\">$item->description</div>\n";
  }
  if ($item->ftitle && $item->fid) {
    $output .= '  <div class="source">'. t('Source') .': '. l($item->ftitle, "aggregator/sources/$item->fid") ."</div>\n";
  }

  $result = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = %d ORDER BY c.title', $item->iid);
  $categories = array();
  while ($category = db_fetch_object($result)) {
    $categories[] = l($category->title, 'aggregator/categories/'. $category->cid);
  }
  if ($categories) {
    $output .= '  <div class="categories">'. t('Categories') .': '. implode(', ', $categories) ."</div>\n";
  }

  $output .= " </div>\n";
  $output .= "</div>\n";

  echo $output;

The problem is that the $last variable doesn't seem to get passed through the themeing functions of the aggregator module. Is there anyway to fix this WITHOUT hacking the aggregator module?

If I must I guess I will make changes in the aggregator module, but I would rather just work in the theme fucntions.

thanks

Comments

Boris Mann’s picture

Rather than duplicate theme_XXX, you actually just need to pass the variables to the phptemplate template, via the callback. All the logic can be taken care of in template.php, and the tpl.php only has to do conditionals and output the structural HTML.

I re-did how to do this properly. First, here is what should be in your template.php:

function phptemplate_aggregator_page_item($item) {

  static $last;
  $date = date('Ymd', $item->timestamp);

  if ($date != $last) {
    $last = $date;
  }
  
  $result = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = %d ORDER BY c.title', $item->iid);
  $categories = array();
  while ($category = db_fetch_object($result)) {
    $categories[] = l($category->title, 'aggregator/categories/'. $category->cid);
  }
  
  return _phptemplate_callback('aggregator_page_item', array('last' => $last, 'date' => $date, 'categories' => $categories, 'item' => $item)); 
  
}

Notice how the callback passes all the variables that are needed for the template file. Now, here is an example aggregator_page_item.tpl.php:

<h3><?php print date('F j, Y', $item->timestamp) ?></h3>
<?php endif; ?>
<div class="news-item">
  <div class="date"><?php print date('H:i', $item->timestamp); ?></div>
  <div class="body">
  <div class="title"><a href="/<?php print $item->link ?>"><?php print $item->title ?></a></div>
<?php if ($item->description): ?>
  <div class="description"><?php print $item->description ?></div>
<?php endif; ?>
<?php if ($item->ftitle && $item->fid): ?>
  <div class="source">Source: <?php print l($item->ftitle, "aggregator/sources/$item->fid") ?></div>
<?php endif; ?>
<?php  if ($categories) : ?>
<div class="categories">Categories: <?php print implode(', ', $categories) ?></div>
<?php endif; ?>
 </div>
</div>

Note: not tested live, but you should get the general idea from that.

bryan kennedy’s picture

Okay, thanks. I din't realize that was how the template.php file worked. If I get this working, I might make some updates to the Handbook page describing this. I wasn't able to figure this out from the current handbook page about this. I will try this out and post back with my results.

-cheers

bryan kennedy’s picture

So I tried this out but the template.php file produced an error.

Parse error: parse error in myfilepath/template.php on line 2

So i figured i needed to add 'function' before phptemplate_aggregator_page_item($item). So the begining looks like this

 function phptemplate_aggregator_page_item($item) {
  static $last;

This eliminates the error but does not fix my original problem. The $last variable is still not getting pased to the different aggregator_page_itme.tpl.php calls. I even put an echo $last in the aggregator_page_itme.tpl.php and it was blank.

Does this have something to do with the static command? I haven't a clue as to what this does. I can't find any documentation on this command anywhere (php.net, drupaldocs.org, google).....

Sorry to be so helpless.

Boris Mann’s picture

I updated the "function" -- forgot about that (Like I said, I haven't actually looked at the function live).

I also realized that yeah, the date vs. last check was happening in the wrong place. I updated the code as well. It might work, but basically, you need to trace the logic of how $last is being used -- see if you can understand the flow in the original.

freyquency’s picture

i'm just posting so i can track this...

media girl’s picture

This retemplating of the aggregator is very exciting to me for a project I have in the works.
--
mediagirl.org

Boris Mann’s picture

Archangel pointed out that if you don't want to create a .tpl.php file, you can just build up a string inside the customized function in template.php instead of doing the return _phptemplate_callback (i.e. you would just do a return $output).

This would be appropriate for 1) small functions where having to create yet another file would be overkill and 2) outputs that involve a high degree of code logic or other PHP-based output.

This part of the aggregator theme might qualify for (2).

Sverre’s picture

The above example didn't work for me (Drupal 4.7) so I had a closer look and made a few changes to get it working...

I placed this code in my template.php:

<?php
function phptemplate_aggregator_page_item($item) {
  static $last;
  $date = date('l, jS F Y', $item->timestamp);
  if ($date != $last) {
    $newdate = TRUE;
    $last = $date;
  } else {
    $newdate = FALSE;
  }
  $result = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = %d ORDER BY c.title', $item->iid);
  $categories = array();
  while ($category = db_fetch_object($result)) {
    $categories[] = l($category->title, 'aggregator/categories/'. $category->cid);
  }
  return _phptemplate_callback('aggregator_page_item', array('newdate' => $newdate, 'date' => $date, 'categories' => $categories, 'item' => $item));
}
?>

And created a new aggregator_page_item.tpl.php containing this code:

<div class="news-item">
  <?php if ($newdate) { ?>
    <h3><?php print $date ?></h3>
  <?php } ?>
  <div class="date"><?php print date('H:i', $item->timestamp); ?></div>
  <div class="body">
    <div class="title"><a href="/<?php print $item->link ?>"><?php print $item->title ?></a></div>
    <?php if ($item->description): ?>
      <div class="description"><?php print $item->description ?></div>
    <?php endif; ?>
    <?php if ($item->ftitle && $item->fid): ?>
      <div class="source">Source: <?php print l($item->ftitle, "aggregator/sources/$item->fid") ?></div>
    <?php endif; ?>
    <?php  if ($categories) : ?>
      <div class="categories">Categories: <?php print implode(', ', $categories) ?></div>
    <?php endif; ?>
  </div>
</div>

A bit of CSS theming and it works and looks great! Thanks Boris for getting most of the way there.

kingandy’s picture

I just wanted to mention that this still works under 5.x ... also that it is much appreciated!

++Andy
Developing Drupal websites for Livelink New Media since 2008

Slim Pickens’s picture

Thanks Sverre - this worked in Aggregator in ver 5.

However I did need to to tweek the item link as follows

<div class="news-item">
  <?php if ($newdate) { ?>
    <h3><?php print $date ?></h3>
  <?php } ?>
  <div class="date"><?php print date('H:i', $item->timestamp); ?></div>
  <div class="body">
    <div class="title"><a href=<?php print $item->link ?>><?php print $item->title ?></a></div>
    <?php if ($item->description): ?>
      <div class="description"><?php print $item->description ?></div>
    <?php endif; ?>
    <?php if ($item->ftitle && $item->fid): ?>
      <div class="source">Source: <?php print l($item->ftitle, "aggregator/sources/$item->fid") ?></div>
    <?php endif; ?>
    <?php  if ($categories) : ?>
      <div class="categories">Categories: <?php print implode(', ', $categories) ?></div>
    <?php endif; ?>
  </div>
</div>
parakeet’s picture

I'm a new user still grasping some of these comments, so can I just ask you to clarify how you theme or mess about with the HTML for aggregator output?

many thanks