Quick Tip: How to Use Shortcodes Within Widgets in WordPress

Jérémy Heleine
Jérémy Heleine
Share

We can do a lot of different things with shortcodes in WordPress, as we explored in our article describing the WordPress Shortcode API. However, by default, WordPress only allows the use of shortcodes in posts (and pages), and not anywhere else.

If you want to use shortcodes in widgets, it’s not possible by default. However, in this quick tip, I’ll cover how you can enable this functionality.

no shortcode in widget

Allowing the Use of Shortcodes in the Text Widget

WordPress provides several widgets by default. One of them is the ‘Text’ widget, which, as its name suggests, allows you to add any text to a widget. You can also use it to add any HTML code.

That means that you can also play with JavaScript code in this widget, so it’s pretty powerful. However, if you need more, like a PHP script to access some data stored in the server, this widget won’t help you by default.

It’s similar to a post. That’s why, like in a post, we would like to be able to use shortcodes to do anything we want. To do that, we can use the widget_text filter. This filter is called to allow modifications in the content of a ‘Text’ widget. We’ll use it here to ask WordPress to parse shortcodes in this widget.

Parsing shortcodes in WordPress is achieved thanks to the do_shortcode() function. It accepts one required parameter, the text to parse, and it returns the parsed text. That means that we can directly use this function as a callback function in the widget_text filter.

The code below can be used in a plugin file or in the functions.php file of your theme.

<?php
add_filter('widget_text', 'do_shortcode');
?>

And we’re done. Now, any existing shortcode you type in the ‘Text’ widget will be parsed.

shortcode

Creating a New Shortcodes Widget

Alternatively, we can also create our own widget. As the default ‘Text’ widget works perfectly, we can simply adapt its code from the following (found in the /wp-includes/default-widgets.php file). It’s worth noting that we should create our own plugin, never modify core WordPress files.

<?php
class WP_Widget_Text extends WP_Widget {

    public function __construct() {
        $widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML.'));
        $control_ops = array('width' => 400, 'height' => 350);
        parent::__construct('text', __('Text'), $widget_ops, $control_ops);
    }

    /**
     * @param array $args
     * @param array $instance
     */
    public function widget( $args, $instance ) {
        /** This filter is documented in wp-includes/default-widgets.php */
        $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );

        /**
         * Filter the content of the Text widget.
         *
         * @since 2.3.0
         *
         * @param string    $widget_text The widget content.
         * @param WP_Widget $instance    WP_Widget instance.
         */
        $text = apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance );
        echo $args['before_widget'];
        if ( ! empty( $title ) ) {
            echo $args['before_title'] . $title . $args['after_title'];
        } ?>
            <div class="textwidget"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></div>
        <?php
        echo $args['after_widget'];
    }

    /**
     * @param array $new_instance
     * @param array $old_instance
     * @return array
     */
    public function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        if ( current_user_can('unfiltered_html') )
            $instance['text'] =  $new_instance['text'];
        else
            $instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // wp_filter_post_kses() expects slashed
        $instance['filter'] = ! empty( $new_instance['filter'] );
        return $instance;
    }

    /**
     * @param array $instance
     */
    public function form( $instance ) {
        $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) );
        $title = strip_tags($instance['title']);
        $text = esc_textarea($instance['text']);
?>
        <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('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( 'text' ); ?>"><?php _e( 'Content:' ); ?></label>
        <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $text; ?></textarea></p>

        <p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked(isset($instance['filter']) ? $instance['filter'] : 0); ?> />&nbsp;<label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p>
<?php
    }
}
?>

We don’t have a lot of details to change here. The first thing to change is the name of the class. I chose to name it WP_Widget_Shortcodes but feel free to choose any name you want. As the constructor of this class sets some information about the widget itself, we also need to modify it.

<?php
public function __construct() {
    $widget_ops = array('classname' => 'widget_shortcodes', 'description' => __('Arbitrary text or HTML with shortcodes.'));
    $control_ops = array('width' => 400, 'height' => 350);
    parent::__construct('shortcodes', __('Shortcodes'), $widget_ops, $control_ops);
}
?>

The other thing to change is in the widget() method which describes to WordPress how to display the widget. We change the content of the $text variable which contains the text to display. We remove the call to the widget_text filter, and we apply the do_shortcode() function to this content.

<?php
$text = empty( $instance['text'] ) ? '' : do_shortcode($instance['text']);
?>

We then need to register our widget, to be able to add it like any other widget. This can be achieved thanks to the widgets_init action triggered once WordPress registered the default widgets.

<?php
add_action('widgets_init', function() {
    register_widget('WP_Widget_Shortcodes');
});
?>

Now you can find our widget in the list of the available widgets. You can add it to any compatible zone, and it will interpret any shortcode you use.

shortcodes widget

Closing Words

As we saw above, enabling the use of shortcodes in widgets is not very complicated, but you need to be careful. In fact, not every shortcode will fit in the place where widgets are displayed. If the shortcode has a fixed width, that can be a problem.

Note that the changes we used in the default ‘Text’ widget are minimal. You can change anything else if you want to customize your widget. You can retrieve the filter we used and the widget we created in an example plugin available to download here if you’d like to experiment further.

Frequently Asked Questions about Using Shortcodes within Widgets in WordPress

What is the purpose of using shortcodes in WordPress widgets?

Shortcodes in WordPress widgets are used to add specific functionalities or features without having to write code. They are essentially shortcuts to complex functions. For instance, you can use a shortcode to embed files, create objects, or insert specific content into your posts or pages. By using shortcodes in widgets, you can extend these functionalities to your website’s sidebar or other widget areas, enhancing the user experience.

How do I add a shortcode to a WordPress widget?

To add a shortcode to a WordPress widget, navigate to the ‘Widgets’ section under ‘Appearance’ in your WordPress dashboard. Drag and drop the ‘Text’ widget to the desired widget area. In the text field of the widget, enter your shortcode enclosed in square brackets [ ]. Click ‘Save’ to apply the changes.

Why isn’t my shortcode working in the widget?

If your shortcode isn’t working in the widget, it could be due to several reasons. The shortcode might be incorrect, or the plugin that provides the shortcode might be deactivated. Ensure that the shortcode is correct and the necessary plugin is active. If the problem persists, there might be a conflict with another plugin or theme. Try deactivating other plugins or switching to a default theme to troubleshoot the issue.

Can I use multiple shortcodes in a single widget?

Yes, you can use multiple shortcodes in a single widget. Just ensure that each shortcode is enclosed in square brackets and there is a space between different shortcodes.

How do I create my own shortcode for a widget?

To create your own shortcode for a widget, you need to add a custom function in your theme’s functions.php file. This function should define what the shortcode does. Once the function is defined, you can use add_shortcode() function to create a new shortcode.

Can I use shortcodes in all types of widgets?

Shortcodes can be used in any widget that accepts text input. This includes the ‘Text’ widget, ‘Custom HTML’ widget, and others. However, not all widgets may support shortcodes.

What is the do_shortcode function in WordPress?

The do_shortcode function in WordPress is used to search the content for shortcodes and filter the shortcodes through their hooks. It essentially allows you to use shortcodes outside the post editor, such as in a widget or a theme file.

Can I use shortcodes in WordPress page builders?

Yes, most WordPress page builders support the use of shortcodes. You can add a shortcode to a page builder module or widget in a similar way as you would add to a regular widget.

How do I find the available shortcodes for my WordPress site?

The available shortcodes for your WordPress site depend on the plugins and theme you have installed. Some plugins and themes provide a list of available shortcodes in their documentation. You can also find shortcodes by searching the plugin or theme files for add_shortcode function.

Can I use shortcodes in WordPress posts and pages?

Yes, shortcodes can be used in WordPress posts and pages. Just like in widgets, you can add a shortcode to a post or page by enclosing it in square brackets in the post editor.