How can I modify the WordPress default widget output?

The question:

I don’t want to style the default widget with only CSS. I want to display the default ‘Categories’ widget content with my own HTML structure.

Is there available any filter or hook to do that?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

To expand on Mark’s answer, there’s not much (generally) available in the way of filters in the default WordPress widgets (except for perhaps widget_text).

But adding your own custom widget is easy – put this in your functions.php:

require_once("my_widget.php");
add_action("widgets_init", "my_custom_widgets_init");

function my_custom_widgets_init(){
  register_widget("My_Custom_Widget_Class");
}

Then you simply want to copy the existing categories widget from wp-includes/widgets/class-wp-widget-categories.php to my_widget.php in your theme, and change the class name to the same name as that used in the call to register_widget() above.

Then make whatever changes you like! I suggest changing the title too so you can distinguish it from the default Categories widget.

Method 2

You can override the default WordPress widgets by extending them. The code for the default Categories widget can be found on the following link: https://developer.wordpress.org/reference/classes/wp_widget_categories/widget/

and below is an example code how you can override the output of the widget.

Class My_Categories_Widget extends WP_Widget_Categories {
    function widget( $args, $instance ) {
        // your code here for overriding the output of the widget
    }
}

function my_categories_widget_register() {
    unregister_widget( 'WP_Widget_Categories' );
    register_widget( 'My_Categories_Widget' );
}
add_action( 'widgets_init', 'my_categories_widget_register' );

Method 3

You do not need to create a complete new widget to do what you need to do. As I read your question, you are just interested in changing how the categories are displayed on the front end. There are two functions that displays the categories on the front end

This all depends on what option was selected in the backend

Now, each of these two functions have a widget specific filter (widget_categories_args and widget_categories_dropdown_args respectively) which you can use to alter the arguments that should be passed to these functions. You can use this to alter the behavior of the list/dropdown. However, this may not be sufficient to do what you want.

Alternatively, each function has its own filter to completely alter the way how these functions should display their output.

They respectively are

We can use the widget_title filter to specifically target the widget only and not other instances of these functions.

In short, you can try the following: (TOTALLY UNTESTED)

add_filter( 'widget_title', function( $title, $instance, $id_base )
{
    // Target the categories base
    if( 'categories' === $id_base ) // Just make sure the base is correct, I'm not sure here
        add_filter( 'wp_list_categories', 'wpse_229772_categories', 11, 2 );
        //add_filter( 'wp_dropdown_cats', 'wpse_229772_categories', 11, 2 );
    return $title;
}, 10, 3 );

function wpse_229772_categories( $output, $args )
{
    // Only run the filter once
    remove_filter( current_filter(), __FUNCTION__ );

    // Get all the categories
    $categories = get_categories( $args );

    $output = '';
    // Just an example of custom html
    $output .= '<div class="some class">';
    foreach ( $categories as $category ) {
        // Just an example of custom html
        $output .= '<div class="' . $category->term_id . '">';
        // You can add any other info here, like a link to the category
        $output .= $category->name;
        // etc ect, you get the drift
        $output .= '</div>';
    }
    $output .= '</div>';

    return $output;
};
    


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment