Skip to content
View in the app

A better way to browse. Learn more.

Web Designer Forum

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[WordPress] Custom Calendar Widget

Featured Replies

Hi there,

 

I'm trying to customise the output of the calendar widget in WordPress, because I'm not quite happy with the default table structure which I've been hoping for months they would improve.

 

I started to play around and customise the output by myself using a filter so I can use it in my theme's functions file. However I have a very little knowledge of PHP and I was hoping someone could help me here.

 

Reading my code there is nothing wrong I can see... Although I don't get any error message, the function breaks my entire blog page. Here is the code I'm including in my functions file below:

 

<?php
function my_calendar($initial = true, $echo = true) {
global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;
$cache = array();
$key = md5( $m . $monthnum . $year );
if ( $cache = wp_cache_get( 'get_calendar', 'calendar' ) ) {
 if ( is_array($cache) && isset( $cache[ $key ] ) ) {
  if ( $echo ) {
   echo apply_filters( 'get_calendar',  $cache[$key] );
   return;
  } else {
   return apply_filters( 'get_calendar',  $cache[$key] );
  }
 }
}
if ( !is_array($cache) )
 $cache = array();
// Quick check. If we have no posts at all, abort!
if ( !$posts ) {
 $gotsome = $wpdb->get_var("SELECT 1 as test FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 1");
 if ( !$gotsome ) {
  $cache[ $key ] = '';
  wp_cache_set( 'get_calendar', $cache, 'calendar' );
  return;
 }
}
if ( isset($_GET['w']) )
 $w = ''.intval($_GET['w']);
// week_begins = 0 stands for Sunday
$week_begins = intval(get_option('start_of_week'));
// Let's figure out when we are
if ( !empty($monthnum) && !empty($year) ) {
 $thismonth = ''.zeroise(intval($monthnum), 2);
 $thisyear = ''.intval($year);
} elseif ( !empty($w) ) {
 // We need to get the month from MySQL
 $thisyear = ''.intval(substr($m, 0, 4));
 $d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
 $thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('{$thisyear}0101', INTERVAL $d DAY) ), '%m')");
} elseif ( !empty($m) ) {
 $thisyear = ''.intval(substr($m, 0, 4));
 if ( strlen($m) < 6 )
   $thismonth = '01';
 else
   $thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
} else {
 $thisyear = gmdate('Y', current_time('timestamp'));
 $thismonth = gmdate('m', current_time('timestamp'));
}
$unixmonth = mktime(0, 0 , 0, $thismonth, 1, $thisyear);
$last_day = date('t', $unixmonth);
// Get the next and previous month and year with at least one post
$previous = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
 FROM $wpdb->posts
 WHERE post_date < '$thisyear-$thismonth-01'
 AND post_type = 'post' AND post_status = 'publish'
  ORDER BY post_date DESC
  LIMIT 1");
$next = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
 FROM $wpdb->posts
 WHERE post_date > '$thisyear-$thismonth-{$last_day} 23:59:59'
 AND post_type = 'post' AND post_status = 'publish'
  ORDER BY post_date ASC
  LIMIT 1");
/* translators: Calendar caption: 1: month name, 2: 4-digit year */
$calendar_caption = _x('%1$s %2$s', 'calendar caption');
$calendar_output = '<h2>' . sprintf($calendar_caption, $wp_locale->get_month($thismonth), date('Y', $unixmonth)) . '</h2>
<ul class="weekdays">';
$myweek = array();
for ( $wdcount=0; $wdcount<=6; $wdcount++ ) {
 $myweek[] = $wp_locale->get_weekday(($wdcount+$week_begins)%7);
}
foreach ( $myweek as $wd ) {
 $day_name = (true == $initial) ? $wp_locale->get_weekday_initial($wd) : $wp_locale->get_weekday_abbrev($wd);
 $wd = esc_attr($wd);
 $calendar_output .= "\n\t\t<li title=\"$wd\">$day_name</li>";
}
$calendar_output .= '
</ul>
<ul class="days">';
// Get days with posts
$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
 FROM $wpdb->posts WHERE post_date >= '{$thisyear}-{$thismonth}-01 00:00:00'
 AND post_type = 'post' AND post_status = 'publish'
 AND post_date <= '{$thisyear}-{$thismonth}-{$last_day} 23:59:59'", ARRAY_N);
