文章目录[隐藏]
手把手教程:为WordPress实现基于用户行为的个性化弹窗与推荐工具
引言:个性化体验在网站运营中的重要性
在当今互联网环境中,用户期望获得与其兴趣和行为高度相关的个性化体验。根据Monetate的研究,93%的企业表示个性化策略显著提高了收入。对于WordPress网站而言,实现基于用户行为的个性化弹窗和推荐工具不仅能提升用户体验,还能有效提高转化率、延长页面停留时间并增强用户粘性。
本教程将详细指导您如何通过WordPress代码二次开发,实现基于用户行为的个性化弹窗与推荐工具。我们将从基础概念讲起,逐步深入到具体实现,最终打造一个完整的个性化推荐系统。
第一部分:个性化系统基础架构设计
1.1 理解用户行为数据收集
在开始开发之前,我们需要明确要收集哪些用户行为数据。常见的用户行为数据包括:
- 页面浏览历史
- 点击行为
- 停留时间
- 滚动深度
- 搜索关键词
- 购买/下载历史
- 设备类型和地理位置
1.2 系统架构设计
我们的个性化系统将包含以下核心组件:
- 数据收集模块:通过JavaScript和PHP收集用户行为数据
- 数据处理模块:分析用户行为并生成用户画像
- 存储模块:将用户数据存储在数据库中
- 推荐引擎:根据用户画像生成个性化内容
- 弹窗与推荐展示模块:在适当时机展示个性化内容
1.3 技术栈选择
- 前端:JavaScript (原生或jQuery)、CSS3、HTML5
- 后端:PHP (WordPress核心)、MySQL
- 数据存储:WordPress自定义表、Transients API、Cookies
- 推荐算法:基于内容的过滤、协同过滤简化版
第二部分:搭建用户行为追踪系统
2.1 创建数据库表存储用户行为
首先,我们需要创建一个自定义数据库表来存储用户行为数据。在您的主题的functions.php文件中添加以下代码:
// 创建用户行为追踪表
function create_user_behavior_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'user_behavior';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id varchar(100) NOT NULL,
session_id varchar(100) NOT NULL,
behavior_type varchar(50) NOT NULL,
behavior_value text NOT NULL,
page_url varchar(500) NOT NULL,
timestamp datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY behavior_type (behavior_type),
KEY timestamp (timestamp)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
add_action('after_setup_theme', 'create_user_behavior_table');
2.2 实现用户识别系统
为了追踪匿名用户和登录用户的行为,我们需要创建一个用户识别系统:
// 生成或获取用户唯一标识
function get_user_identifier() {
$identifier = '';
// 检查是否已登录
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$identifier = 'user_' . $user_id;
} else {
// 对于匿名用户,使用cookie存储的标识符
if (isset($_COOKIE['wp_visitor_id'])) {
$identifier = 'visitor_' . $_COOKIE['wp_visitor_id'];
} else {
// 生成新的唯一标识符
$visitor_id = wp_generate_uuid4();
setcookie('wp_visitor_id', $visitor_id, time() + (365 * 24 * 60 * 60), '/');
$identifier = 'visitor_' . $visitor_id;
}
}
return $identifier;
}
// 生成UUID4
function wp_generate_uuid4() {
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
2.3 前端行为追踪脚本
创建一个JavaScript文件来收集用户行为数据:
// 文件路径: /wp-content/themes/your-theme/js/user-behavior-tracker.js
(function() {
'use strict';
// 用户行为追踪对象
var UserBehaviorTracker = {
// 配置
config: {
endpoint: '/wp-admin/admin-ajax.php',
trackingInterval: 30000, // 30秒发送一次数据
scrollThresholds: [25, 50, 75, 90]
},
// 存储待发送的数据
pendingData: [],
// 初始化
init: function() {
this.bindEvents();
this.startPeriodicTracking();
this.trackPageView();
},
// 绑定事件
bindEvents: function() {
// 点击事件
document.addEventListener('click', this.trackClick.bind(this));
// 滚动事件
var scrollTimeout;
window.addEventListener('scroll', function() {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
UserBehaviorTracker.trackScroll();
}, 500);
});
// 表单提交事件
document.addEventListener('submit', this.trackFormSubmit.bind(this));
// 页面离开事件
window.addEventListener('beforeunload', this.sendPendingData.bind(this, true));
},
// 追踪页面浏览
trackPageView: function() {
var pageData = {
behavior_type: 'page_view',
behavior_value: JSON.stringify({
page_title: document.title,
referrer: document.referrer || '',
screen_resolution: window.screen.width + 'x' + window.screen.height,
viewport_size: window.innerWidth + 'x' + window.innerHeight
}),
page_url: window.location.href
};
this.addToPendingData(pageData);
},
// 追踪点击事件
trackClick: function(event) {
var target = event.target;
var clickableElement = this.findClickableElement(target);
if (clickableElement) {
var clickData = {
behavior_type: 'click',
behavior_value: JSON.stringify({
element_type: clickableElement.tagName,
element_id: clickableElement.id || '',
element_class: clickableElement.className || '',
element_text: this.getElementText(clickableElement).substring(0, 100),
element_href: clickableElement.href || ''
}),
page_url: window.location.href
};
this.addToPendingData(clickData);
}
},
// 追踪滚动深度
trackScroll: function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var scrollPercentage = scrollHeight > 0 ? Math.round((scrollTop / scrollHeight) * 100) : 0;
// 检查是否达到阈值
for (var i = 0; i < this.config.scrollThresholds.length; i++) {
var threshold = this.config.scrollThresholds[i];
if (scrollPercentage >= threshold && scrollPercentage < threshold + 5) {
var scrollData = {
behavior_type: 'scroll',
behavior_value: JSON.stringify({
scroll_percentage: scrollPercentage,
scroll_position: scrollTop,
page_height: scrollHeight
}),
page_url: window.location.href
};
this.addToPendingData(scrollData);
break;
}
}
},
// 追踪表单提交
trackFormSubmit: function(event) {
var form = event.target;
var formData = {
behavior_type: 'form_submit',
behavior_value: JSON.stringify({
form_id: form.id || '',
form_class: form.className || '',
form_action: form.action || ''
}),
page_url: window.location.href
};
this.addToPendingData(formData);
},
// 辅助方法:查找可点击元素
findClickableElement: function(element) {
var clickableTags = ['A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
while (element && element !== document) {
if (clickableTags.indexOf(element.tagName) !== -1) {
return element;
}
element = element.parentNode;
}
return null;
},
// 辅助方法:获取元素文本
getElementText: function(element) {
return element.innerText || element.textContent || '';
},
// 添加到待发送数据
addToPendingData: function(data) {
this.pendingData.push(data);
// 如果数据量较大,立即发送
if (this.pendingData.length >= 10) {
this.sendPendingData();
}
},
// 发送待处理数据
sendPendingData: function(sync) {
if (this.pendingData.length === 0) return;
var dataToSend = this.pendingData.slice();
this.pendingData = [];
var requestData = {
action: 'save_user_behavior',
behaviors: dataToSend
};
if (sync) {
// 同步发送(用于页面离开时)
this.sendRequestSync(requestData);
} else {
// 异步发送
this.sendRequestAsync(requestData);
}
},
// 异步发送请求
sendRequestAsync: function(data) {
var xhr = new XMLHttpRequest();
xhr.open('POST', this.config.endpoint, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status !== 200) {
console.error('行为数据发送失败:', xhr.statusText);
}
}
};
xhr.send(this.serializeData(data));
},
// 同步发送请求
sendRequestSync: function(data) {
var xhr = new XMLHttpRequest();
xhr.open('POST', this.config.endpoint, false);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(this.serializeData(data));
},
// 序列化数据
serializeData: function(obj) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(
typeof obj[p] === 'object' ? JSON.stringify(obj[p]) : obj[p]
));
}
}
return str.join("&");
},
// 开始定期追踪
startPeriodicTracking: function() {
setInterval(this.sendPendingData.bind(this), this.config.trackingInterval);
}
};
// 初始化追踪器
document.addEventListener('DOMContentLoaded', function() {
UserBehaviorTracker.init();
});
// 暴露到全局作用域
window.UserBehaviorTracker = UserBehaviorTracker;
})();
2.4 后端数据处理接口
在functions.php中添加处理前端发送的行为数据的代码:
// 保存用户行为数据
function save_user_behavior_callback() {
// 验证nonce
if (!check_ajax_referer('user_behavior_nonce', 'security', false)) {
wp_die('安全验证失败', 403);
}
// 获取用户标识符
$user_identifier = get_user_identifier();
// 获取session ID
$session_id = session_id();
if (empty($session_id)) {
session_start();
$session_id = session_id();
}
// 获取行为数据
$behaviors = json_decode(stripslashes($_POST['behaviors']), true);
if (is_array($behaviors)) {
global $wpdb;
$table_name = $wpdb->prefix . 'user_behavior';
foreach ($behaviors as $behavior) {
$wpdb->insert(
$table_name,
array(
'user_id' => $user_identifier,
'session_id' => $session_id,
'behavior_type' => sanitize_text_field($behavior['behavior_type']),
'behavior_value' => sanitize_text_field($behavior['behavior_value']),
'page_url' => esc_url_raw($behavior['page_url'])
),
array('%s', '%s', '%s', '%s', '%s')
);
}
wp_send_json_success(array('message' => '行为数据保存成功', 'count' => count($behaviors)));
} else {
wp_send_json_error('无效的行为数据格式');
}
}
add_action('wp_ajax_save_user_behavior', 'save_user_behavior_callback');
add_action('wp_ajax_nopriv_save_user_behavior', 'save_user_behavior_callback');
// 注册并加载追踪脚本
function enqueue_user_behavior_tracker() {
// 注册脚本
wp_register_script(
'user-behavior-tracker',
get_template_directory_uri() . '/js/user-behavior-tracker.js',
array(),
'1.0.0',
true
);
// 本地化脚本,传递必要数据
wp_localize_script('user-behavior-tracker', 'userBehaviorTrackerVars', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('user_behavior_nonce')
));
// 加载脚本
wp_enqueue_script('user-behavior-tracker');
}
add_action('wp_enqueue_scripts', 'enqueue_user_behavior_tracker');
第三部分:构建用户画像系统
3.1 分析用户行为数据
创建用户画像分析函数,定期分析用户行为并生成用户标签:
// 分析用户行为并生成用户画像
function analyze_user_profile($user_identifier, $days = 30) {
global $wpdb;
$table_name = $wpdb->prefix . 'user_behavior';
// 获取用户最近的行为数据
$date_limit = date('Y-m-d H:i:s', strtotime("-$days days"));
$behaviors = $wpdb->get_results($wpdb->prepare(
"SELECT behavior_type, behavior_value, page_url, timestamp
FROM $table_name
WHERE user_id = %s AND timestamp >= %s
ORDER BY timestamp DESC",
$user_identifier,
$date_limit
));
if (empty($behaviors)) {
return false;
}
$profile = array(
'interests' => array(),
'behavior_patterns' => array(),
'preferred_categories' => array(),
'preferred_tags' => array(),
'engagement_level' => 'low',
'last_activity' => $behaviors[0]->timestamp,
'total_visits' => 0,
'avg_session_duration' => 0
);
// 分析页面浏览和兴趣
$page_views = array();
$category_views = array();
$tag_views = array();
foreach ($behaviors as $behavior) {
if ($behavior->behavior_type === 'page_view') {
$profile['total_visits']++;
// 解析页面URL,获取分类和标签信息
$post_id = url_to_postid($behavior->page_url);
if ($post_id) {
// 获取分类
$categories = wp_get_post_categories($post_id);
foreach ($categories as $cat_id) {
$category = get_category($cat_id);
if ($category) {
if (!isset($category_views[$category->slug])) {
$category_views[$category->slug] = 0;
}
$category_views[$category->slug]++;
}
}
// 获取标签
$tags = wp_get_post_tags($post_id);
foreach ($tags as $tag) {
if (!isset($tag_views[$tag->slug])) {
$tag_views[$tag->slug] = 0;
}
$tag_views[$tag->slug]++;
}
}
}
}
// 确定最感兴趣的分类
arsort($category_views);
$profile['preferred_categories'] = array_slice(array_keys($category_views), 0, 5);
// 确定最感兴趣的标签
arsort($tag_views);
$profile['preferred_tags'] = array_slice(array_keys($tag_views), 0, 10);
// 分析参与度
$total_duration = 0;
$session_count = 0;
$current_session = array();
$last_timestamp = null;
foreach ($behaviors as $index => $behavior) {
if ($last_timestamp) {
$time_diff = strtotime($last_timestamp) - strtotime($behavior->timestamp);
// 如果时间差小于30分钟,视为同一会话
if ($time_diff < 1800) {
if (empty($current_session)) {
$current_session[] = $last_timestamp;
}
$current_session[] = $behavior->timestamp;
} else {
// 会话结束,计算持续时间
if (!empty($current_session)) {
$session_start = strtotime(end($current_session));
$session_end = strtotime($current_session[0]);
$total_duration += $session_duration;
$session_count++;
$current_session = array();
}
}
}
$last_timestamp = $behavior->timestamp;
}
// 处理最后一个会话
if (!empty($current_session)) {
$session_start = strtotime(end($current_session));
$session_end = strtotime($current_session[0]);
$session_duration = $session_end - $session_start;
$total_duration += $session_duration;
$session_count++;
}
// 计算平均会话时长
if ($session_count > 0) {
$profile['avg_session_duration'] = round($total_duration / $session_count);
// 确定参与度等级
if ($profile['avg_session_duration'] > 600) { // 10分钟以上
$profile['engagement_level'] = 'high';
} elseif ($profile['avg_session_duration'] > 180) { // 3-10分钟
$profile['engagement_level'] = 'medium';
}
}
// 分析点击行为模式
$click_patterns = array();
foreach ($behaviors as $behavior) {
if ($behavior->behavior_type === 'click') {
$click_data = json_decode($behavior->behavior_value, true);
if ($click_data && isset($click_data['element_type'])) {
$element_type = $click_data['element_type'];
if (!isset($click_patterns[$element_type])) {
$click_patterns[$element_type] = 0;
}
$click_patterns[$element_type]++;
}
}
}
$profile['behavior_patterns'] = $click_patterns;
// 分析滚动深度
$scroll_data = array();
foreach ($behaviors as $behavior) {
if ($behavior->behavior_type === 'scroll') {
$scroll_info = json_decode($behavior->behavior_value, true);
if ($scroll_info && isset($scroll_info['scroll_percentage'])) {
$scroll_data[] = $scroll_info['scroll_percentage'];
}
}
}
if (!empty($scroll_data)) {
$profile['avg_scroll_depth'] = round(array_sum($scroll_data) / count($scroll_data));
}
return $profile;
}
// 获取或生成用户画像
function get_user_profile($user_identifier, $force_refresh = false) {
$transient_key = 'user_profile_' . md5($user_identifier);
// 如果不需要强制刷新且存在缓存的画像,直接返回
if (!$force_refresh) {
$cached_profile = get_transient($transient_key);
if ($cached_profile !== false) {
return $cached_profile;
}
}
// 分析用户行为生成新画像
$profile = analyze_user_profile($user_identifier);
if ($profile) {
// 缓存用户画像12小时
set_transient($transient_key, $profile, 12 * HOUR_IN_SECONDS);
// 同时存储到用户元数据(如果用户已登录)
if (strpos($user_identifier, 'user_') === 0) {
$user_id = str_replace('user_', '', $user_identifier);
update_user_meta($user_id, 'personalization_profile', $profile);
}
}
return $profile;
}
3.2 创建用户画像管理界面
为了方便查看和管理用户画像,我们可以创建一个简单的管理界面:
// 添加用户画像管理菜单
function add_user_profiles_admin_menu() {
add_menu_page(
'用户画像分析',
'用户画像',
'manage_options',
'user-profiles',
'display_user_profiles_page',
'dashicons-admin-users',
30
);
}
add_action('admin_menu', 'add_user_profiles_admin_menu');
// 显示用户画像页面
function display_user_profiles_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'user_behavior';
// 获取所有用户标识符
$user_identifiers = $wpdb->get_col("SELECT DISTINCT user_id FROM $table_name ORDER BY user_id");
echo '<div class="wrap">';
echo '<h1>用户画像分析</h1>';
if (empty($user_identifiers)) {
echo '<p>暂无用户行为数据。</p>';
return;
}
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr>
<th>用户ID</th>
<th>最后活动</th>
<th>访问次数</th>
<th>兴趣分类</th>
<th>兴趣标签</th>
<th>参与度</th>
<th>操作</th>
</tr></thead>';
echo '<tbody>';
foreach ($user_identifiers as $identifier) {
$profile = get_user_profile($identifier);
if (!$profile) {
continue;
}
echo '<tr>';
echo '<td>' . esc_html($identifier) . '</td>';
echo '<td>' . esc_html($profile['last_activity']) . '</td>';
echo '<td>' . esc_html($profile['total_visits']) . '</td>';
echo '<td>' . esc_html(implode(', ', $profile['preferred_categories'])) . '</td>';
echo '<td>' . esc_html(implode(', ', array_slice($profile['preferred_tags'], 0, 3))) . '...</td>';
echo '<td>' . esc_html($profile['engagement_level']) . ' (' . esc_html($profile['avg_session_duration']) . '秒)</td>';
echo '<td><button class="button button-small view-profile-details" data-user="' . esc_attr($identifier) . '">查看详情</button></td>';
echo '</tr>';
}
echo '</tbody></table>';
// 添加详情模态框
echo '<div id="profile-details-modal" style="display:none;">
<div id="profile-details-content"></div>
</div>';
// 添加JavaScript
echo '<script>
jQuery(document).ready(function($) {
$(".view-profile-details").click(function() {
var userIdentifier = $(this).data("user");
$.ajax({
url: ajaxurl,
type: "POST",
data: {
action: "get_user_profile_details",
user_identifier: userIdentifier
},
success: function(response) {
if (response.success) {
$("#profile-details-content").html(response.data);
$("#profile-details-modal").dialog({
modal: true,
width: 800,
height: 600,
title: "用户画像详情 - " + userIdentifier
});
}
}
});
});
});
</script>';
echo '</div>';
}
// AJAX获取用户画像详情
function get_user_profile_details_callback() {
$user_identifier = sanitize_text_field($_POST['user_identifier']);
$profile = get_user_profile($user_identifier, true);
if (!$profile) {
wp_send_json_error('未找到用户画像数据');
}
$html = '<div class="user-profile-details">';
$html .= '<h3>基本信息</h3>';
$html .= '<p><strong>最后活动:</strong> ' . esc_html($profile['last_activity']) . '</p>';
$html .= '<p><strong>总访问次数:</strong> ' . esc_html($profile['total_visits']) . '</p>';
$html .= '<p><strong>平均会话时长:</strong> ' . esc_html($profile['avg_session_duration']) . ' 秒</p>';
$html .= '<p><strong>参与度等级:</strong> ' . esc_html($profile['engagement_level']) . '</p>';
if (isset($profile['avg_scroll_depth'])) {
$html .= '<p><strong>平均滚动深度:</strong> ' . esc_html($profile['avg_scroll_depth']) . '%</p>';
}
$html .= '<h3>兴趣分类</h3>';
$html .= '<ul>';
foreach ($profile['preferred_categories'] as $category) {
$html .= '<li>' . esc_html($category) . '</li>';
}
$html .= '</ul>';
$html .= '<h3>兴趣标签</h3>';
$html .= '<ul>';
foreach ($profile['preferred_tags'] as $tag) {
$html .= '<li>' . esc_html($tag) . '</li>';
}
$html .= '</ul>';
$html .= '<h3>行为模式</h3>';
if (!empty($profile['behavior_patterns'])) {
$html .= '<ul>';
foreach ($profile['behavior_patterns'] as $element_type => $count) {
$html .= '<li><strong>' . esc_html($element_type) . ':</strong> ' . esc_html($count) . ' 次点击</li>';
}
$html .= '</ul>';
} else {
$html .= '<p>暂无行为模式数据</p>';
}
$html .= '</div>';
wp_send_json_success($html);
}
add_action('wp_ajax_get_user_profile_details', 'get_user_profile_details_callback');
第四部分:实现个性化推荐引擎
4.1 基于内容的推荐算法
// 获取个性化推荐内容
function get_personalized_recommendations($user_identifier, $limit = 5) {
$profile = get_user_profile($user_identifier);
if (!$profile || empty($profile['preferred_categories']) || empty($profile['preferred_tags'])) {
// 如果没有用户画像,返回热门内容
return get_popular_posts($limit);
}
// 构建推荐查询
$args = array(
'post_type' => 'post',
'posts_per_page' => $limit,
'post_status' => 'publish',
'orderby' => 'relevance',
'meta_query' => array(
'relation' => 'OR'
),
'tax_query' => array(
'relation' => 'OR'
)
);
// 添加分类查询
if (!empty($profile['preferred_categories'])) {
$args['tax_query'][] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $profile['preferred_categories'],
'operator' => 'IN'
);
}
// 添加标签查询
if (!empty($profile['preferred_tags'])) {
$args['tax_query'][] = array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => $profile['preferred_tags'],
'operator' => 'IN'
);
}
// 排除用户已经看过的文章
$viewed_posts = get_user_viewed_posts($user_identifier);
if (!empty($viewed_posts)) {
$args['post__not_in'] = $viewed_posts;
}
// 根据参与度调整时间范围
if ($profile['engagement_level'] === 'high') {
// 高参与度用户:显示更广泛的内容
$args['date_query'] = array(
array(
'after' => '3 months ago'
)
);
} elseif ($profile['engagement_level'] === 'medium') {
// 中等参与度用户:显示近期热门内容
$args['date_query'] = array(
array(
'after' => '1 month ago'
)
);
$args['orderby'] = 'comment_count';
} else {
// 低参与度用户:显示最新内容
$args['orderby'] = 'date';
$args['order'] = 'DESC';
}
// 执行查询
$recommendations_query = new WP_Query($args);
if ($recommendations_query->have_posts()) {
return $recommendations_query->posts;
} else {
// 如果查询无结果,返回备用推荐
return get_fallback_recommendations($limit);
}
}
// 获取用户已浏览的文章
function get_user_viewed_posts($user_identifier, $limit = 50) {
global $wpdb;
$table_name = $wpdb->prefix . 'user_behavior';
$viewed_urls = $wpdb->get_col($wpdb->prepare(
"SELECT DISTINCT page_url
FROM $table_name
WHERE user_id = %s AND behavior_type = 'page_view'
ORDER BY timestamp DESC
LIMIT %d",
$user_identifier,
$limit
));
$viewed_posts = array();
foreach ($viewed_urls as $url) {
$post_id = url_to_postid($url);
if ($post_id) {
$viewed_posts[] = $post_id;
}
}
return array_unique($viewed_posts);
}
// 获取热门文章(备用推荐)
function get_popular_posts($limit = 5) {
$args = array(
'post_type' => 'post',
'posts_per_page' => $limit,
'post_status' => 'publish',
'orderby' => 'comment_count',
'order' => 'DESC',
'date_query' => array(
array(
'after' => '1 month ago'
)
)
);
$query = new WP_Query($args);
return $query->posts;
}
// 获取备用推荐(当个性化推荐不足时)
function get_fallback_recommendations($limit = 5) {
// 策略1:获取编辑推荐的文章
$editor_picks = get_posts(array(
'post_type' => 'post',
'posts_per_page' => $limit,
'post_status' => 'publish',
'meta_key' => 'editor_pick',
'meta_value' => '1',
'orderby' => 'date',
'order' => 'DESC'
));
if (count($editor_picks) >= $limit) {
return $editor_picks;
}
// 策略2:获取最新文章补充
$latest_posts = get_posts(array(
'post_type' => 'post',
'posts_per_page' => $limit - count($editor_picks),
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'post__not_in' => wp_list_pluck($editor_picks, 'ID')
));
return array_merge($editor_picks, $latest_posts);
}
4.2 实时推荐API
创建实时推荐API,供前端动态获取推荐内容:
// 实时推荐API
function get_realtime_recommendations_callback() {
// 验证nonce
if (!check_ajax_referer('recommendations_nonce', 'security', false)) {
wp_send_json_error('安全验证失败');
}
$user_identifier = get_user_identifier();
$limit = isset($_POST['limit']) ? intval($_POST['limit']) : 5;
$context = isset($_POST['context']) ? sanitize_text_field($_POST['context']) : 'general';
// 根据上下文调整推荐策略
$recommendations = get_personalized_recommendations($user_identifier, $limit);
// 格式化推荐结果
$formatted_recommendations = array();
foreach ($recommendations as $post) {
$formatted_recommendations[] = array(
'id' => $post->ID,
'title' => get_the_title($post),
'excerpt' => wp_trim_words(get_the_excerpt($post), 20),
'url' => get_permalink($post),
'image' => get_the_post_thumbnail_url($post, 'medium'),
'date' => get_the_date('', $post),
'categories' => wp_get_post_categories($post->ID, array('fields' => 'names'))
);
}
// 添加推荐原因
$profile = get_user_profile($user_identifier);
$reason = '根据您的浏览历史为您推荐';
if ($profile && !empty($profile['preferred_categories'])) {
$reason = '基于您对' . implode('、', array_slice($profile['preferred_categories'], 0, 2)) . '的兴趣推荐';
}
wp_send_json_success(array(
'recommendations' => $formatted_recommendations,
'reason' => $reason,
'context' => $context
));
}
add_action('wp_ajax_get_realtime_recommendations', 'get_realtime_recommendations_callback');
add_action('wp_ajax_nopriv_get_realtime_recommendations', 'get_realtime_recommendations_callback');
第五部分:实现个性化弹窗系统
5.1 弹窗触发条件与规则引擎
// 弹窗规则引擎
class Personalized_Popup_Rules {
private $user_identifier;
private $user_profile;
private $current_page;
public function __construct() {
$this->user_identifier = get_user_identifier();
$this->user_profile = get_user_profile($this->user_identifier);
$this->current_page = $this->get_current_page_info();
}
// 获取当前页面信息
private function get_current_page_info() {
global $post;
$page_info = array(
'id' => get_the_ID(),
'type' => get_post_type(),
'url' => get_permalink(),
'categories' => array(),
'tags' => array()
);
if ($post) {
$page_info['categories'] = wp_get_post_categories($post->ID, array('fields' => 'slugs'));
$page_info['tags'] = wp_get_post_tags($post->ID, array('fields' => 'slugs'));
}
return $page_info;
}
