← Blog/WordPress

Build a WordPress Widget Plugin — Social Links, Recent Posts & Custom HTML

Learn how to build a WordPress plugin that adds 3 custom widgets using the WP_Widget class. Build a Social Links widget, Recent Posts widget with thumbnails, and a Custom HTML widget — all configurable from Appearance → Widgets.

📅 2026-06-293 min read📚 Ebook #17

What Are WordPress Widgets?

Widgets are small content blocks that site owners drag into widget areas (sidebars, footers, header areas) from Appearance → Widgets in the WordPress admin. Every widget you see — calendar, search box, recent posts — is built using the same WP_Widget class.

Building your own widget lets you add custom functionality to any WordPress site without touching theme files.

The WP_Widget Class — 4 Methods

Every widget extends WP_Widget and implements exactly 4 methods:

class My_Widget extends WP_Widget {

    // 1. Define widget ID, name, description
    public function __construct() {
        parent::__construct('my_widget', 'My Widget', [
            'description' => 'What this widget does'
        ]);
    }

    // 2. Front-end HTML output
    public function widget( $args, $instance ) {
        echo $args['before_widget'];
        // Your HTML here
        echo $args['after_widget'];
    }

    // 3. Admin form fields
    public function form( $instance ) {
        // HTML inputs for the admin
    }

    // 4. Save admin form values
    public function update( $new_instance, $old_instance ) {
        $instance['title'] = sanitize_text_field( $new_instance['title'] );
        return $instance;
    }
}

// Register the widget
add_action( 'widgets_init', function() {
    register_widget( 'My_Widget' );
});

Widget 1 — Social Links Widget

The Social Links widget lets site owners enter URLs for Twitter, Instagram, Telegram, GitHub, and LinkedIn. Only platforms with a URL filled in are displayed:

public function widget( $args, $instance ) {
    echo $args['before_widget'];

    $networks = [
        'twitter'   => ['label' => 'Twitter / X',  'icon' => '𝕏'],
        'instagram' => ['label' => 'Instagram',    'icon' => '📷'],
        'telegram'  => ['label' => 'Telegram',     'icon' => '✈'],
    ];

    echo '<ul class="yfin-social-links">';
    foreach ( $networks as $key => $network ) {
        $url = $instance[$key] ?? '';
        if ( ! empty($url) ) {
            echo '<li><a href="' . esc_url($url) . '" target="_blank">'
               . $network['icon'] . ' ' . $network['label']
               . '</a></li>';
        }
    }
    echo '</ul>';
    echo $args['after_widget'];
}

Widget 2 — Recent Posts Widget

The Recent Posts widget uses get_posts() to fetch the latest posts and displays them with thumbnails and dates:

$posts = get_posts([
    'numberposts' => $num_posts,
    'post_status' => 'publish',
    'orderby'     => 'date',
    'order'       => 'DESC',
]);

foreach ( $posts as $post ) {
    $permalink = get_permalink( $post->ID );
    $thumb_id  = get_post_thumbnail_id( $post->ID );
    $thumb_url = $thumb_id
        ? wp_get_attachment_image_url( $thumb_id, 'thumbnail' )
        : '';
    // Render each post item
}

Widget 3 — Custom HTML Widget

The most flexible widget — accepts any HTML in a textarea and renders it safely:

// wp_kses_post() allows safe HTML, removes <script> and other dangerous tags
echo wp_kses_post( $instance['content'] );

This is a preview. The full ebook includes complete code for all 3 widgets, the admin form with select dropdown for post count, checkboxes for show/hide thumbnail and date, widget CSS, and a bonus section on registering custom sidebar areas.

Why Widgets Beat Manual HTML

Once your widget plugin is active, any non-technical site owner can configure it from the WordPress admin — no code editing required. Change the social links, adjust post count, swap HTML content — all through a friendly interface.

Ready to Build This Yourself?

This article is a preview. The full ebook has complete code, detailed explanations, troubleshooting tips, and bonus sections — all in a downloadable PDF.

Buy Full Ebook — $1.50 in $YFIN
Pay with $YFIN on BNB Smart Chain · 30% burned permanently