Download & Extend

content_format() does not work on Date CCK fields

Project:Date
Version:6.x-2.x-dev
Component:Date Field
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs review

Issue Summary

I have a date field with both from and to values and number of values = 1, and I have to print the field separately from the node template. So in "display values" settings I have "exclude" checkbox turned on for the field.
However, I found that printing the field using content_format() function like I'm used to doesn't work. After some troubleshooting I've found that theme_date_display_combination() has a bug inside (or it's too smart to be a generic function). It has following block of code:

<?php
 
// If this is a full node or a pseudo node created by grouping
  // multiple values, see exactly which values are supposed to be visible.
 
if (isset($node->$field_name)) {
   
$node = date_prepare_node($node, $field, $type_name, $context, $options);
   
// Did the current value get removed by formatter settings?
   
if (empty($node->{$field_name}[$item['#delta']])) {
      return
$output;
    }
   
// Adjust the $element values to match the changes.
   
$element['#node'] = $node;
  }
?>

I've found that in my case $item array doesn't have "#delta" key, so the function terminates without printing anything.

Comments

#1

Component:Date CCK Field» Date Field

I found the same exact bug, and did a backtrace to find where exactly the $item['#delta'] comes from -- and therefore, why it isn't appearing in our $item.

First, my use case:

I'm pulling up a node through node_load() and rendering the field like this:

<?php
  $node
= node_load($nid);
  return
content_format('field_date', $node->field_date[0], 'default', $node);
?>

Second, the problem:

$item['#delta'] is actually first set in the following code snippet from content_field($op='view'):

<?php
 
if ($single) {
    foreach (
$items as $delta => $item) {
     
$element['items'][$delta] += $format_info;
     
$element['items'][$delta]['#item']['#delta'] = $delta;
    }
  }
?>

This content_field($op='view') is called in only two places (as far as I can tell).

First place that content_field($op='view') is called:

Second place that content_field($op='view') is called:

Could we fix our problem by calling content_view_field() or content_view() instead? No, because:

  1. content_view_field() requires the field definition, and we don't have the field definition when we're pulling it in through node_load().
  2. Implementations of hook_nodeapi($op='view') are only triggered when the page is actually being loaded for viewing -- not through node_load().
  3. Either way, it is painfully inefficient to trigger content_field($op='view') in some applications -- especially when it's going to be needed over multiple nodes.

So, we need to accept that there are legitimate use cases where $item['#delta'] will not be set.

Finally, the solution:

Checking if isset($item['#delta']) ought to be sufficient to avoid the unwanted triggering of the return $output; in the next line. That's what the attached patch does.

AttachmentSizeStatusTest resultOperations
date-theme-bug-811216-1.patch598 bytesTest request sentNoneView details

#2

Status:active» needs review

Marking as needs review.

#3

Title:Bug in the theme_date_display_combination() causes content_format() to not work for Date CCK fields.» content_format() does not work on Date CCK fields

Updating the title to be simpler and more to the point.

#4

patch in #1 works for me

#5

I can also confirm that this resolves the issue presented.

Applied the patch from #1 and added the following to theme_preprocess_node

<?php
$vars
['event_times'] = content_format('field_event_datetime', $vars['field_event_datetime'][0], 'default', $vars);
?>