Here're what I tried on my local site:
1. Create the widget class.
Save this widget somewhere and include it in your functions.php
:
class PostInfoWidget extends WP_Widget
{
/**
* Constructor
*/
function __construct() {
parent::__construct('post-info-widget',
__('Display Post Information', 'text-domain'), [
'classname' => 'post-info-widget',
'description' => __('Use this widget to display a specific post information.')
]);
}
/**
* Display front-end contents.
*/
function widget($args, $instance)
{
$post = get_post($instance['post_id']);
echo $args['before_widget'];
if ( !empty($instance['widget_title']) ) {
echo $args['before_title'] . $instance['widget_title'] . $args['after_title'];
}
?>
<article class="post post-sidebar" itemscope itemtype="https://schema.org/Article">
<?= get_the_post_thumbnail($post, 'thumbnail', ['itemprop' => 'thumbnail']) ?>
<h4 itemprop="name">
<a itemprop="url" href="<?= esc_url( get_permalink($post) ) ?>">
<?= get_the_title($post) ?>
</a>
</h4>
<div class="author-info">
<span class="author-name">
<?php the_author_meta('display_name', $post->post_author) ?>
</span>
<span class="author-avatar">
<?= get_avatar($post->post_author) ?>
</span>
</div>
<div class="category-info">
<?php the_category(', ', '', $instance['post_id']) ?>
</div>
</article>
<?php
echo $args['after_widget'];
}
/**
* Display back-end form.
*/
function form($instance)
{
$widget_title = !empty($instance['widget_title']) ? $instance['widget_title'] : '';
$post_id = !empty($instance['post_id']) ? $instance['post_id'] : 1;
?>
<p>
<label for="<?= $this->get_field_id('widget_title') ?>">
<?= __('Title of the widget:', 'text-domain') ?>
</label>
<input class="widefat" type="text" name="<?= $this->get_field_name('widget_title') ?>" value="<?= $widget_title ?>">
</p>
<p>
<label for="<?= $this->get_field_id('post_id') ?>">
<?= __('Displaying infomation of post ID:', 'text-domain') ?>
</label>
<input type="number" name="<?= $this->get_field_name('post_id') ?>" value="<?= $post_id ?>">
</p>
<?php
}
/**
* Save back-end form.
*/
function update($new_instance, $old_instance)
{
$instance = [];
$instance['widget_title'] = sanitize_text_field($new_instance['widget_title']);
$instance['post_id'] = absint($new_instance['post_id']);
return $instance;
}
}
2. Register the widget
Add this to your functions.php
after you included the above code.
add_action('widgets_init', function() {
register_widget('PostInfoWidget');
});
3. Register a sidebar to display the widget.
Add this code to your functions.php
too:
register_sidebar([
'name' => __('Post infomation sidebar', 'text-domain'),
'id' => 'post-info-sidebar',
'description' => __('Use this sidebar to display a specific post information.', 'text-domain'),
'before_widget' => '<aside id="%1$s" class="widget %2$s" itemscope itemtype="https://schema.org/WPSideBar">',
'after_widget' => '</aside>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>'
]);
4. Display the widget.
Add this code to your sidebar.php
or any templates you want:
<?php if ( is_active_sidebar('post-info-sidebar') ) {
dynamic_sidebar('post-info-sidebar');
} else {
// Do something else.
} ?>
Now, try it out and customize it to your preference.