I wanted a widget that displays a list of all the posts displayed on the current page, but I couldn’t find a WordPress widget plugin that would do what I wanted. Ergo sum I’ll build it myself. Here’s a super short tutorial on how to create a WordPress widget plugin.
To accomplish this, we’ll create a plugin that registers a widget. This widget will grab the global $posts
object from WordPress (which contains the posts that are being displayed on the current page), and list their titles in a widget.
Here’s my template code:
<?php
/**
* Plugin Name: My Posts Widget
* Description: A widget that displays a list of all the posts displayed on the current page.
* Version: 1.0
* Author: Your Name
*/
// Register and load the widget
function my_posts_widget_load() {
register_widget( 'my_posts_widget' );
}
add_action( 'widgets_init', 'my_posts_widget_load' );
// Creating the widget
class my_posts_widget extends WP_Widget {
function __construct() {
parent::__construct(
'my_posts_widget',
__('My Posts Widget', 'my_posts_widget_domain'),
array( 'description' => __( 'A widget that displays a list of all the posts displayed on the current page.', 'my_posts_widget_domain' ), )
);
}
// Creating widget front-end
public function widget( $args, $instance ) {
global $posts;
$title = apply_filters( 'widget_title', $instance['title'] );
echo $args['before_widget'];
if ( ! empty( $title ) )
echo $args['before_title'] . $title . $args['after_title'];
// this is where we output the posts
echo '<ul>';
foreach ($posts as $post) {
echo '<li><a href="' . get_permalink($post) . '">' . $post->post_title . '</a></li>';
}
echo '</ul>';
echo $args['after_widget'];
}
// Widget Backend
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'my_posts_widget_domain' );
}
// Widget admin form
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
</p>
<?php
}
// Updating widget replacing old instances with new
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
return $instance;
}
}
Here’s what’s happening in the code:
- We’re creating a new widget with the name “My Posts Widget”. This will appear in the list of available widgets in the WordPress admin dashboard.
- The widget has a title which is editable from the widget settings.
- In the widget method, we’re accessing the global
$posts
variable, which WordPress sets with all the posts being displayed on the current page. - We’re then iterating through each of the posts and adding a link to the post in an unordered list.
To install this plugin, you need to:
- Create a
my-posts-widget
directory. The majority of plugins follow the same pattern re: use of “-” to separate words. - Copy the code above and put it in
my_posts_widget.php
file insidemy-posts-widget
directory. - Compress the
my-posts-widget
directory tomy-posts-widget.zip
. - Go to your WordPress admin dashboard, then go to “Plugins > Add New > Upload Plugin”.
- Choose the
my-posts-widget.zip
file and click “Install Now”. - After installation, activate the plugin by clicking “Activate”.
After you’ve done this, you’ll see a new widget available in your list of widgets called “My Posts Widget”. You can add it to any widget area in your theme like you would with any other widget.
Please note that this plugin will display all posts that are being displayed on the current page, regardless of where they’re displayed. That includes posts in main query, posts in sidebars, posts in footer etc. If you need more precise control, you’ll need to modify the code to suit your needs.