Example - Theme all-day events without a time.
Here's an example of how to apply the theme_date_display_combination override.
In this example, we want to:
- Theme "all-day events" so the time is not shown (users set time to 0:00 to indicate all day*)
- Theme "multi-day all-day events" so they show, for example, Jan. 1 - 5, 2008 or Jan. 28 - Feb. 2, 2008
- Theme "single-day, multi-time events" so they show, for example, Tues. Jan. 1 - 11:00 am - 2:30 pm
(* From a usability perspective, it would be better to add a CCK checkbox field for all-day events, and then utilize that here - this can be done fairly easily and is left as an exercise...)
The primary difficulty here is that the dates are already formatted when we get them. A more elegant solution could be achieved by overriding the theme_date_formatter() function - but that is beyond the scope of this tutorial, which provides a simpler (but slightly "hack'ish") approach.
To this end, I need to make 2 assumptions (be sure they apply to you!):
- All date formats used will specify a dash, - , to separate the time from the date. Most date formats do this, but not all. Check the comments in the code for the places this is important.
- For "multi-day all-day events" you never want to show the Day name. Thus, the format for this type of date is fixed in the code - the admin settings for date formats are totally ignored for these types of events.
The original idea for this example came from: http://drupal.org/node/211668
This code goes into your template.php file.
function phptemplate_date_display_combination($field, $dates, $node = NULL) {
// If there is no From date - get out...
if (empty($dates['value']['formatted'])) {
return;
}
$date1 = $dates['value']['object']->db; // the "From" date
$date2 = $dates['value2']['object']->db; // the "To" date
// Same From and To Date and Time, don't consider the To date...
if ($date1->timestamp == $date2->timestamp) {
unset($date2);
}
$sameDay = $date1->parts['year'] == $date2->parts['year'] &&
$date1->parts['yday'] == $date2->parts['yday'];
$sameTime = $date1->parts['hours'] == $date2->parts['hours'] &&
$date1->parts['minutes'] == $date2->parts['minutes']; // to the nearest minute
// All day events have only a from date with a time of 0:00
$allDay = (empty($date2) && !_isTimeSet($date1));
// All day, multi-day events have both times set to 0:00
$multiDay = !_isTimeSet($date1) && !empty($date2) && !_isTimeSet($date2);
$sameMonth = $date1->parts['mon'] == $date2->parts['mon'];
if ($allDay) { //this is an all day, single-day event
// Assumption 1: stripping time off formatted date based on location of dash!
$dashPos = strpos($dates['value']['formatted'],'-'); // find start of time portion
$formattedDate= substr($dates['value']['formatted'],0,$dashPos); // strip off time
// Here is an alternate that hard-codes the date format (Jan. 1, 2008)
// $formattedDate = date('F j, Y', $date1->timestamp);
return '<span class="date-display-single">'. $formattedDate .'</span>';
}
elseif ($multiDay) { //this is an all day, multi-day event
// Assumption 2: The date formats here are hard-coded....
$startDate = date('F j', $date1->timestamp);
$endFormat = ($sameMonth?'j, Y':'F j, Y');
$endDate = date($endFormat, $date2->timestamp);
return _theme_date_range($startDate, $endDate);
}
elseif ($sameDay && !$sameTime) { //this is a single day, multi-time event
$startDate = $dates['value']['formatted'];
$date = $dates['value2']['formatted'];
$dashPos = strpos($date,'-'); // find start of time portion
$endDate= substr($date, $dashPos+2, strlen($date)); // grab just the time
// Here is an alternate that hard-codes the end time format (2:30pm)
// $endDate = date('g:ia', $date2->timestamp);
return _theme_date_range($startDate, $endDate);
}
else { //single day/time event or multi-day/multi time event - let default themer do it
return theme_date_display_combination($field, $dates, $node);
}
}
/**
* Helper to determine if the time for a given date is set to 0:00
* Returns true if a 'valid' time is set, false if time is 0:00
*/
function _isTimeSet($date) {
return $date->parts['hours']!=0 || $date->parts['minutes']!=0; // to nearest minute only
}
/**
* Helper function to theme a pair of dates as: StartDate - EndDate
* Note extra class added : date-display-short-end
* This can be used to override the default CSS, which puts a line-break between dates.
*/
function _theme_date_range($startDate, $endDate) {
return '<span class="date-display-start">'. $startDate .
'</span><span class="date-display-separator"> - </span><span class="date-display-end date-display-short-end">'.
$endDate .'</span>';
}
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion