WordPress短代码无法更新动态数据问题求助
捐赠进度条动态数据无法更新的问题
我开发了一款捐赠类WordPress插件,其中添加了一个从数据库读取数值的进度条。将短代码添加至/sample-page/页面后,即便后续更新数据库内的数值,页面显示的数值也不会改变;只有修改URL(如/sample-page/?something=s)才会加载新内容,之后数据库数值再次变更时,仍需修改URL才能渲染最新内容。
相关代码
add_shortcode( $this->donationProgressShortCode, array($this,'progressBarShortCode')); function progressBarShortCode($params){ if(!isset($params['id']) || !$params['id']){ return 'ID NOT PROVIDED'; } $model = new Donation(); $donation = $model->getDonation($params['id']); if(!$donation){ return; } $target = $donation->target; if($target <= 0){ return; } $total = 0; $percentage = 0; $transactions = $model->getTransactions($params['id']); if($transactions){ foreach($transactions as $item){ // error_log('ITEMS HERE MAN: '.json_encode($item)); $total+= $item->amount; } } if($total > 0){ $percentage = ($total * 100) / $target; } wp_enqueue_style('tz_payment_gateway_style', $this->pluginUrl . 'assets/style/checkout-style.css'); $content = '<div style="width: 100%; padding: 2px"> <div style="display: flex; justify-content-between; font-weight: bold"> <div style="width: 100%;">'.$total.'<small>'.$donation->currency.'</small></div> <div style="width: 100%; text-align: right">'.$target.'<small>'.$donation->currency.'</small></div> </div> <div style="position: relative; background-color: #ccc9; border-radius: 5px; overflow: hidden; height: 18px"> <div style="transition: 11.5s all ease-in; height: 18px; background-color: '.$donation->background_color.'; position: absolute; width:'.($percentage> 100? 100: $percentage).'%; color: transparent">.</div> <div style="height: 18px; line-height: 18px; text-shadow: 1px 1px 2px black; color: #fff; width: 100%; position: absolute; text-align: center;">'.$percentage.'%</div> </div> </div>'; return $content; }
实现逻辑
读取数据库中所有已支付交易记录,基于目标金额计算百分比,最终渲染出进度条:
解决方案
问题根源
WordPress的页面缓存(内置静态缓存或第三方缓存插件)会将短代码的输出缓存,导致数据库更新后页面仍显示旧内容,只有URL变化时才会生成新的缓存。
方案1:使用Transients缓存交易数据并实时更新
通过WordPress的Transients API缓存交易总额,同时在新交易完成时清除对应缓存,平衡性能与实时性:
- 修改短代码中的总额计算部分:
$transient_key = 'donation_total_' . $params['id']; $total = get_transient($transient_key); if (false === $total) { $total = 0; $transactions = $model->getTransactions($params['id']); if($transactions){ foreach($transactions as $item){ $total+= $item->amount; } } // 设置5分钟过期,可根据需求调整 set_transient($transient_key, $total, 5 * MINUTE_IN_SECONDS); }
- 在交易完成的处理函数中添加缓存清理:
// 假设$donation_id是当前捐赠的ID delete_transient('donation_total_' . $donation_id);
方案2:AJAX动态加载进度条内容
彻底绕过页面缓存,通过前端AJAX实时请求最新数据:
- 修改短代码函数,输出容器并注册AJAX脚本:
function progressBarShortCode($params){ if(!isset($params['id']) || !$params['id']){ return 'ID NOT PROVIDED'; } wp_enqueue_style('tz_payment_gateway_style', $this->pluginUrl . 'assets/style/checkout-style.css'); // 注册AJAX脚本 wp_enqueue_script('donation-progress-script', $this->pluginUrl . 'assets/js/progress-script.js', array('jquery'), '1.0', true); // 传递AJAX地址和捐赠ID wp_localize_script('donation-progress-script', 'donationProgress', array( 'ajax_url' => admin_url('admin-ajax.php'), 'donation_id' => $params['id'] )); return '<div class="donation-progress-container" data-id="'.$params['id'].'"></div>'; }
- 创建
assets/js/progress-script.js文件:
jQuery(document).ready(function($){ function loadProgressBar() { var container = $('.donation-progress-container'); var donationId = container.data('id'); $.ajax({ url: donationProgress.ajax_url, type: 'POST', data: { action: 'get_donation_progress', donation_id: donationId }, success: function(response) { if(response.success) { container.html(response.data); } }, error: function() { container.html('加载进度失败'); } }); } // 页面加载时获取进度 loadProgressBar(); // 每30秒自动刷新一次(可选) setInterval(loadProgressBar, 30000); });
- 添加AJAX处理函数(放在插件主文件中):
// 处理前台AJAX请求 add_action('wp_ajax_get_donation_progress', 'get_donation_progress'); add_action('wp_ajax_nopriv_get_donation_progress', 'get_donation_progress'); function get_donation_progress() { if(!isset($_POST['donation_id']) || !$_POST['donation_id']){ wp_send_json_error('ID NOT PROVIDED'); } $model = new Donation(); $donation = $model->getDonation($_POST['donation_id']); if(!$donation){ wp_send_json_error('捐赠不存在'); } $target = $donation->target; if($target <= 0){ wp_send_json_error('目标金额无效'); } $total = 0; $percentage = 0; $transactions = $model->getTransactions($_POST['donation_id']); if($transactions){ foreach($transactions as $item){ $total+= $item->amount; } } if($total > 0){ $percentage = ($total * 100) / $target; } $content = '<div style="width: 100%; padding: 2px"> <div style="display: flex; justify-content-between; font-weight: bold"> <div style="width: 100%;">'.$total.'<small>'.$donation->currency.'</small></div> <div style="width: 100%; text-align: right">'.$target.'<small>'.$donation->currency.'</small></div> </div> <div style="position: relative; background-color: #ccc9; border-radius: 5px; overflow: hidden; height: 18px"> <div style="transition: 11.5s all ease-in; height: 18px; background-color: '.$donation->background_color.'; position: absolute; width:'.($percentage> 100? 100: $percentage).'%; color: transparent">.</div> <div style="height: 18px; line-height: 18px; text-shadow: 1px 1px 2px black; color: #fff; width: 100%; position: absolute; text-align: center;">'.$percentage.'%</div> </div> </div>'; wp_send_json_success($content); }
内容的提问来源于stack exchange,提问作者Anseloh
相关产品推荐
相关产品推荐

