1

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:

  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

3
  • I don't think this is easy approach... Could you give some context please. Can you edit widget itself (is it your own or third party code) ? Do you need to do this once or recurrently?
    – Rarst
    Jan 11, 2011 at 12:49
  • The idea is to alter any particular widget's settings without either having to alter its core code or having to do it manually. This would be extremely useful in many situations--user interactions, time, context, etc. Many widgets do not come with any useful hooks for example--by directly altering their settings in the database much of this can be overcome. I think I have outlined an efficient way of doing it, but I just don't know how to select a particular setting in a serialized array when there are multiple occurrences of the same widget. Jan 11, 2011 at 14:46
  • I wonder if you can just call the widget sub class's update method and just pass in your own params. Shall have a play and post an answer if it works. Jan 11, 2011 at 15:07

2 Answers 2

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...

1
  • $widget_number = 3; that is not that easy as we would need javascript... how to get the id within php?
    – user9
    Dec 11, 2013 at 12:30
0

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.

1
  • I hadn't realised you could filter a specific named option using add_filter('option_name_widget-some-widget', ... Interesting. However, in the meantime I've come up with what seems to be an elegant (and tested) solution (see my answer). Jan 12, 2011 at 1:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.