You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现WordPress店铺列表页开放/关闭标签动态化并排除缓存

Fixing Cached Restaurant Open/Close Statuses in WordPress

Got it, let's solve this caching problem for your 200-restaurant list page. The issue is your full-page cache is freezing the static status value, so even when business hours change, the label stays stuck. Here are three practical ways to keep the rest of your page cached while making those statuses dynamically update:

1. Shortcode + Cache Plugin Exclusion (Simplest Approach)

Most popular WordPress cache plugins (like WP Rocket, W3 Total Cache, or LiteSpeed Cache) let you exclude specific shortcodes from being cached. We'll wrap your status logic in a shortcode, then tell the cache plugin to skip it.

First, add this to your theme's functions.php file (or a custom plugin):

function restaurant_status_shortcode($atts) {
    // Extract the restaurant ID from shortcode attributes
    $atts = shortcode_atts([
        'id' => '',
    ], $atts);

    if (empty($atts['id'])) return '';

    // Get your dynamic status
    $status = open_close_status(intval($atts['id']));
    // Return sanitized HTML for the status label
    return '<span class="restaurant-status ' . esc_attr($status) . '">' . esc_html($status) . '</span>';
}
add_shortcode('restaurant_status', 'restaurant_status_shortcode');

Next, replace your original template code with this:

<?php echo do_shortcode('[restaurant_status id="' . esc_attr($restaurant_id) . '"]'); ?>

Finally, head to your cache plugin's settings:

  • Look for an option like "Exclude Shortcodes" or "Dynamic Content Exclusion"
  • Add restaurant_status to the list of excluded shortcodes.

This tells the cache plugin to skip generating static content for this shortcode—instead, it'll run the PHP logic every time a user loads the page.

2. AJAX Asynchronous Loading (For More Control)

If your cache plugin doesn't support shortcode exclusion, or you want to avoid touching plugin settings, use AJAX to load each status after the page loads.

Step 1: Add AJAX Handler to functions.php

function get_restaurant_status() {
    // Validate the restaurant ID
    if (!isset($_POST['restaurant_id']) || !is_numeric($_POST['restaurant_id'])) {
        wp_send_json_error('Invalid restaurant ID');
    }

    $restaurant_id = intval($_POST['restaurant_id']);
    $status = open_close_status($restaurant_id);

    // Return sanitized HTML and status data
    wp_send_json_success([
        'html' => '<span class="restaurant-status ' . esc_attr($status) . '">' . esc_html($status) . '</span>'
    ]);
}
// Register AJAX actions for logged-in and guest users
add_action('wp_ajax_get_restaurant_status', 'get_restaurant_status');
add_action('wp_ajax_nopriv_get_restaurant_status', 'get_restaurant_status');

Step 2: Add Placeholder in Your Template

Replace your original status code with this placeholder:

<span class="restaurant-status-placeholder" data-restaurant-id="<?php echo esc_attr($restaurant_id); ?>"></span>

Step 3: Add JavaScript to Load Statuses

Add this to your theme's main JS file (or enqueue it via functions.php):

document.addEventListener('DOMContentLoaded', () => {
    const placeholders = document.querySelectorAll('.restaurant-status-placeholder');
    
    placeholders.forEach(placeholder => {
        const restaurantId = placeholder.dataset.restaurantId;
        // Create a nonce for security (add this line to your PHP template if needed)
        const nonce = '<?php echo wp_create_nonce("restaurant_status_nonce"); ?>';

        fetch('/wp-admin/admin-ajax.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-WP-Nonce': nonce
            },
            body: `action=get_restaurant_status&restaurant_id=${restaurantId}`
        })
        .then(res => res.json())
        .then(data => {
            if (data.success) {
                placeholder.innerHTML = data.data.html;
            } else {
                placeholder.innerHTML = '<span class="restaurant-status error">Status Unavailable</span>';
            }
        })
        .catch(() => {
            placeholder.innerHTML = '<span class="restaurant-status error">Status Unavailable</span>';
        });
    });
});

This loads each status dynamically after the cached page renders, so the rest of the page stays cached while the statuses update in real-time.

3. Per-Restaurant Transient Caching (Balanced Performance)

If you want to avoid AJAX and still keep performance high, use WordPress transients to cache individual restaurant statuses with a short expiration window. This way, you don't hit your open_close_status function on every page load, but the statuses still update regularly.

Add this wrapper function to functions.php:

function get_cached_restaurant_status($restaurant_id) {
    // Unique transient key for each restaurant
    $transient_key = 'restaurant_status_' . $restaurant_id;
    $status = get_transient($transient_key);

    // If transient doesn't exist, generate and cache the status
    if ($status === false) {
        $status = open_close_status($restaurant_id);
        // Cache for 5 minutes (adjust based on how often hours change)
        set_transient($transient_key, $status, 5 * MINUTE_IN_SECONDS);
    }

    return $status;
}

Then update your template code:

$status = get_cached_restaurant_status($restaurant_id);
<span class="restaurant-status <?php echo esc_attr($status); ?>"><?php echo esc_html($status); ?></span>

This balances dynamic updates with performance—each status is cached for a short time, so your server doesn't get overloaded, but the labels will refresh within the expiration window.


内容的提问来源于stack exchange,提问作者Tod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:47:38