How to Completely Customize Widgets (2.x builds only)

Published on: November 17, 2011 |Tags: ,, | Categories: Tutorial

Note: most of this tutorial and the code provided here applies to the 2.x code base and will not be applicable in 3.x

Some time ago I posted this tutorial on how to show featured thumbnails for the Next Events widget. Then someone asked: “Is there a way to make this occur for only the first event?”. Yes there is, but it requires some further customization of the widgets (which will be helpful to point out here in general) since it will apply to all widgets and give you more customization control over them.

Basically what we need to do is unregister an already registered widget, copy the code for that widget and make our modifications and then register our copy in place of the other widget.

Full functions.php Source: http://pastebin.com/cuYhhXWz 

Full widget-featured-display.php Source: http://pastebin.com/UqvxU0uk

Unregister The Widget

This is slightly different depending on how the widget is registered. In some cases you will want to use this code:

function remove_widgets() {
unregister_widget('TheClassNameOfMyWidget');
}
add_action( 'widgets_init', 'remove_widgets', 11 );

In this particular case to unregister the Next Events widget you’ll want to use:

remove_action( 'widgets_init', 'events_calendar_load_featured_widget',100);

Since that action is added to add the widget, you want to remove the action. If you’re wanting to unregister another widget you’ll just want to look through the widget code to see how it was added and adjust accordingly. Note that when using the unregister function you’ll need to get the classname of the registered widget in the widget code.

Place this code in your functions.php file or as a separate include to keep things organized. If you save functions.php at this point and go back to your Widgets page in WordPress you should notice the Next Events widget is gone. Don’t worry, we’re going to add it back :)

Copy the Original Widget Code

For the Next Events widget this can be found in plugins/events=calendar-pro/lib/widget-featured.class.php - open the file and copy the entire contents.

Paste Widget Code

Paste the code into your functions.php file or your separate include above or below the above code.

Make it Your Own Widget

At the top of the widget code you’ll see the class declaration for the widget that identifies the widget throughout WordPress. Change the following lines:

if( !class_exists( 'TribeEventsFeatureWidget') ) {
class TribeEventsFeatureWidget extends WP_Widget {
function TribeEventsFeatureWidget() {

to:

if( !class_exists( 'CustomTribeEventsFeatureWidget') ) {
class CustomTribeEventsFeatureWidget extends WP_Widget {
function CustomTribeEventsFeatureWidget() {

You’ll also see this line towards the top of the widget code:

$this->WP_Widget('next_event', __('Next Event Widget'), $widget_ops);

..,which declares the widgets name as it appears in WordPress. Change ‘Next Event Widget’ to ‘Custom Next Event Widget’ or how ever else you want it to appear.

Remove Unnecessary Code

Scroll to the bottom of the widget code and remove the following:

/* Add function to the widgets_ hook. */
// hook is commented out until development is finished, allows WP's default calendar widget to work
add_action( 'widgets_init', 'events_calendar_load_featured_widget',100);
//add_action( 'widgets_init', 'get_calendar_custom' );
//function get_calendar_custom(){echo "hi";}
/* Function that registers widget. */
function events_calendar_load_featured_widget() {
register_widget( 'TribeEventsFeatureWidget' );
// load text domain after class registration
load_plugin_textdomain( 'tribe-events-calendar-pro', false, basename(dirname(dirname(__FILE__))) . '/lang/');
}

This will prevent conflicts with the existing widget code.

Register Your Widget

You’ve unregistered the default widget and copied the code from it. Now you need to register your copy. Simply paste the following code into functions.php or your include:

function activate_of_widgets() {
register_widget( 'CustomTribeEventsFeatureWidget' );
}
add_action( 'widgets_init', 'activate_of_widgets' );

Make Your Modifications

As I stated in the beginning a forum user asked if they can only display the featured thumbnail for the first Next Event post. We’ve got to make a few modifications to our widget code now to achieve this functionality. First, the Next Event widget only pulls in the one next event post so we’ll want to change this to pull in more than one post. Look for this function in your widget code:

if( function_exists( 'tribe_get_events' ) ) {
$posts = tribe_get_events( 'eventDisplay=upcoming&numResults=1&eventCat=' . $category );
$template = TribeEventsTemplates::getTemplateHierarchy('widget-featured-display');
}

And change ‘numResults’ to -1 instead of 1 which will bring in all events (or change it to however many you want to bring in (2, 3, 4, 5, etc.). So the code should now look like:

if( function_exists( 'tribe_get_events' ) ) {
$posts = tribe_get_events( 'eventDisplay=upcoming&numResults=-1&eventCat=' . $category );
$template = TribeEventsTemplates::getTemplateHierarchy('widget-featured-display');
}

The next step is we need to add a counter to determine what event we’re looking at so we can conditionally only show the Featured Thumbnail for the first event in the list. Find the following in your widget code:

if ( $posts ) {
/* Display list of events. */
foreach( $posts as $post ) :
setup_postdata($post);
include $template;
endforeach;
}

And change to:

if ( $posts ) {
/* Display list of events. */
$i = 0;
foreach( $posts as $post ) :
setup_postdata($post);
include $template;
endforeach;
}

…adding a variable with which to count by.

Update the View Template

Next we need to go into our actual widget view template which I covered in this (http://tri.be/how-to-show-featured-thumbnails-in-the-next-events-widget/) tutorial. If you don’t know what I’m talking about then go read that tutorial first to setup that file.

In widget-featured-display.php we need to now look at the counter variable we declared in our widget code and see if we’re on the first record and display the thumbnail code if we are and if not remove the thumbnail code. To do that we just need to use an if statement to check if the counter variable is 0 (on the first record), then display the event details with the featured thumbnail or else just display the event details. So it would look something like this:

<?php if($i == 0) { ?>

<div class="event">
	<?php if(has_post_thumbnail($post->ID, 'thumbnail')):
   	$image_id = get_post_thumbnail_id($post->ID);
   	$image_url = wp_get_attachment_image_src($image_id, 'thumbnail', true); ?>
		<a href="<?php echo get_permalink($post->ID) ?>" class="post-thumb"><img src="<?php echo $image_url[0]; ?>" alt="<?php echo $post->post_title ?>" /></a>
	<?php endif; ?>
	<a href="<?php echo get_permalink($post->ID) ?>"><?php echo $post->post_title ?></a>
</div>
<div class="when">
	<?php
		echo tribe_get_start_date( $post->ID, isset($start) ? $start : null );

		if($event->AllDay && $start)
			echo ' <small>('.__('All Day','tribe-events-calendar-pro').')</small>';
	?>
</div>
<div class="loc">
	<?php
		if ( tribe_get_city() != '' ) {
			echo tribe_get_city() . ', ';
		}
		if (tribe_get_region() != '') {
			echo tribe_get_region() . ', ';
		}
		if (tribe_get_country() != '') {
			echo tribe_get_country();
		}
	?>
</div>
<div class="event_body">
	<?php the_content('... More');?>
</div>
<?php $alt_text = ( empty( $alt_text ) ) ? 'alt' : ''; ?>

 <?php } else { ?>

 <div class="event">
	<a href="<?php echo get_permalink($post->ID) ?>"><?php echo $post->post_title ?></a>
</div>
<div class="when">
	<?php
		echo tribe_get_start_date( $post->ID, isset($start) ? $start : null );

		if($event->AllDay && $start)
			echo ' <small>('.__('All Day','tribe-events-calendar-pro').')</small>';
	?>
</div>
<div class="loc">
	<?php
		if ( tribe_get_city() != '' ) {
			echo tribe_get_city() . ', ';
		}
		if (tribe_get_region() != '') {
			echo tribe_get_region() . ', ';
		}
		if (tribe_get_country() != '') {
			echo tribe_get_country();
		}
	?>
</div>
<div class="event_body">
	<?php the_content('... More');?>
</div>
<?php $alt_text = ( empty( $alt_text ) ) ? 'alt' : ''; ?>

 <?php }
 $i++;
 ?>

Conclusion

That’s about it! You should now only see the thumbnail for the first event displayed in the widget.

Unregistering and registering your own copies of widgets can be super helpful in general because if there’s certain functionality in a plugins widget you want, you don’t have to modify the core and worry about losing your changes when there are updates to that plugin. You simply make a copy of the widget code, unregister the widget you copied from and register your own copy with your changes!

If you have any questions, hit me up in the comments :)

Full functions.php Source: http://pastebin.com/cuYhhXWz

Full widget-featured-display.php Source: http://pastebin.com/UqvxU0uk

2 Responses to How to Completely Customize Widgets (2.x builds only)

  1. Anders says

    How do I remove the borders around a picture using Image Widget in by sidebar?????

    • Rob La Gatta says

      Hey Anders. Is this related to Image Widget’s interaction with the Events Calendar PRO plugin, or something unrelated? If not calendar-related and specific to the Image Widget…it’d be awesome if you could post on that plugin’s forum (http://wordpress.org/tags/image-widget?forum_id=10) so we can address the issue that way.

      Thanks in advance!