if ( $dayswithposts ) {
 foreach ( (array) $dayswithposts as $daywith ) {
  $daywithpost[] = $daywith[0];
 }
} else {
 $daywithpost = array();
}
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || stripos($_SERVER['HTTP_USER_AGENT'], 'camino') !== false || stripos($_SERVER['HTTP_USER_AGENT'], 'safari') !== false)
 $ak_title_separator = "\n";
else
 $ak_title_separator = ', ';
$ak_titles_for_day = array();
$ak_post_titles = $wpdb->get_results("SELECT ID, post_title, DAYOFMONTH(post_date) as dom "
 ."FROM $wpdb->posts "
 ."WHERE post_date >= '{$thisyear}-{$thismonth}-01 00:00:00' "
 ."AND post_date <= '{$thisyear}-{$thismonth}-{$last_day} 23:59:59' "
 ."AND post_type = 'post' AND post_status = 'publish'"
);
if ( $ak_post_titles ) {
 foreach ( (array) $ak_post_titles as $ak_post_title ) {
   $post_title = esc_attr( apply_filters( 'the_title', $ak_post_title->post_title, $ak_post_title->ID ) );
   if ( empty($ak_titles_for_day['day_'.$ak_post_title->dom]) )
 $ak_titles_for_day['day_'.$ak_post_title->dom] = '';
   if ( empty($ak_titles_for_day["$ak_post_title->dom"]) ) // first one
 $ak_titles_for_day["$ak_post_title->dom"] = $post_title;
   else
 $ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . $post_title;
 }
}
$daysinmonth = intval(date('t', $unixmonth));
for ( $day = 1; $day <= $daysinmonth; ++$day ) {
 if ( $day == gmdate('j', current_time('timestamp')) && $thismonth == gmdate('m', current_time('timestamp')) && $thisyear == gmdate('Y', current_time('timestamp')) )
  $calendar_output .= '<li id="today">';
 else
  $calendar_output .= '<li>';
 if ( in_array($day, $daywithpost) ) // any posts today?
   $calendar_output .= '<a href="' . get_day_link( $thisyear, $thismonth, $day ) . '" title="' . esc_attr( $ak_titles_for_day[ $day ] ) . "\">$day</a>";
 else
  $calendar_output .= $day;
 $calendar_output .= '</li>';
}
$calendar_output .= '</ul>
<menu>';
if ( $previous ) {
 $calendar_output .= '<a href="' . get_month_link($previous->year, $previous->month) . '" id="prev" class="backwards" title="' . esc_attr( sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($previous->month), date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year)))) . '">' . $wp_locale->get_month_abbrev($wp_locale->get_month($previous->month)) . date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year)) . '</a>';
}
if ( $next ) {
 $calendar_output .= '<a href="' . get_month_link($next->year, $next->month) . '" id="next" class="forwards" title="' . esc_attr( sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($next->month), date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year))) ) . '">' . $wp_locale->get_month_abbrev($wp_locale->get_month($next->month)) . date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year)) . '</a>';
}
$calendar_output .= '</menu>';
$cache[ $key ] = $calendar_output;
wp_cache_set( 'get_calendar', $cache, 'calendar' );
remove_filter( 'get_calendar' , 'my_calendar_filter' );
$output = apply_filters( 'get_calendar',  $calendar_output );
add_filter( 'get_calendar' , 'my_calendar_filter' );
if ( $echo )
 echo $output;
else
 return $output;
}
function my_calendar_filter( $content ) {
$output = my_calendar( '' , '' , false );
return $output;
}
add_filter( 'get_calendar' , 'my_calendar_filter' , 10 , 2 );
?>

 

Someone might already have tried to customised the output of the calendar widget, but I didn't find much online.

 

Please let me know if anyone can help me here :)

 

PS: I also attached my PHP file if you find it more convenient.

my-calendar.php

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.