I was disappointed to find that there wasn’t a “Posts on Page” widget plugin for WordPress. I wanted something that would:
- Display a list of all the posts on a page
- The title is optional
- Also, add “Recent Posts”
- Again the recent posts title could be optional
- The number of recent posts could be fixed or variable based on the number of posts on the page (I use 5 fixed)
- The recent posts could be selected by category, by tag, or by both – so you can effectively add “featured” posts
- Display all as a <ul> list (or not)
So I learned how to create a WordPress plugin that creates a widget, there’s a tutorial here: https://horkan.com/2023/08/08/creating-a-wordpress-widget-plugin-tutorial
And then built my own. It should be over there on the right, doing its job.
You can download the widget from here: http://horkan.com/wp-content/uploads/2023/08/posts-on-page-widget.zip
The code is below. I’ll add it to GitHub later.
<?php
/**
* Plugin Name: Posts on Page Widget
* Plugin URI: https://horkan.com/posts-on-page-wordpress-widget-plugin
* Description: A widget that displays a list of all posts displayed on the current page.
* Version: 1.0
* Author: Wayne Horkan
* Author URI: https://horkan.com
* License: MIT
*/
// Register and load the widget
function posts_on_page_widget_load() {
register_widget( 'Posts_On_Page_Widget' );
}
add_action( 'widgets_init', 'posts_on_page_widget_load' );
class Posts_On_Page_Widget extends WP_Widget {
public function __construct() {
$widget_options = array(
'classname' => 'posts_on_page_widget',
'description' => 'This is a plugin developed by Wayne Horkan that displays a list of all posts displayed on the current page.',
);
parent::__construct( 'posts_on_page_widget', 'Posts on Page Widget', $widget_options );
}
public function widget( $args, $instance ) {
if(isset($instance['title'])) {
$title = apply_filters( 'widget_title', $instance[ 'title' ] );
echo $args['before_widget'] . $args['before_title'] . $title . $args['after_title'];
}
global $posts;
if (empty($posts)) {
$posts = get_posts();
}
$total_posts_to_show = count($posts);
$displayed_posts = 0;
if ($instance['use_list']) {
echo '<ul>';
foreach ($posts as $post) {
if($displayed_posts < $total_posts_to_show) {
echo '<li><a href="' . get_permalink($post) . '">' . $post->post_title . '</a></li>';
$displayed_posts++;
}
}
echo '</ul>';
} else {
foreach ($posts as $post) {
if($displayed_posts < $total_posts_to_show) {
echo '<a href="' . get_permalink($post) . '">' . $post->post_title . '</a><br/>';
$displayed_posts++;
}
}
}
if ($instance['fixed_variable_recent']) {
$total_posts_to_show = isset($instance['total_posts']) ? $instance['total_posts'] : 0; # count($posts);
if ($total_posts_to_show != 0) {
$total_posts_to_show = $total_posts_to_show + $displayed_posts;
}
} else {
$total_posts_to_show = isset($instance['total_posts']) ? $instance['total_posts'] : 0; # count($posts);
if($displayed_posts < $total_posts_to_show) {
$total_posts_to_show = $total_posts_to_show - $displayed_posts;
} else {
$total_posts_to_show = 0;
}
}
if($instance['show_recent'] && $displayed_posts < $total_posts_to_show) {
$recent_posts_args = array(
'numberposts' => $total_posts_to_show - $displayed_posts,
'offset' => 0,
'category' => 0,
'orderby' => 'post_date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'post_status' => 'publish',
'suppress_filters' => true,
);
if(isset($instance['recent_category']) && isset($instance['recent_tag'])) {
$recent_posts_args['category_name'] = $instance['recent_category'];
$recent_posts_args['tag'] = $instance['recent_tag'];
} elseif(isset($instance['recent_category'])) {
$recent_posts_args['category_name'] = $instance['recent_category'];
} elseif(isset($instance['recent_tag'])) {
$recent_posts_args['tag'] = $instance['recent_tag'];
}
$recent_posts = wp_get_recent_posts( $recent_posts_args, ARRAY_A );
echo '<br/>';
echo '<br/>';
echo '<br/>';
if(isset($instance['recent_title'])) {
$recent_title = $instance['recent_title'];
echo $args['before_title'] . $recent_title . $args['after_title'];
}
if($instance['use_list']) {
echo '<ul>';
foreach ($recent_posts as $post) {
echo '<li><a href="' . get_permalink($post['ID']) . '">' . $post['post_title'] . '</a></li>';
}
echo '</ul>';
} else {
foreach ($recent_posts as $post) {
echo '<a href="' . get_permalink($post['ID']) . '">' . $post['post_title'] . '</a><br/>';
}
}
}
echo $args['after_widget'];
}
// Form method
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : 'Posts on Page';
$use_list = ! empty( $instance['use_list'] ) ? $instance['use_list'] : true;
$recent_title = ! empty( $instance['recent_title'] ) ? $instance['recent_title'] : 'Recent Posts';
$show_recent = ! empty( $instance['show_recent'] ) ? $instance['show_recent'] : true;
$recent_category = ! empty( $instance['recent_category'] ) ? $instance['recent_category'] : '';
$recent_tag = ! empty( $instance['recent_tag'] ) ? $instance['recent_tag'] : '';
$total_posts = ! empty( $instance['total_posts'] ) ? $instance['total_posts'] : '5';
$fixed_variable_recent = ! empty( $instance['fixed_variable_recent'] ) ? $instance['fixed_variable_recent'] : true;
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Title (Optional):</label>
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $title ); ?>" placeholder="Enter title (optional)" />
</p>
<p>
<input type="checkbox" id="<?php echo $this->get_field_id( 'use_list' ); ?>" name="<?php echo $this->get_field_name( 'use_list' ); ?>" <?php checked($use_list, true); ?> />
<label for="<?php echo $this->get_field_id( 'use_list' ); ?>">Use List Format</label>
</p>
<p>
<input type="checkbox" id="<?php echo $this->get_field_id( 'show_recent' ); ?>" name="<?php echo $this->get_field_name( 'show_recent' ); ?>" <?php checked($show_recent, true); ?> />
<label for="<?php echo $this->get_field_id( 'show_recent' ); ?>">Show Recent Posts</label>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'recent_title' ); ?>">Recent Title (Optional):</label>
<input type="text" id="<?php echo $this->get_field_id( 'recent_title' ); ?>" name="<?php echo $this->get_field_name( 'recent_title' ); ?>" value="<?php echo esc_attr( $recent_title ); ?>" placeholder="Enter recent title (optional)" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'total_posts' ); ?>">Total Posts to Show:</label>
<input type="number" id="<?php echo $this->get_field_id( 'total_posts' ); ?>" name="<?php echo $this->get_field_name( 'total_posts' ); ?>" value="<?php echo esc_attr( $total_posts ); ?>" />
</p>
<p>
<input type="checkbox" id="<?php echo $this->get_field_id( 'fixed_variable_recent' ); ?>" name="<?php echo $this->get_field_name( 'fixed_variable_recent' ); ?>" <?php checked($fixed_variable_recent, true); ?> />
<label for="<?php echo $this->get_field_id( 'fixed_variable_recent' ); ?>">Fixed or Variable</label>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'recent_category' ); ?>">Recent Posts Category:</label>
<input type="text" id="<?php echo $this->get_field_id( 'recent_category' ); ?>" name="<?php echo $this->get_field_name( 'recent_category' ); ?>" value="<?php echo esc_attr( $recent_category ); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'recent_tag' ); ?>">Recent Posts Tag:</label>
<input type="text" id="<?php echo $this->get_field_id( 'recent_tag' ); ?>" name="<?php echo $this->get_field_name( 'recent_tag' ); ?>" value="<?php echo esc_attr( $recent_tag ); ?>" />
</p>
<?php
}
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['use_list'] = filter_var($new_instance['use_list'], FILTER_VALIDATE_BOOLEAN);
$instance['show_recent'] = filter_var($new_instance['show_recent'], FILTER_VALIDATE_BOOLEAN);
$instance['recent_title'] = strip_tags( $new_instance['recent_title'] );
$instance['recent_category'] = strip_tags( $new_instance['recent_category'] );
$instance['recent_tag'] = strip_tags( $new_instance['recent_tag'] );
$instance['total_posts'] = strip_tags( $new_instance['total_posts'] );
$instance['fixed_variable_recent'] = filter_var($new_instance['fixed_variable_recent'], FILTER_VALIDATE_BOOLEAN);
return $instance;
}
}
?>