0

I'm not sure if it is true but seems that the content of the widgets is cached. I initially thought there was a problem with my code (I need to hide/show a section in a custom widget according to a session value) but I have the same problem with all widgets and get_option().

I did this test.

In page "A" I update an option:

update_option( 'custom_check', 'a' );

In page "B" I update the same option with a different value:

update_option( 'custom_check', 'b' );

When I go from the page "A" to "B" (or viceversa) the options are updated correctly in the database. And the value is printed correctly in the page with:

echo get_option( 'custom_check' );

But if I print the value in a widget (I've tried with different widgets, default text and recent posts widgets included) the value is not updated. Until the refresh of the page.

Example: I'm on page "A" so the value is "a". When I visit the page "B", the value is "b" in the database and is printed correctly in the page content. But the widget displays the old value ("a"). When I refresh the page, the widget displays the correct value ("b").

Any idea?

[Edit] I will try to explain better what I mean.

I’m using Twenty Fourteen, not a custom theme. In the sidebar I’ve the menu with page “A” and “B” so I can visit those pages with one click (@s_ha_dum♦ no AJAX involved). And the default text widget included in WordPress.

In page.php (Twenty Fourteen) I have this code at the top:

<?php
if ( is_page( 749 ) ) {
    update_option( 'custom_check', 'a' );
} elseif ( is_page( 800 ) ) {
    update_option( 'custom_check', 'b' );
}

echo get_option( 'custom_check' );
?>

749 and 800 are the IDs of the pages “A” and “B”.

To test the variable in a widget, I’ve inserted this line in /wp-includes/default-widgets.php (I know that it is bad practice, I’m just testing), inside the WP_Widget_Text class:

echo get_option( 'custom_check' );

The problem: I am on page “A”, “custom_check” equals to “a” and the widget displays “a”. When I click on the page “B” link on the menu, “custom_check” equals to “b” in the db and is printed correctly at the top of the page. But in the text widget I still see “a”. If I refresh the page, the widget display the correct value.

Is this a cache problem? Or maybe the update of the option fires too late (after widget_init)?

3
  • "until the refresh of the page"? Sounds like there is AJAX involved? If not, no data on the page should be expected to change until a refresh. Please try to clarify.
    – s_ha_dum
    Commented Nov 25, 2015 at 15:27
  • anything can happen. widget can or can not be cached depending on the code of the wisget itself. If it is your widget then please show the code as it is hard to guess. Commented Nov 25, 2015 at 15:38
  • I’ve just updated my question to explain better what I mean. Commented Nov 25, 2015 at 17:41

1 Answer 1

0

Ok, seems that the problem is not related to the cache. But to the action execution order. If I update the value inside a page template (or inside a shortcode, that's why I started my tests) the update fires after the render of the widget.

Solution: update the value inside an action. In this example you can use the 'wp' action:

function test() {
    if ( is_page( 749 ) ) {
        update_option( 'custom_check', 'a' );
    } elseif ( is_page( 800 ) ) {
        update_option( 'custom_check', 'b' );
    }
}

add_action( 'wp', 'test' );
2
  • shortcode just should not have this kind of side effect :(. calling update_option while evaluating a shortcode can bring sites down. Commented Nov 25, 2015 at 18:06
  • @MarkKaplun you're right. Shortcodes don't have this problem. I've tested a simple shortcode right now and it updates the option correctly. Commented Nov 25, 2015 at 20:27

Your Answer

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

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