How to Create a Custom WordPress Widget

Luca R Dec 30, 2024 Widgets
How can I add my own little box or section to my WordPress site to show specific information?
What is the process for creating a custom WordPress widget using the Widget API, and how can I implement it to display dynamic content?
Andy answered Dec 30, 2024

Creating a Custom WordPress Widget

Basic Custom Widget Implementation

Here's a complete custom widget that you can add to your theme's functions.php file or in a site-specific plugin:

This code creates a widget that displays a title and custom text with basic styling options:

class My_Custom_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'my_custom_widget', 
            'My Custom Widget',
            array('description' => 'A simple custom widget example')
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        
        if (!empty($instance['title'])) {
            echo $args['before_title'] . esc_html($instance['title']) . $args['after_title'];
        }
        
        if (!empty($instance['content'])) {
            echo '<div class="custom-widget-content">';
            echo wp_kses_post($instance['content']);
            echo '</div>';
        }
        
        echo $args['after_widget'];
    }

    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : '';
        $content = !empty($instance['content']) ? $instance['content'] : '';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>">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>
        <p>
            <label for="<?php echo $this->get_field_id('content'); ?>">Content:</label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('content'); ?>" 
                      name="<?php echo $this->get_field_name('content'); ?>"><?php echo esc_textarea($content); ?></textarea>
        </p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
        $instance['content'] = (!empty($new_instance['content'])) ? wp_kses_post($new_instance['content']) : '';
        return $instance;
    }
}

Register the widget using this code (also in functions.php):

function register_my_custom_widget() {
    register_widget('My_Custom_Widget');
}
add_action('widgets_init', 'register_my_custom_widget');

Optional Styling

Add this CSS to your theme's stylesheet or in the Customizer:

.custom-widget-content {
    padding: 15px;
    background: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 4px;
}

Plugin Alternatives

If you prefer using a plugin solution, here are some reliable options:

  1. Custom Widgets - Create widgets with custom HTML, shortcodes, and PHP
  2. Widget Logic - Add conditional logic to control widget visibility
  3. Elementor - Page builder with custom widget creation capabilities

Usage

After implementing the code:

  1. Go to Appearance → Widgets in your WordPress dashboard
  2. Find "My Custom Widget" in the available widgets list
  3. Drag it to your desired widget area
  4. Fill in the title and content fields
  5. Save the widget

Notes

  • The widget supports HTML in the content area
  • Content is sanitized for security
  • The widget is responsive and will adapt to your theme's styling
  • You can modify the widget class to add more fields or customize the output

This implementation follows WordPress coding standards and uses proper security measures for data sanitization and escaping.