Exclude a dynamic value from cache with Wordpress

2019-07-18 09:33发布

I'm using the Super Cache plugin.

For some time I was looking for a solution, but without success. I need to disable the cache for one function in the file functions.php.

add_shortcode('custom_counter', 'example_shortcode');
function example_shortcode() {
    // Get custom counter option value
    $counter = get_option( 'wc-custom-counter' );
    return '<span class="custom-counter">' . $counter . ' rub.</span>';
}

This is shortcode is used on the created custom page. It is necessary that the data output by this shortcode does not fall into the page cache.

2条回答
\"骚年 ilove
2楼-- · 2019-07-18 09:52

You cannot exclude a function from cache plugins. Instead you can exclude an URL (in WP Super Cache, go to 'Settings > WP Super Cache > Advanced' - 'Accepted Filenames & Rejected URIs' section).

So, call this function using AJAX instead calling directly and you can exclude the AJAX URL.

Here is the full code.

Add these in theme's functions.php:

add_action('wp_ajax_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_nopriv_{action}

function customer_counter_ajax_handler() {      
    // Get custom counter option value
    $counter = get_option( 'wc-custom-counter' );
    echo $counter . ' rub.';
}

Replace all your shortcodes [custom_counter] instances with <span class="customer_counter_shortcode">&nbsp;</span>.

Add this script to theme's footer.php:

jQuery(function($){
    $.ajax({
        url : '<?php echo site_url(); ?>/wp-admin/admin-ajax.php', // AJAX handler
        data : { action : 'customer_counter' },
        type : 'POST',
        success : function( $result ){
            if( $result ) {
                $('.customer_counter_shortcode').html($result);
            }
        }
    });
});

You can then exclude the AJAX URL - /wp-admin/admin-ajax.php?action=customer_counter.

查看更多
forever°为你锁心
3楼-- · 2019-07-18 10:12

Adapted from this old WSE thread, you will find bellow the complete way to make it working.

Here we display a spinner loading icon enter image description here that will be replaced by the counter real non cached value through ajax. Javascript stays always active even in a cached page, so it can change anything needed on the page via Ajax or via any detected event. So there is no need to exclude anything in the plugin settings.

The replacement code:

// The shortcode
add_shortcode('custom_counter', 'customer_counter_shortcode');
function customer_counter_shortcode() {
    // Start buffering
    ob_start(); 

    // Using woocommerce existing animated spinner gif icon
    $loading_url = home_url( '/wp-content/plugins/woocommerce/assets/images/select2-spinner.gif' );

    // Displaying a "Loading spinner icon + text to be replaced by Ajax value
    echo '<span class="custom-counter">
        <img id="loading-img" src="'.$loading_url.'" alt="Loading..." style="opacity:0.5; display:inline-block; vertical-align: middle;" />
        <span style="opacity:0.5;"> ' . _("loading…") . '</span>
    </span>';
    ?>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof woocommerce_params === 'undefined')
            return false;

        $.ajax({
            type: 'POST',
            url: woocommerce_params.ajax_url,
            data: {
                'action': 'custom_counter',
                'custom-counter': true,
            },
            success: function (result) {
                $('.custom-counter').text(result);
                console.log('response: '+result); // just for testing | TO BE REMOVED
            },
            error: function(error){
                console.log(error); // just for testing | TO BE REMOVED
            }
        });
    });
    </script>
    <?php
    return ob_get_clean(); // Return the buffered code
}

// The wordpress ajax hooked function (for logged in and non logged users)
add_action('wp_ajax_custom_counter', 'ajax_custom_counter');
add_action('wp_ajax_nopriv_custom_counter', 'ajax_custom_counter');
function ajax_custom_counter() {
    if( isset($_POST['custom-counter']) && $_POST['custom-counter'] )
        echo get_option( 'wc-custom-counter' ); // Get option value

    exit();
}

Code goes in function.php file of your active child theme (or active theme). tested and works.

查看更多
登录 后发表回答