首页 / 应用软件 / WordPress开发教程,集成网站自动化数据采集与信息聚合工具

WordPress开发教程,集成网站自动化数据采集与信息聚合工具

WordPress开发教程:集成网站自动化数据采集与信息聚合工具,通过WordPress程序的代码二次开发实现常用互联网小工具功能

引言:WordPress的无限可能

在当今数字化时代,网站已不仅仅是信息展示的窗口,更是功能集成与服务的平台。WordPress作为全球最受欢迎的内容管理系统,占据了互联网上超过43%的网站份额。然而,许多用户仅将其视为简单的博客或内容发布工具,未能充分挖掘其作为强大开发平台的潜力。

实际上,通过代码二次开发,WordPress可以转型为功能丰富的应用平台,集成自动化数据采集、信息聚合以及各种实用小工具。本教程将深入探讨如何通过WordPress开发,实现网站自动化数据采集与信息聚合,并集成常用互联网小工具功能,帮助您将普通网站升级为智能化的多功能平台。

第一部分:WordPress开发环境搭建与基础知识

1.1 开发环境配置

在开始WordPress二次开发之前,首先需要搭建合适的开发环境。推荐使用本地开发环境如XAMPP、MAMP或Local by Flywheel,这些工具提供了完整的PHP、MySQL和Web服务器环境。

对于代码编辑器,Visual Studio Code是目前最受欢迎的选择,配合以下扩展插件可极大提升开发效率:

  • PHP Intelephense(PHP代码智能提示)
  • WordPress Snippet(WordPress代码片段)
  • GitLens(Git版本控制集成)

此外,建议安装调试工具如Query Monitor和Debug Bar,这些插件能帮助您在开发过程中实时监控数据库查询、PHP错误和性能数据。

1.2 WordPress主题与插件架构理解

要有效进行WordPress二次开发,必须深入理解其核心架构:

主题系统:WordPress主题控制网站的外观和显示方式。子主题开发是自定义功能而不影响父主题更新的最佳实践。创建子主题只需在wp-content/themes目录下建立新文件夹,包含style.css和functions.php文件。

插件系统:插件用于扩展WordPress功能,独立于主题。良好的插件应遵循单一职责原则,专注于特定功能的实现。

钩子机制:动作钩子(Action Hooks)和过滤器钩子(Filter Hooks)是WordPress扩展性的核心。动作钩子允许在特定点执行自定义代码,而过滤器钩子允许修改数据。

// 动作钩子示例
add_action('wp_head', 'custom_head_code');
function custom_head_code() {
    echo '<meta name="custom-tag" content="value">';
}

// 过滤器钩子示例
add_filter('the_title', 'custom_title_format');
function custom_title_format($title) {
    return '📌 ' . $title;
}

1.3 自定义文章类型与字段

对于数据采集和聚合,自定义文章类型(CPT)和字段是基础。CPT允许您创建不同于标准文章和页面的内容类型,如“新闻”、“产品”或“数据条目”。

// 注册自定义文章类型
function register_data_collection_cpt() {
    $labels = array(
        'name' => '采集数据',
        'singular_name' => '数据条目'
    );
    
    $args = array(
        'labels' => $labels,
        'public' => true,
        'has_archive' => true,
        'supports' => array('title', 'editor', 'custom-fields'),
        'show_in_rest' => true, // 启用Gutenberg编辑器支持
    );
    
    register_post_type('collected_data', $args);
}
add_action('init', 'register_data_collection_cpt');

对于更复杂的字段需求,推荐使用Advanced Custom Fields(ACF)插件或Meta Box框架,它们提供了直观的字段管理界面。

第二部分:自动化数据采集系统开发

2.1 数据采集策略与规划

在开发数据采集功能前,需要明确采集目标、数据源和更新频率。常见的数据源包括:

  • RSS/Atom订阅源
  • 公开API接口
  • 网页抓取(需遵守robots.txt和法律法规)
  • 社交媒体平台
  • 公开数据库

设计数据采集系统时,应考虑以下因素:

  1. 数据源稳定性与可用性
  2. 采集频率与服务器负载平衡
  3. 数据去重与更新机制
  4. 错误处理与日志记录
  5. 版权与法律合规性

2.2 WordPress定时任务系统

WordPress提供了内置的定时任务系统WP-Cron,可用于定期执行数据采集任务。但需要注意的是,WP-Cron基于页面访问触发,对于精确的定时任务可能不够可靠。对于高要求的采集任务,建议使用系统级的Cron任务。

// 注册定时采集任务
function register_data_collection_cron() {
    // 确保事件未已安排
    if (!wp_next_scheduled('hourly_data_collection')) {
        // 安排每小时执行一次
        wp_schedule_event(time(), 'hourly', 'hourly_data_collection');
    }
}
add_action('wp', 'register_data_collection_cron');

// 定义采集函数
function perform_data_collection() {
    // 数据采集逻辑
    $data_sources = get_option('data_collection_sources', array());
    
    foreach ($data_sources as $source) {
        $collected_data = fetch_data_from_source($source);
        process_and_store_data($collected_data);
    }
    
    // 记录采集日志
    update_option('last_collection_time', current_time('mysql'));
}
add_action('hourly_data_collection', 'perform_data_collection');

// 添加自定义时间间隔
function add_custom_cron_intervals($schedules) {
    $schedules['every_10_minutes'] = array(
        'interval' => 600,
        'display' => __('每10分钟')
    );
    return $schedules;
}
add_filter('cron_schedules', 'add_custom_cron_intervals');

2.3 数据采集方法实现

RSS/Atom订阅采集

function fetch_rss_feed($feed_url) {
    include_once(ABSPATH . WPINC . '/feed.php');
    
    // 获取RSS订阅
    $rss = fetch_feed($feed_url);
    
    if (is_wp_error($rss)) {
        error_log('RSS采集错误: ' . $rss->get_error_message());
        return false;
    }
    
    $max_items = $rss->get_item_quantity(10); // 获取最新10条
    $rss_items = $rss->get_items(0, $max_items);
    
    $collected_data = array();
    
    foreach ($rss_items as $item) {
        $data_entry = array(
            'title' => $item->get_title(),
            'content' => $item->get_content(),
            'excerpt' => $item->get_description(),
            'source_url' => $item->get_permalink(),
            'publish_date' => $item->get_date('Y-m-d H:i:s'),
            'author' => $item->get_author() ? $item->get_author()->get_name() : '',
            'categories' => array()
        );
        
        // 获取分类
        $categories = $item->get_categories();
        if ($categories) {
            foreach ($categories as $category) {
                $data_entry['categories'][] = $category->get_label();
            }
        }
        
        $collected_data[] = $data_entry;
    }
    
    return $collected_data;
}

API数据采集

function fetch_api_data($api_url, $api_key = '') {
    $args = array(
        'timeout' => 30,
        'headers' => $api_key ? array('Authorization' => 'Bearer ' . $api_key) : array()
    );
    
    $response = wp_remote_get($api_url, $args);
    
    if (is_wp_error($response)) {
        error_log('API请求错误: ' . $response->get_error_message());
        return false;
    }
    
    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log('JSON解析错误: ' . json_last_error_msg());
        return false;
    }
    
    return $data;
}

网页内容抓取
对于网页抓取,建议使用WordPress内置的HTTP API配合DOM解析:

function scrape_website_content($url, $selector) {
    // 获取网页内容
    $response = wp_remote_get($url, array('timeout' => 30));
    
    if (is_wp_error($response)) {
        return false;
    }
    
    $html = wp_remote_retrieve_body($response);
    
    // 使用DOMDocument解析HTML
    $dom = new DOMDocument();
    @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
    
    $xpath = new DOMXPath($dom);
    $elements = $xpath->query($selector);
    
    $results = array();
    foreach ($elements as $element) {
        $results[] = $dom->saveHTML($element);
    }
    
    return $results;
}

注意:网页抓取应遵守robots.txt规则,尊重版权,并控制请求频率以避免对目标服务器造成负担。

2.4 数据存储与处理

采集到的数据需要有效存储和处理。WordPress提供了多种存储选项:

自定义数据库表
对于大量结构化数据,创建自定义数据库表可能更高效:

function create_data_collection_table() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'collected_data';
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        source_id varchar(100) NOT NULL,
        title text NOT NULL,
        content longtext,
        source_url varchar(500),
        collected_date datetime DEFAULT CURRENT_TIMESTAMP,
        processed tinyint(1) DEFAULT 0,
        PRIMARY KEY (id),
        KEY source_id (source_id),
        KEY processed (processed)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_data_collection_table');

使用自定义文章类型存储
对于大多数情况,使用自定义文章类型配合自定义字段是更简单的方法:

function store_collected_data_as_post($data) {
    // 检查是否已存在相同内容(避免重复)
    $existing_post = get_posts(array(
        'post_type' => 'collected_data',
        'meta_query' => array(
            array(
                'key' => 'source_url',
                'value' => $data['source_url']
            )
        ),
        'posts_per_page' => 1
    ));
    
    if (!empty($existing_post)) {
        // 更新现有文章
        $post_id = $existing_post[0]->ID;
        $post_data = array(
            'ID' => $post_id,
            'post_title' => $data['title'],
            'post_content' => $data['content'],
            'post_excerpt' => $data['excerpt'],
            'post_status' => 'publish'
        );
        
        wp_update_post($post_data);
    } else {
        // 创建新文章
        $post_data = array(
            'post_title' => $data['title'],
            'post_content' => $data['content'],
            'post_excerpt' => $data['excerpt'],
            'post_status' => 'publish',
            'post_type' => 'collected_data',
            'post_date' => $data['publish_date'] ?: current_time('mysql')
        );
        
        $post_id = wp_insert_post($post_data);
    }
    
    // 保存元数据
    if ($post_id && !is_wp_error($post_id)) {
        update_post_meta($post_id, 'source_url', $data['source_url']);
        update_post_meta($post_id, 'original_author', $data['author']);
        update_post_meta($post_id, 'collected_date', current_time('mysql'));
        
        // 保存分类
        if (!empty($data['categories'])) {
            $category_ids = array();
            foreach ($data['categories'] as $category_name) {
                $term = term_exists($category_name, 'category');
                if (!$term) {
                    $term = wp_insert_term($category_name, 'category');
                }
                if (!is_wp_error($term)) {
                    $category_ids[] = (int)$term['term_id'];
                }
            }
            wp_set_post_terms($post_id, $category_ids, 'category');
        }
    }
    
    return $post_id;
}

2.5 数据清洗与去重

采集的数据通常需要清洗和去重处理:

function clean_and_deduplicate_data($data_array) {
    $unique_data = array();
    $content_hashes = array();
    
    foreach ($data_array as $data) {
        // 内容清洗
        $data['title'] = sanitize_text_field($data['title']);
        $data['content'] = wp_kses_post($data['content']); // 过滤允许的HTML
        
        // 去除HTML标签获取纯文本用于去重
        $content_text = wp_strip_all_tags($data['content']);
        $content_hash = md5($content_text);
        
        // 检查是否重复
        if (!in_array($content_hash, $content_hashes)) {
            $content_hashes[] = $content_hash;
            $unique_data[] = $data;
        }
    }
    
    return $unique_data;
}

第三部分:信息聚合与展示系统

3.1 数据聚合策略

信息聚合不仅仅是收集数据,更是将多源数据整合为有价值的信息流。常见的聚合策略包括:

  1. 时间线聚合:按时间顺序展示多源数据
  2. 主题聚合:按主题或分类组织相关内容
  3. 来源聚合:按数据源分类展示
  4. 混合聚合:结合多种维度展示数据

3.2 创建聚合页面模板

在WordPress主题中创建专门的聚合页面模板:

<?php
/*
Template Name: 数据聚合页面
*/
get_header();

// 获取聚合配置
$sources = get_field('aggregation_sources'); // 假设使用ACF字段
$layout = get_field('aggregation_layout', 'grid'); // 网格或列表布局
$items_per_page = get_field('items_per_page', 20);
$current_page = max(1, get_query_var('paged'));
?>

<div class="aggregation-container">
    <header class="aggregation-header">
        <h1><?php the_title(); ?></h1>
        <div class="aggregation-filters">
            <select id="source-filter">
                <option value="all">所有来源</option>
                <?php foreach ($sources as $source): ?>
                <option value="<?php echo esc_attr($source['value']); ?>">
                    <?php echo esc_html($source['label']); ?>
                </option>
                <?php endforeach; ?>
            </select>
            
            <select id="date-filter">
                <option value="all">全部时间</option>
                <option value="today">今天</option>
                <option value="week">本周</option>
                <option value="month">本月</option>
            </select>
        </div>
    </header>
    
    <div class="aggregation-content" id="aggregation-results">
        <?php
        // 查询聚合数据
        $args = array(
            'post_type' => 'collected_data',
            'posts_per_page' => $items_per_page,
            'paged' => $current_page,
            'orderby' => 'date',
            'order' => 'DESC'
        );
        
        // 添加源过滤
        if (isset($_GET['source']) && $_GET['source'] !== 'all') {
            $args['meta_query'] = array(
                array(
                    'key' => 'data_source',
                    'value' => sanitize_text_field($_GET['source']),
                    'compare' => '='
                )
            );
        }
        
        // 添加日期过滤
        if (isset($_GET['date_filter'])) {
            $date_filter = sanitize_text_field($_GET['date_filter']);
            $date_query = array();
            
            switch ($date_filter) {
                case 'today':
                    $date_query = array(
                        'after' => 'today midnight',
                        'inclusive' => true
                    );
                    break;
                case 'week':
                    $date_query = array(
                        'after' => '1 week ago'
                    );
                    break;
                case 'month':
                    $date_query = array(
                        'after' => '1 month ago'
                    );
                    break;
            }
            
            if (!empty($date_query)) {
                $args['date_query'] = $date_query;
            }
        }
        
        $aggregation_query = new WP_Query($args);
        
        if ($aggregation_query->have_posts()):
            echo $layout === 'grid' ? '<div class="aggregation-grid">' : '<div class="aggregation-list">';
            
            while ($aggregation_query->have_posts()): $aggregation_query->the_post();
                include(locate_template('template-parts/aggregation-item.php'));
            endwhile;
            
            echo '</div>';
            
            // 分页
            echo '<div class="aggregation-pagination">';
            echo paginate_links(array(
                'total' => $aggregation_query->max_num_pages,
                'current' => $current_page,
                'prev_text' => '&laquo; 上一页',
                'next_text' => '下一页 &raquo;'
            ));
            echo '</div>';
            
            wp_reset_postdata();
        else:
            echo '<p class="no-results">暂无聚合数据</p>';
        endif;
        ?>
    </div>
</div>

<script>
// AJAX过滤功能
jQuery(document).ready(function($) {
    $('#source-filter, #date-filter').on('change', function() {
        var source = $('#source-filter').val();
        var dateFilter = $('#date-filter').val();
        
        $.ajax({
            url: '<?php echo admin_url("admin-ajax.php"); ?>',
            type: 'POST',
            data: {

data',

            source: source,
            date_filter: dateFilter,
            page: 1
        },
        beforeSend: function() {
            $('#aggregation-results').html('<div class="loading">加载中...</div>');
        },
        success: function(response) {
            $('#aggregation-results').html(response);
        }
    });
});

});
</script>

<?php
get_footer();


#### 3.3 实时数据聚合与更新

对于需要实时展示的数据,可以结合AJAX和WebSocket技术:

// 实时数据推送端点
function realtime_aggregation_endpoint() {

register_rest_route('aggregation/v1', '/realtime', array(
    'methods' => 'GET',
    'callback' => 'get_realtime_aggregation_data',
    'permission_callback' => '__return_true'
));

}
add_action('rest_api_init', 'realtime_aggregation_endpoint');

function get_realtime_aggregation_data($request) {

$last_id = $request->get_param('last_id');
$category = $request->get_param('category');

$args = array(
    'post_type' => 'collected_data',
    'posts_per_page' => 10,
    'orderby' => 'date',
    'order' => 'DESC'
);

if ($last_id) {
    $args['date_query'] = array(
        'after' => get_the_date('Y-m-d H:i:s', $last_id)
    );
}

if ($category && $category !== 'all') {
    $args['tax_query'] = array(
        array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $category
        )
    );
}

$query = new WP_Query($args);
$data = array();

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        $data[] = array(
            'id' => get_the_ID(),
            'title' => get_the_title(),
            'excerpt' => get_the_excerpt(),
            'date' => get_the_date('Y-m-d H:i:s'),
            'source' => get_post_meta(get_the_ID(), 'data_source', true),
            'url' => get_permalink()
        );
    }
    wp_reset_postdata();
}

return rest_ensure_response(array(
    'success' => true,
    'data' => $data,
    'timestamp' => current_time('timestamp')
));

}


前端实时更新实现:

// 前端实时数据监听
class RealtimeAggregation {

constructor(options) {
    this.options = Object.assign({
        endpoint: '/wp-json/aggregation/v1/realtime',
        interval: 30000, // 30秒
        container: '#realtime-feed',
        lastId: 0
    }, options);
    
    this.init();
}

init() {
    this.container = document.querySelector(this.options.container);
    if (!this.container) return;
    
    this.loadInitialData();
    this.startPolling();
}

async loadInitialData() {
    try {
        const response = await fetch(`${this.options.endpoint}?last_id=0`);
        const data = await response.json();
        
        if (data.success && data.data.length > 0) {
            this.renderData(data.data);
            this.options.lastId = data.data[0].id;
        }
    } catch (error) {
        console.error('加载数据失败:', error);
    }
}

startPolling() {
    setInterval(() => {
        this.checkForUpdates();
    }, this.options.interval);
}

async checkForUpdates() {
    try {
        const response = await fetch(
            `${this.options.endpoint}?last_id=${this.options.lastId}`
        );
        const data = await response.json();
        
        if (data.success && data.data.length > 0) {
            this.prependData(data.data);
            this.options.lastId = data.data[0].id;
            
            // 显示新数据通知
            this.showNewItemsNotification(data.data.length);
        }
    } catch (error) {
        console.error('检查更新失败:', error);
    }
}

renderData(items) {
    items.forEach(item => {
        const itemElement = this.createItemElement(item);
        this.container.appendChild(itemElement);
    });
}

prependData(items) {
    items.reverse().forEach(item => {
        const itemElement = this.createItemElement(item);
        this.container.insertBefore(itemElement, this.container.firstChild);
    });
}

createItemElement(item) {
    const div = document.createElement('div');
    div.className = 'realtime-item';
    div.innerHTML = `
        <div class="item-header">
            <span class="source-badge">${this.escapeHtml(item.source)}</span>
            <span class="item-time">${this.formatTime(item.date)}</span>
        </div>
        <h3 class="item-title">
            <a href="${this.escapeHtml(item.url)}">${this.escapeHtml(item.title)}</a>
        </h3>
        <p class="item-excerpt">${this.escapeHtml(item.excerpt)}</p>
    `;
    return div;
}

showNewItemsNotification(count) {
    // 实现新数据通知逻辑
    const notification = document.createElement('div');
    notification.className = 'new-items-notification';
    notification.innerHTML = `
        有${count}条新内容,<a href="#" class="show-new">点击查看</a>
    `;
    
    notification.querySelector('.show-new').addEventListener('click', (e) => {
        e.preventDefault();
        notification.remove();
    });
    
    document.body.appendChild(notification);
    
    setTimeout(() => {
        if (notification.parentNode) {
            notification.remove();
        }
    }, 5000);
}

escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

formatTime(dateString) {
    const date = new Date(dateString);
    const now = new Date();
    const diff = Math.floor((now - date) / 1000); // 秒
    
    if (diff < 60) return '刚刚';
    if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`;
    if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`;
    return date.toLocaleDateString();
}

}

// 初始化实时聚合
document.addEventListener('DOMContentLoaded', () => {

new RealtimeAggregation({
    container: '#realtime-feed',
    interval: 15000 // 15秒
});

});


#### 3.4 智能推荐与个性化聚合

基于用户行为实现个性化内容推荐:

