Featured Post Widget
Adds a "Featured Post" widget that highlights one post or page you pick, shown as a card with its featured image, excerpt and a read-more link.
Opens WPIDE on
Code
if ( ! class_exists( 'WPIDE_Featured_Post_Widget' ) ) {
class WPIDE_Featured_Post_Widget extends WP_Widget {
public function __construct() {
parent::__construct( 'wpide_featured_post', 'Featured Post', array(
'description' => 'One post or page you choose, shown as a card with its image and excerpt.',
'customize_selective_refresh' => true,
) );
}
public function widget( $args, $instance ) {
$post = ! empty( $instance['post_id'] ) ? get_post( absint( $instance['post_id'] ) ) : null;
if ( ! $post || 'publish' !== $post->post_status || post_password_required( $post ) || ( is_singular() && get_queried_object_id() === $post->ID ) ) {
return;
}
$title = isset( $instance['title'] ) ? $instance['title'] : '';
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
$link = get_permalink( $post );
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput -- theme markup.
if ( '' !== (string) $title ) {
echo $args['before_title'] . esc_html( $title ) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput
}
echo '<article class="wpide-featured-post">';
if ( has_post_thumbnail( $post ) ) {
echo '<a href="' . esc_url( $link ) . '" tabindex="-1" aria-hidden="true">' . get_the_post_thumbnail( $post, 'medium_large', array( 'alt' => '', 'style' => 'display:block;width:100%;height:auto;border-radius:6px;margin-bottom:.5em;' ) ) . '</a>';
}
echo '<h3 style="margin:0 0 .35em;font-size:1.1em;"><a href="' . esc_url( $link ) . '">' . esc_html( get_the_title( $post ) ) . '</a></h3>';
echo '<p style="margin:0 0 .5em;">' . esc_html( wp_trim_words( get_the_excerpt( $post ), 25 ) ) . '</p>';
echo '<a href="' . esc_url( $link ) . '">' . esc_html( ! empty( $instance['more'] ) ? $instance['more'] : 'Read more' ) . '<span class="screen-reader-text">: ' . esc_html( get_the_title( $post ) ) . '</span></a>';
echo '</article>';
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput
}
public function form( $instance ) {
$title = isset( $instance['title'] ) ? $instance['title'] : 'Featured';
$post_id = ! empty( $instance['post_id'] ) ? absint( $instance['post_id'] ) : 0;
$more = isset( $instance['more'] ) ? $instance['more'] : 'Read more';
$choices = get_posts( array(
'post_type' => array( 'post', 'page' ),
'posts_per_page' => 100,
'no_found_rows' => true,
'orderby' => 'date',
) );
echo '<p><label for="' . esc_attr( $this->get_field_id( 'title' ) ) . '">Title:</label><input class="widefat" type="text" id="' . esc_attr( $this->get_field_id( 'title' ) ) . '" name="' . esc_attr( $this->get_field_name( 'title' ) ) . '" value="' . esc_attr( $title ) . '" /></p>';
echo '<p><label for="' . esc_attr( $this->get_field_id( 'post_id' ) ) . '">Post or page:</label><select class="widefat" id="' . esc_attr( $this->get_field_id( 'post_id' ) ) . '" name="' . esc_attr( $this->get_field_name( 'post_id' ) ) . '"><option value="0">— Select —</option>';
foreach ( $choices as $choice ) {
echo '<option value="' . esc_attr( $choice->ID ) . '"' . selected( $post_id, $choice->ID, false ) . '>' . esc_html( get_the_title( $choice ) . ' (' . $choice->post_type . ')' ) . '</option>';
}
echo '</select></p>';
echo '<p><label for="' . esc_attr( $this->get_field_id( 'more' ) ) . '">Link text:</label><input class="widefat" type="text" id="' . esc_attr( $this->get_field_id( 'more' ) ) . '" name="' . esc_attr( $this->get_field_name( 'more' ) ) . '" value="' . esc_attr( $more ) . '" /></p>';
return '';
}
public function update( $new_instance, $old_instance ) {
return array(
'title' => isset( $new_instance['title'] ) ? sanitize_text_field( $new_instance['title'] ) : '',
'post_id' => isset( $new_instance['post_id'] ) ? absint( $new_instance['post_id'] ) : 0,
'more' => isset( $new_instance['more'] ) ? sanitize_text_field( $new_instance['more'] ) : '',
);
}
}
}
add_action( 'widgets_init', function () {
register_widget( 'WPIDE_Featured_Post_Widget' );
} );
Notes
The widget hides itself on the featured post's own page and when the post is unpublished.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.