2

I am currently looking into passing a single query into multiple widgets on a template without running multiple queries. The obvious goal is speed and efficiency.

I have a widget that will deliver specific aspects of the same object with different instances of the widget in the template. Widget instances are a must, but the object instance should remain unchanged. Is there a sweet spot in the template run of actions and filters I should look for in my widget?

For example, I want object->title to show in my widget at the top of the page, so I check that box and so to show in that area. Then I have another instance of the widget where I check object->content to show in that area.

That's very easy inside of the widget, however, very inefficient because I just ran two queries for the same object, because of my widgets being two different objects unto themselves.

How can my widget not attempt the same query twice in this situation? Will get_queried_object run a query for both of those widget instances?

  • Can't you just run the query in the widget, assign it to a global and then the later widgets can just check if it exists? – Andy Macaulay-Brook Oct 1 '16 at 8:32
3

I suggest to use the Object Cache API or Transients API, whatever fits better your needs.

A very quick example with object cache:

// helper function
function get_my_object() {
    $object = wp_cache_get( 'my_object' );
    if ( false === $object ) {
        $args = array( .... );
        $object = new WP_Query( $args );
        wp_cache_set( 'my_object', $object );
    } 
    return $object;
}

class cyb_my_widget extends WP_Widget {

    function __construct() {
        // ...
    }

    function widget( $args, $instance ) {
        // ...
        $object = get_my_object();
    }

    function update( $new_instance, $old_instance ) {
        // ...
    }

    function form( $instance ) {
       // ...
    }
}
  • Yep, better than another global. – Andy Macaulay-Brook Oct 1 '16 at 9:59
  • Beautiful! Thank you for the answer, this is just what I needed. – Nathan Powell Oct 1 '16 at 13:29
0

The easy way would be to generate a global variable or transient (in case you want to use the object on multiple pages) in your template and have the widgets access that.

A programmatically more sound approach would be quite some work and go like this:

  1. Build a widget that runs the query and returns your object. Normally a WP_widget instance will use the parent's constructor to initialize. However, when you are extending the WP_Widget class, you can also include an additional constructor. Here you generate the possibility to pass an additional argument to a widget instance, your object.
  2. The other widgets you define not as extensions of WP_Widget, but as extensions of your parent widget, so they can take an extra argument.
  3. Inside the parent widget use the_widget to display other widgets, passing the object.

I'm sure there must be other approaches, but this is the course I would be exploring. Note: I haven't felt the need to do something like this, so this approach is offered 'as is'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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