Changing widget options via the functions.php when there are no hooks

The problem: to change a widget’s options with a custom function in functions.php, when there are no useful hooks, and where there are multiple occurrences of the same widget (multiwidget).

This would involve:

Read More
  1. Retrieving the options from “widget_some-widget” in the “wp_options” table. (The returned option containing a string of settings (in serialized form) repeated several times corresponding to several unique occurrences of the same widget.)

  2. Changing the value of say the third occurrence of an option instance called some_name, from “old-value” to “new-value”, and another called some_other_name, from “some-old-value” to “some-new-value”. (It may be that each occurrence of the widget has its own id within the serialized options string that could be recognised somehow?)

  3. Updating the database with the altered options

i.e. something along these lines –

function change_widget_configuration() {

    $options = get_option('widget_some-widget');

// [code to parse $options string to ensure the correct occurrences of 'some_name' and 'some_other_name' have their values changed]

/* third-occurrence of */    $options['some_name'] = 'new value';
/* third-occurrence of */    $options['some_other_name'] = 'new value';

    update_option('widget_some-widget', $options);

}

The widget’s serialized options string might look something like this (minus the ellipsis) –

i:3;a:20:{s:5:"title";s:8:"My Title";s:9:"some_name";s:11:"Bit of text";s:15:"some_other_name";s:2:"17"; […] s:14:"more_from_this";s:29:"More articles on this subject";}s:12:"_multiwidget";i:1;}

What kind of approach can be taken (with the commented-out code above) to solve this problem? *

*This would be very useful for controlling the output of third-party widgets (that do not have any useful hooks) without needing to alter their code, or repeating large chunks of it in the functions.php

Related posts

Leave a Reply

2 comments

  1. After some digging, I’ve arrived at a solution (explained in the comments) –

    function change_widget_configuration() {
    
    $options = get_option('widget_some-widget'); // retrieve the options for all occurrences of the named widget*
    
        $widget_number = 3; // the id number of the specific occurrence of the widget whose options you wish to alter (this can be obtained simply in the html from the <div id=""> tag of the specific widget)
    
        $sub_options = $options[$widget_number]; // this now contains the options of the specific occurrence of the widget**
    
            $sub_options['some_name'] = 'new value'; // change any named option*
            $sub_options['some_other_name'] = 'new value';
    
        $options[$widget_number] = $sub_options // pass the changes back to the multi-widget array
    
    update_option('widget_some-widget', $options); // write the altered widget options back into the wp_options table*
    
    }
    

    *Add appropriate conditional statements to check that the options exist before getting or updating the array.

    **This is the particular solution for multiwidgets.

    That’s it! This simple little function now allows us to control the output of all sorts of widgets, simply by changing their options programmatically, rather than manually or hacking into the code. For example, I now have a third-party widget on the Frontpage of a blog, which normally displays a list of posts from a fixed category set in admin, but which now has its category (and its title) changing periodically according to a custom function placed in functions.php. The possible applications are endless, and it solves many of the problems of interacting with plugins which lack useful hooks, all without having to hack into their code. Add custom fields to the mix and we’re flying…

  2. Hi @maduroblanco:

    This would very much be a hack, but have you tried to hook 'option_widget_some-widget' like this?

    add_filter('option_widget_some-widget','your_option_widget_some_widget');
    function your_option_widget_some_widget($value) {
      static $instance = 1;
      select ($instance) {
        case 1: 
          $value = 'foo'; // Return whatever your first one needs
          break;
        case 2: 
          $value = 'bar'; // Return whatever your second one needs 
          break;
        case 3: 
          $value = 'baz';  // Return whatever your third time needs
          break;
      }
      $instance++;
      return $value;
    }  
    

    Again, this is very much a hack, but it might work? I’ve not tested this code so let me know if it gives you want you were looking for. Note that the filter name is based on the name of the option, so be sure to change that to match whatever the option name is.