class PersonalizedAggregation {

private $user_id;
private $preferences;

public function __construct($user_id = null) {
    $this->user_id = $user_id ?: get_current_user_id();
    $this->load_user_preferences();
}

private function load_user_preferences() {
    if ($this->user_id) {
        $this->preferences = get_user_meta($this->user_id, 'aggregation_preferences', true);
    }
    
    if (empty($this->preferences)) {
        $this->preferences = array(
            'preferred_categories' => array(),
            'preferred_sources' => array(),
            'reading_history' => array(),
            'click_pattern' => array()
        );
    }
}

public function track_user_interaction($post_id, $interaction_type = 'view') {
    if (!$this->user_id) return;
    
    $post_categories = wp_get_post_categories($post_id);
    $post_source = get_post_meta($post_id, 'data_source', true);
    
    // 更新阅读历史
    $history = $this->preferences['reading_history'];
    array_unshift($history, array(
        'post_id' => $post_id,
        'timestamp' => current_time('timestamp'),
        'type' => $interaction_type
    ));
    
    // 保持最近100条记录
    $this->preferences['reading_history'] = array_slice($history, 0, 100);
    
    // 更新分类偏好
    foreach ($post_categories as $cat_id) {
        if (!isset($this->preferences['preferred_categories'][$cat_id])) {
            $this->preferences['preferred_categories'][$cat_id] = 0;
        }
        $this->preferences['preferred_categories'][$cat_id] += 1;
    }
    
    // 更新来源偏好
    if ($post_source) {
        if (!isset($this->preferences['preferred_sources'][$post_source])) {
            $this->preferences['preferred_sources'][$post_source] = 0;
        }
        $this->preferences['preferred_sources'][$post_source] += 1;
    }
    
    $this->save_preferences();
}

public function get_personalized_feed($limit = 20) {
    $args = array(
        'post_type' => 'collected_data',
        'posts_per_page' => $limit,
        'orderby' => 'relevance',
        'meta_query' => array()
    );
    
    // 基于用户偏好调整查询
    if (!empty($this->preferences['preferred_categories'])) {
        arsort($this->preferences['preferred_categories']);
        $top_categories = array_slice(
            array_keys($this->preferences['preferred_categories']), 
            0, 
            3
        );
        
        $args['category__in'] = $top_categories;
    }
    
    if (!empty($this->preferences['preferred_sources'])) {
        arsort($this->preferences['preferred_sources']);
        $top_sources = array_slice(
            array_keys($this->preferences['preferred_sources']), 
            0, 
            2
        );
        
        $args['meta_query'][] = array(
            'key' => 'data_source',
            'value' => $top_sources,
            'compare' => 'IN'
        );
    }
    
    // 排除已读内容
    if (!empty($this->preferences['reading_history'])) {
        $read_posts = array_column($this->preferences['reading_history'], 'post_id');
        $args['post__not_in'] = array_unique($read_posts);
    }
    
    // 添加相关性评分
    add_filter('posts_where', array($this, 'add_relevance_scoring'));
    
    $query = new WP_Query($args);
    
    remove_filter('posts_where', array($this, 'add_relevance_scoring'));
    
    return $query;
}

public function add_relevance_scoring($where) {
    // 基于用户偏好计算相关性得分的复杂逻辑
    // 这里简化实现,实际应用中可能需要更复杂的算法
    global $wpdb;
    
    if (!empty($this->preferences['preferred_categories'])) {
        // 为偏好的分类添加权重
        $category_weights = array();
        foreach ($this->preferences['preferred_categories'] as $cat_id => $count) {
            $weight = min(10, $count / 10); // 计算权重
            $category_weights[$cat_id] = $weight;
        }
        
        // 这里可以添加更复杂的SQL逻辑来计算相关性
    }
    
    return $where;
}

private function save_preferences() {
    if ($this->user_id) {
        update_user_meta(
            $this->user_id, 
            'aggregation_preferences', 
            $this->preferences
        );
    }
}

public function get_recommendations_based_on_similarity($post_id, $limit = 5) {
    $post_categories = wp_get_post_categories($post_id);
    $post_tags = wp_get_post_tags($post_id, array('fields' => 'ids'));
    $post_source = get_post_meta($post_id, 'data_source', true);
    
    $args = array(
        'post_type' => 'collected_data',
        'posts_per_page' => $limit,
        'post__not_in' => array($post_id),
        'orderby' => 'relevance'
    );
    
    // 基于内容相似性查找相关文章
    $tax_query = array('relation' => 'OR');
    
    if (!empty($post_categories)) {
        $tax_query[] = array(
            'taxonomy' => 'category',
            'field' => 'term_id',
            'terms' => $post_categories
        );
    }
    
    if (!empty($post_tags)) {
        $tax_query[] = array(
            'taxonomy' => 'post_tag',
            'field' => 'term_id',
            'terms' => $post_tags
        );
    }
    
    if (!empty($tax_query)) {
        $args['tax_query'] = $tax_query;
    }
    
    if ($post_source) {
        $args['meta_query'] = array(
            array(
                'key' => 'data_source',
                'value' => $post_source,
                'compare' => '='
            )
        );
    }
    
    return new WP_Query($args);
}

}

