How to Update a WordPress Widget Programmatically

A customer site has a couple of sidebar widgets that contain content found on a third-party site. The customer used to manually go to this third-party site, copy the data, and paste into the widget; one weekly, one daily…

Naturally, sometimes they forgot or made a mistake when copying/pasting. Plus, it was a serious waste of time!

I suggested we setup a cron job to fetch and update that widget content programmatically.

Then I found out that either there is no native WP method for doing this, or it is extremely well hidden…

So here’s what I built…

TL;DR
// the title of the widget you want to return
$title = 'My Custom HTML Widget Title';

// get all "Custom HTML" widgets
$widgets = get_option( 'widget_custom_html' );

foreach ( $widgets as $key => $widget ) :

    // if this is NOT it, move on
    if ( mb_strtolower( $widget['title'] ) !== mb_strtolower( $title ) ) continue;

    // if this IS it, replace current widget content with new content
    $widget['content'] = $content;

    // update the database
    $updated = update_option( 'widget_custom_html', $widgets );

endforeach;
    

The comments pretty much explain the process. I have this wrapped in a function that I call during a nightly cron job.

The Details

In my theme’s functions.php file, I added the following code (note the numbers in the parentheses correlate to the numbered bullets below the code block, for deeper explanations):

// namespacing my function to reduce the chance of conflicts
if ( ! function_exists( 'atg_update_widget' ) ) :

    // function receives two required string; setting specific defaults for error-handling (1)
    function atg_update_widget( $title = '', $content = '' ) {

        // make sure we got a title & content (1)
        if ( $title === '' ||  $content === '' ) return false;

        // set initial "updated" status, for error handling
        $updated = false;
        
        // get all Custom HTML widgets (2)
        $widgets = get_option( 'widget_custom_html' );
        
        // loop through to find the correct widget
        foreach ( $widgets as $key => $widget ) :

            // if this is NOT it, move on (3)
            if ( mb_strtolower( $widget['title'] ) !== mb_strtolower( $title ) ) continue;

            // if this IS it, replace current content with new content (4)
            $widget['content'] = $content;

            // update DB and exit the loop (5)
            $updated = update_option( 'widget_custom_html', $widgets );
            break;

        endforeach;

        // check if update was successful
        if ( !$updated ) :
            // do some form of error handling (6)
        endif;

        return $updated;

    } // atg_update_widget

endif;

Again, the comments pretty much tell the tale, but a few additional notes never hurt…

  1. This function is called nightly via a cron job to update a widget’s content. The function requires two string variables (the widget’s “Title” and the updated content) and cannot process properly with them. If either is missing, the function fails.
  2. get_option is a WordPress function that returns an the requested “option”; the returned data type can vary based on what was requested. In my case, the function returns an array of all Custom HTML Widgets.
  3. While looping through the returned widgets, I compare this loop’s “title” with the one passed to the function. Note that I use mb_strtolower instead of strtolower; mb_strtolower provides support for UTF-8 (international) characters.
  4. If this is the correct widget, I update that widget’s content in the widgets array.
  5. Once the widgets array is updated, I use the update_option WordPress function to push the updated widgets array back into the database. The function returns either either true or false.
  6. If the update fails for some reason, the false return can be used to perform error handling. In my case, I send an email to myself.

Happy widgeting,
Atg

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.