- Lets start off with some great documentation
- Codex
- Justin Tadlock (guide)
- WP Engineer (guide)
- Simple code is alot easier to inplement when all you have to do is extend the class via a simple API.
- Go ahead and download this widget
- Let me answer your questions. And show you some examples
We are going to add this to our function.php file in your current theme.
register_widget( 'Example_Widget' );
<?php
/* Add our function to the widgets_init hook. */
add_action( 'widgets_init', 'wordcamp_miami_example_widget' );
/* Function that registers our widget. */
function wordcamp_miami_example_widget() {
/* Load the widget file. */
require_once( get_stylesheet_directory() . '/library/classes/widget-example.php' );
register_widget( 'Example_Widget' );
}
?>
New lets create a the file in our theme. We'll put it in the folder /library/classes/.
Since WordPress 2.8, we simply have to extend the pre-existing WP_Widget class. So, the first step is creating a new class with a unique name as shown before. Were still going to use the Example_Widget nme.
<?php
class Example_Widget extends WP_Widget {
Then, we’ll want to add our first function. This function will be what makes our widget unique to WordPress, and it’ll allow us to set up the widget settings. Note that the class name and first function name are the same. In this example this is Example_Widget.
function Example_Widget() {
/* Widget settings. */
$widget_ops = array( 'classname' => 'example', 'description' => 'This widget does nothing, with class!' );
/* Widget control settings. */
$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );
/* Create the widget. */
$this->WP_Widget( 'example-widget', 'Example Widget', $widget_ops, $control_ops );
}
//
The next function within our Example_Widget class will handle the display of the widget.
It’s also important to make sure you use the $before_widget, $after_widget, $before_title, and $after_title variables. These are provided by the theme and should not be hardcoded. How widgets are displayed should always be handled by the theme.
function widget( $args, $instance ) {
extract( $args );
/* User-selected settings. */
$title = apply_filters( 'widget_title', $instance['title'] );
$name = $instance['name'];
$handle = $instance['handle'];
$show_handle = isset( $instance['show_handle'] ) ? $instance['show_handle'] : false;
/* Before widget (defined by themes). */
echo $before_widget;
/* Title of widget (before and after defined by themes). */
if ( $title )
echo $before_title . $title . $after_title;
/* Display name from widget settings. */
if ( $name )
echo '<p>Hello, my name is ' . $name . '.</p>';
/* Show handle. */
if ( $show_handle )
echo '<p>Follow me @<a href="http://twitter.com/' . $handle . '">' . $handle . '</a>.</p>';
/* After widget (defined by themes). */
echo $after_widget;
}
In this step, we’ll take each of our widget settings and save them. It’s a pretty simple procedure. We’re just updating the widget to use the new user-selected values.
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
/* Strip tags (if needed) and update the widget settings. */
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['name'] = strip_tags( $new_instance['name'] );
$instance['handle'] = $new_instance['handle'];
$instance['show_handle'] = $new_instance['show_handle'];
return $instance;
}
First, we might want to set up some defaults. By setting up defaults, we can control what’s shown just in case the user doesn’t select anything.
function form( $instance ) {
/* Set up some default widget settings. */
$defaults = array(
'title' => 'Example Title',
'name' => 'Austin Passy',
'handle' => 'TheFrosty',
'show_handle' => true
);
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
Now we need to output the HTML to control the inputs. The first three parts of the form will be text inputs: the widget title and the users name.
<p> <label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label> <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" /> </p> <p> <label for="<?php echo $this->get_field_id( 'name' ); ?>">Your Name:</label> <input id="<?php echo $this->get_field_id( 'name' ); ?>" name="<?php echo $this->get_field_name( 'name' ); ?>" value="<?php echo $instance['name']; ?>" style="width:100%;" /> </p> <p> <label for="<?php echo $this->get_field_id( 'handle' ); ?>">Your Handle:</label> @<input id="<?php echo $this->get_field_id( 'handle' ); ?>" name="<?php echo $this->get_field_name( 'handle' ); ?>" value="<?php echo $instance['handle']; ?>" style="width:100%;" /> </p>
The last part of the form will show a checkbox that allows the user to select whether they want to display their handle publicly.
<p> <input class="checkbox" type="checkbox" <?php checked( $instance['show_handle'], true ); ?> id="<?php echo $this->get_field_id( 'show_handle' ); ?>" name="<?php echo $this->get_field_name( 'show_handle' ); ?>" /> <label for="<?php echo $this->get_field_id( 'show_handle' ); ?>">Display your handle publicly?</label> </p>
<?php } } ?>
Here is the completed widget with name changes so you can paste a working copy into your functions.php file.
<?php
/**
* Twitter Widget by Austin Passy
* at WordCamp Miami 2011
*
* @link http://austinpassy.com
*
* @since 0.1.0
* @package Twitter Widget
* @subpackage Classes
*/
class WordCamp_MIA_Widget extends WP_Widget {
var $prefix;
var $textdomain;
/**
* Set up the widget's unique name, ID, class, description, and other options.
* @since 0.1.0
*/
function WordCamp_MIA_Widget() {
$widget_ops = array( 'classname' => 'tweet', 'description' => __( 'Displays Your latest tweet.' );
$control_ops = array( 'width' => 200, 'height' => 350, 'id_base' => 'tweet' );
$this->WP_Widget( 'tweet', __( 'Recent Tweet' ), $widget_ops, $control_ops );
}
/**
* Outputs the widget based on the arguments input through the widget controls.
* @since 0.1.0
*/
function widget( $args, $instance ) {
extract( $args );
$handle = esc_attr( $instance['handle'] );
$count = esc_attr( $instance['count'] );
echo $before_widget;
if ( $instance['title'] )
echo $before_title . apply_filters( 'widget_title', $instance['title'] ) . $after_title; ?>
<div class="tweet">
<p><?php echo get_cached_twitter_status( $handle, $count ); ?></p>
<p>@<a href="http://twitter.com/<?php echo $handle; ?>" class="twitter-anywhere-user"><?php echo $handle; ?></a></p>
</div><?php
echo $after_widget;
}
/**
* Updates the widget control options for the particular instance of the widget.
* @since 0.1.0
*/
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance = $new_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['handle'] = strip_tags( $new_instance['handle'] );
$instance['count'] = strip_tags( $new_instance['count'] );
return $instance;
}
/**
* Displays the widget control options in the Widgets admin screen.
* @since 0.1.0
*/
function form( $instance ) {
//Defaults
$defaults = array(
'title' => __( '' ),
'handle' => __( 'TheFrosty' ),
'count' => __( '1' ),
);
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<div class="columns-1">
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'handle' ); ?>"><?php _e( 'Handle:' ); ?></label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id( 'handle' ); ?>" name="<?php echo $this->get_field_name( 'handle' ); ?>" value="<?php echo $instance['handle']; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php _e( 'Count:' ); ?></label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" value="<?php echo $instance['count']; ?>" />
</p>
</div>
<div style="clear:both;"> </div>
<?php
}
}
/**
* Display my recent tweet and chache
* the results for "" minutes.
*
* @ref http://yoast.com/display-latest-tweet/
*/
function get_cached_twitter_status( $handle, $count = '2' ) {
require_once( ABSPATH . 'wp-includes/class-snoopy.php' );
$tweet = get_option( "{$handle}_recent_tweet" );
$url = "http://twitter.com/statuses/user_timeline/{$handle}.json?count={$count}";
if ( $tweet['lastcheck'] < ( mktime() - 400 ) ) {
$snoopy = new Snoopy;
$result = $snoopy->fetch( $url );
if ( $result ) {
$twitterdata = json_decode( $snoopy->results, true );
$i = 0;
while ( $twitterdata[$i]['in_reply_to_user_id'] != '' ) {
$i++;
}
$time = $twitterdata[$i]['created_at']; // Wed Feb 09 17:20:13 +0000
$tweettime = ( strtotime( date() . " " . $time ) ) -8000; // This is the value of the time difference - UK + 1 hours (3600 seconds)
$nowtime = time();
$timeago = ( $nowtime - $time );
$thehours = floor( $timeago/3600 );
$theminutes = floor( $timeago/60 );
$thedays = floor( $timeago/86400 );
/********************* Checking the times and returning correct value */
if ( $theminutes < 60 ) {
if ( $theminutes < 1 ) {
$timemessage = "Less than 1 minute ago";
} else if ( $theminutes == 1 ) {
$timemessage = $theminutes . " minute ago.";
} else {
$timemessage = $theminutes . " minutes ago.";
}
} elseif ( $theminutes > 60 && $thedays < 1 ) {
if ( $thehours == 1 ) {
$timemessage = $thehours . " hour ago.";
} else {
$timemessage = $thehours . " hours ago.";
}
} else {
if ( $thedays == 1 ) {
$timemessage = $thedays . " day ago.";
} else {
$timemessage = $thedays . " days ago.";
}
}
$output = '';
$pattern = '/\@([a-zA-Z]+)/';
$replace = '<a href="http://twitter.com/' . strtolower('\1') . '" rel="nofollow">@\1</a>';
$output .= preg_replace( $pattern, $replace, $twitterdata[$i]["text"] );
//$output .= "<br />\n<span>" . $timemessage . "</span>\n";
$tweet['lastcheck'] = mktime();
$tweet['data'] = $output;
$tweet['rawdata'] = $twitterdata;
$tweet['followers'] = $twitterdata[0]['user']['followers_count'];
update_option( "{$handle}_recent_tweet", $tweet );
} else {
$output = "Twitter API not responding.";
}
} else {
$output = $tweet['data'];
}
return make_clickable( $output );
}
?>