Custom code for creating a dynamic sidebar widget in WordPress

Sarah M Dec 17, 2024 Widgets
How can I make a widget that shows different content based on the page someone is on?
What is the best way to create a dynamic sidebar widget in WordPress that displays different content based on the current page context using WordPress hooks and conditional tags?
Andy answered Dec 17, 2024

Creating a Dynamic Sidebar Widget

Here's how to create a custom widget that changes its content based on the current page:

First, create a new widget class that extends WP_Widget. Place this code in your theme's functions.php file or in a custom plugin file:

class Dynamic_Context_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'dynamic_context_widget',
            'Dynamic Context Widget',
            array('description' => 'Shows different content based on page context')
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        
        if (is_front_page()) {
            echo '<h3>Homepage Content</h3>';
            echo '<p>' . esc_html($instance['home_content']) . '</p>';
        } 
        elseif (is_single()) {
            echo '<h3>Single Post Content</h3>';
            echo '<p>' . esc_html($instance['post_content']) . '</p>';
        }
        elseif (is_page()) {
            echo '<h3>Page Content</h3>';
            echo '<p>' . esc_html($instance['page_content']) . '</p>';
        }
        else {
            echo '<h3>Default Content</h3>';
            echo '<p>' . esc_html($instance['default_content']) . '</p>';
        }
        
        echo $args['after_widget'];
    }

    public function form($instance) {
        $home_content = isset($instance['home_content']) ? $instance['home_content'] : '';
        $post_content = isset($instance['post_content']) ? $instance['post_content'] : '';
        $page_content = isset($instance['page_content']) ? $instance['page_content'] : '';
        $default_content = isset($instance['default_content']) ? $instance['default_content'] : '';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('home_content'); ?>">Homepage Content:</label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('home_content'); ?>" name="<?php echo $this->get_field_name('home_content'); ?>"><?php echo esc_textarea($home_content); ?></textarea>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('post_content'); ?>">Single Post Content:</label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('post_content'); ?>" name="<?php echo $this->get_field_name('post_content'); ?>"><?php echo esc_textarea($post_content); ?></textarea>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('page_content'); ?>">Page Content:</label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('page_content'); ?>" name="<?php echo $this->get_field_name('page_content'); ?>"><?php echo esc_textarea($page_content); ?></textarea>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('default_content'); ?>">Default Content:</label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('default_content'); ?>" name="<?php echo $this->get_field_name('default_content'); ?>"><?php echo esc_textarea($default_content); ?></textarea>
        </p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['home_content'] = strip_tags($new_instance['home_content']);
        $instance['post_content'] = strip_tags($new_instance['post_content']);
        $instance['page_content'] = strip_tags($new_instance['page_content']);
        $instance['default_content'] = strip_tags($new_instance['default_content']);
        return $instance;
    }
}

Register the widget by adding this code to your theme's functions.php:

function register_dynamic_context_widget() {
    register_widget('Dynamic_Context_Widget');
}
add_action('widgets_init', 'register_dynamic_context_widget');

This widget:

  • Creates separate content areas for homepage, single posts, pages, and default content
  • Uses WordPress conditional tags to determine the current context
  • Allows easy content editing through the WordPress admin
  • Sanitizes input and output for security

To extend the widget for custom post types, add this condition check inside the widget method:

elseif (is_singular('your_custom_post_type')) {
    echo '<h3>Custom Post Type Content</h3>';
    echo '<p>' . esc_html($instance['cpt_content']) . '</p>';
}

Plugin Alternative

If you prefer using a plugin, consider:

These plugins offer user-friendly interfaces for controlling widget visibility without coding.