// 使用示例
add_action('wp', function() {

if (is_singular('collected_data')) {
    $personalizer = new PersonalizedAggregation();
    $personalizer->track_user_interaction(get_the_ID());
}

});


### 第四部分:常用互联网小工具集成

#### 4.1 工具类插件架构设计

创建可扩展的小工具系统:

// 小工具管理器类
class ToolManager {

private static $instance = null;
private $tools = array();

private function __construct() {
    $this->load_tools();
    add_action('init', array($this, 'register_tools'));
}

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function load_tools() {
    // 加载内置工具
    $this->register_tool('unit_converter', array(
        'name' => '单位换算器',
        'description' => '常用单位换算工具',
        'callback' => array($this, 'render_unit_converter'),
        'icon' => 'dashicons-calculator',
        'category' => 'utility'
    ));
    
    $this->register_tool('color_picker', array(
        'name' => '颜色选择器',
        'description' => 'RGB/HEX颜色选择与转换',
        'callback' => array($this, 'render_color_picker'),
        'icon' => 'dashicons-art',
        'category' => 'design'
    ));
    
    $this->register_tool('qrcode_generator', array(
        'name' => '二维码生成器',
        'description' => '生成自定义二维码',
        'callback' => array($this, 'render_qrcode_generator'),
        'icon' => 'dashicons-format-image',
        'category' => 'generator'
    ));
    
    // 允许其他插件注册工具
    do_action('tool_manager_register_tools', $this);
}

public function register_tool($slug, $args) {
    $defaults = array(
        'name' => '',
        'description' => '',
        'callback' => null,
        'icon' => 'dashicons-admin-tools',
        'category' => 'general',
        'settings' => array()
    );
    
    $this->tools[$slug] = wp_parse_args($args, $defaults);
}

public function register_tools() {
    // 注册短代码
    foreach ($this->tools as $slug => $tool) {
        add_shortcode('tool_' . $slug, $tool['callback']);
    }
    
    // 注册Gutenberg块
    if (function_exists('register_block_type')) {
        $this->register_tool_blocks();
    }
}

private function register_tool_blocks() {
    wp_register_script(
        'tool-blocks',
        plugins_url('js/tool-blocks.js', __FILE__),
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components'),
        '1.0.0',
        true
    );
    
    register_block_type('tool-manager/tool', array(
        'editor_script' => 'tool-blocks',
        'render_callback' => array($this, 'render_tool_block')
    ));
}

public function render_tool_block($attributes) {
    $slug = $attributes['toolSlug'] ?? '';
    
    if (isset($this->tools[$slug]) && is_callable($this->tools[$slug]['callback'])) {
        ob_start();
        call_user_func($this->tools[$slug]['callback'], $attributes);
        return ob_get_clean();
    }
    
    return '<p>工具未找到</p>';
}

public function get_tools_by_category($category = '') {
    if (empty($category)) {
        return $this->tools;
    }
    
    return array_filter($this->tools, function($tool) use ($category) {
        return $tool['category'] === $category;
    });
}

public function render_tool_selector() {
    $categories = array();
    foreach ($this->tools as $tool) {
        if (!isset($categories[$tool['category']])) {
            $categories[$tool['category']] = array();
        }
        $categories[$tool['category']][] = $tool;
    }
    
    ob_start();
    ?>
    <div class="tool-selector">
        <?php foreach ($categories as $category_name => $category_tools): ?>
        <div class="tool-category">
            <h3><?php echo esc_html($this->get_category_label($category_name)); ?></h3>
            <div class="tool-grid">
                <?php foreach ($category_tools as $slug => $tool): ?>
                <div class="tool-item" data-tool="<?php echo esc_attr($slug); ?>">
                    <div class="tool-icon">
                        <span class="dashicons <?php echo esc_attr($tool['icon']); ?>
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5150.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部