WordPress功能开发求助:点击服务页按钮解锁用户仪表盘隐藏内容
解决方案:修复WordPress仪表盘服务容器刷新/重登后保持可见的问题
你的现有代码已经实现了点击按钮更新用户元数据并实时显示容器,但缺少页面加载时读取用户元数据初始化容器状态的逻辑,导致刷新或重新登录后容器又变回隐藏状态。以下是完整的修复方案:
1. 前端:页面加载时初始化容器可见状态
修改JavaScript代码,在页面加载完成后先根据用户已解锁的服务状态初始化容器显示,同时保留原有点击解锁逻辑:
jQuery(document).ready(function($) { // 页面加载时,根据后端传递的已解锁服务列表初始化容器 if (my_ajax_object.visible_services) { my_ajax_object.visible_services.forEach(serviceId => { $('#service-' + serviceId).removeClass('hidden-service'); }); } // 点击按钮解锁服务的原有逻辑 $('.unhide-service-btn').on('click', function(e) { e.preventDefault(); const serviceId = $(this).data('service-id'); $.ajax({ url: my_ajax_object.ajax_url, type: 'POST', data: { action: 'unhide_service', serviceId: serviceId, nonce: my_ajax_object.nonce }, success: function(response) { if (response.success) { $('#service-' + serviceId).removeClass('hidden-service'); // 同步更新本地的已解锁列表,避免刷新前状态不一致 if (!my_ajax_object.visible_services.includes(serviceId)) { my_ajax_object.visible_services.push(serviceId); } } }, error: function(xhr, status, error) { console.log('解锁失败:', status, error); } }); }); });
2. 后端:传递已解锁服务状态到前端
修改PHP的脚本本地化函数,把当前用户已解锁的服务ID列表传递给前端,避免额外AJAX请求:
function enqueue_custom_scripts() { wp_enqueue_script('custom-js', get_template_directory_uri() . '/js/custom.js', array('jquery'), null, true); // 获取当前用户已解锁的服务列表 $visible_services = array(); if (is_user_logged_in()) { $user_id = get_current_user_id(); // 这里替换成你实际的服务ID集合,比如从自定义字段/数据库查询 $all_service_ids = array('service1', 'service2', 'service3'); foreach ($all_service_ids as $service_id) { if (get_user_meta($user_id, 'visible_service_' . $service_id, true)) { $visible_services[] = $service_id; } } } wp_localize_script('custom-js', 'my_ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('unhide_service_nonce'), 'visible_services' => $visible_services // 新增:传递已解锁服务ID )); } add_action('wp_enqueue_scripts', 'enqueue_custom_scripts'); // 保留原有的AJAX回调函数 function unhide_service_callback() { check_ajax_referer('unhide_service_nonce', 'nonce'); $service_id = isset($_POST['serviceId']) ? sanitize_text_field($_POST['serviceId']) : ''; if ($service_id && is_user_logged_in()) { $user_id = get_current_user_id(); update_user_meta($user_id, 'visible_service_' . $service_id, true); } wp_send_json_success(); } add_action('wp_ajax_unhide_service', 'unhide_service_callback');
3. 可选:后端渲染时直接控制容器类名
如果你的仪表盘容器是通过PHP模板渲染的,直接在模板里判断用户元数据输出类名,比前端JS初始化更可靠:
<?php $target_service_id = 'service1'; // 替换为实际服务ID $is_service_visible = get_user_meta(get_current_user_id(), 'visible_service_' . $target_service_id, true); $container_classes = $is_service_visible ? '' : 'hidden-service'; ?> <div id="service-<?php echo esc_attr($target_service_id); ?>" class="<?php echo esc_attr($container_classes); ?>"> <!-- 服务容器内容 --> </div>
关键修复说明
- 状态持久化:通过后端传递已解锁服务列表,确保页面刷新、用户重登后容器状态正确。
- 登录校验:所有用户元数据操作都加上
is_user_logged_in()判断,避免未登录用户的无效请求。 - 性能优化:后端直接传递状态,避免前端额外发起AJAX请求初始化页面。
内容的提问来源于stack exchange,提问作者Adeyemi Oyinlola
相关产品推荐
相关产品推荐

