子比文章归档页面模板【二次开发版】-好运哒哒指标源码网

子比文章归档页面模板【二次开发版】

7b2那边有大佬开发了一个带图表的文章归档页面,那别人有的我们也必须要有,该页面仅子比主题可用,文章卡片使用的是子比主题自带的卡片函数生成

子比文章归档页面模板【二次开发版】-好运哒哒指标源码网

 

该页面所使用的技术栈如下:

  • Apache ECharts(精美的图表组件)
  • WordPress自带的Transient瞬态API缓存
  • 子比主题内置函数

该页面使用Transient瞬态API缓存一天

在子比主题目录下的pages文件夹创建一个PHP文件,名字随便起,由于我是子主题所以我直接命名为了archives.php

<?php

/**
 * Template name: Grace-文章归档
 * Description:   A archives page for displaying article statistics and monthly updates.
 */

// 获取分类统计信息并缓存
function get_category_statistics() {
    return get_cached_data('category_stats', function() {
        $categories = get_categories(['hide_empty' => false]);
        $data = [];
        foreach ($categories as $category) {
            $data[] = ['value' => $category->count, 'name' => $category->name];
        }
        return json_encode($data);
    });
}

// 获取文章热力图数据并缓存
function get_heatmap_data() {
    return get_cached_data('heatmap_data', function() {
        global $wpdb;
        // 使用SQL查询一次性获取所有必要的数据,以减少循环中的函数调用
        $query = "
            SELECT DATE(post_date) AS date, COUNT(*) AS count
            FROM {$wpdb->posts}
            WHERE post_type = 'post' AND post_status = 'publish'
            GROUP BY DATE(post_date)
            ORDER BY date ASC
        ";
        $results = $wpdb->get_results($query, ARRAY_A);

        // 填充缺失的日期
        if (!empty($results)) {
            $start_date = $results[0]['date'];
            $end_date = end($results)['date'];
            $current_date = strtotime($start_date);
            $heatmap_data = [];

            while (date('Y-m-d', $current_date) <= $end_date) {
                $formatted_date = date('Y-m-d', $current_date);
                $count = 0;

                foreach ($results as $result) {
                    if ($result['date'] === $formatted_date) {
                        $count = $result['count'];
                        break;
                    }
                }

                $heatmap_data[] = [$formatted_date, $count];
                $current_date = strtotime('+1 day', $current_date);
            }

            return json_encode($heatmap_data);
        } else {
            return json_encode([]);
        }
    });
}

// 获取用户统计数据并缓存
function get_user_vip_statistics() {
    return get_cached_data('user_vip_stats', function() {
        // 如果有更高效的获取会员级别的方式,请替换zib_get_user_vip_level()
        $users = get_users(['fields' => ['ID']]);
        $user_counts = [
            'normal' => 0,
            'vip_1' => 0,
            'vip_2' => 0
        ];

        foreach ($users as $user) {
            $vip_level = zib_get_user_vip_level($user->ID);

            switch ($vip_level) {
                case 1:
                    $user_counts['vip_1']++;
                    break;
                case 2:
                    $user_counts['vip_2']++;
                    break;
                default:
                    $user_counts['normal']++;
                    break;
            }
        }

        $chart_data = [
            ['value' => $user_counts['normal'], 'name' => '普通用户'],
            ['value' => $user_counts['vip_1'], 'name' => _pz('pay_user_vip_1_name')],
            ['value' => $user_counts['vip_2'], 'name' => _pz('pay_user_vip_2_name')]
        ];

        return json_encode($chart_data);
    });
}

// 使用瞬态API缓存数据以减少数据库查询次数
function get_cached_data($transient_key, $fetch_callback) {
    if (false === ($data = get_transient($transient_key))) {
        $data = call_user_func($fetch_callback);
        set_transient($transient_key, $data, DAY_IN_SECONDS); // 缓存一天
    }
    return $data;
}

// 渲染小部件
function render_archives_widgets($type = 'day') {
    // 初始化变量
    $icons = [
        'day' => ['icon' => 'fa fa-birthday-cake', 'color' => 'c-blue-2', 'title' => '运营时间'],
        'post' => ['icon' => '#icon-post', 'color' => 'c-green', 'title' => '文章总量'],
        'comment' => ['icon' => '#icon-comment-color', 'color' => 'c-yellow', 'title' => '评论总量'],
        'user' => ['icon' => '#icon-user-color-2', 'color' => 'c-blue', 'title' => '注册用户']
    ];

    // 根据传入的参数类型获取统计数据并构建HTML
    switch ($type) {
        case 'day':
            // 尝试获取ID为1的用户注册时间作为运营时间起点
            $first_user = get_userdata(1);
            if ($first_user && !empty($first_user->user_registered)) {
                $start_time = strtotime($first_user->user_registered);
            } else {
                // 如果获取不到用户1的数据,则回退到站点设置时间或者当前时间
                $start_time = strtotime(get_option('siteorigin_setting_time')) ?: time();
            }
            $statistic = esc_html(floor((time() - $start_time) / (60 * 60 * 24))) . ' 天';
            break;
        case 'post':
            $statistic = esc_html(wp_count_posts()->publish);
            break;
        case 'comment':
            $approved_comments = get_comment_count()['approved'];
            $pending_comments = get_comment_count()['moderated'];
            $spam_comments = get_comment_count()['spam'];
            $trash_comments = get_comment_count()['trash'];
            $statistic = esc_html($approved_comments + $pending_comments + $spam_comments + $trash_comments);
            break;
        case 'user':
            $statistic = esc_html(count_users()['total_users']);
            break;
        default:
            return; // 如果类型不匹配,则不输出任何内容
    }

    // 输出HTML结构
    echo '<div style="flex: 1;" class="zib-widget flex1">';
    echo '<div class="muted-color em09 mb6">' . $icons[$type]['title'] . '统计</div>';
    echo '<div class="flex jsb">';
    echo '<span class="font-bold ' . $icons[$type]['color'] . ' em12">' . $statistic . '</span>';
    
    if (strpos($icons[$type]['icon'], '#') === 0) {
        // 使用SVG图标
        echo '<svg class="em14 ' . $icons[$type]['color'] . '" aria-hidden="true"><use xlink:href="' . $icons[$type]['icon'] . '"></use></svg>';
    } else {
        // 使用Font Awesome图标
        echo '<i class="' . $icons[$type]['icon'] . ' ' . $icons[$type]['color'] . ' em14"></i>';
    }
    
    echo '</div></div>';
}

// 在适当的地方调用这些函数以获取所需的数据
$json_data = get_category_statistics();
$json_heatmap_data = get_heatmap_data();
$json_chart_data = get_user_vip_statistics();

function Grace_archives_scripts() {
    // 注册并加载ECharts库
    wp_enqueue_script('echarts', 'https://jsd.admincdn.com/npm/echarts/dist/echarts.min.js', array(), null, true);

    // 注册自定义JS文件
    wp_enqueue_script('archives-script', 'https://www.vxras.com/wp-content/themes/grace/assets/js/archives.js', array('echarts'), null, true);

    // 使用wp_localize_script将PHP变量传递给JavaScript
    $data_to_js = array(
        'vipChartData' => json_decode(get_user_vip_statistics(), true),
        'postChartData' => json_decode(get_category_statistics(), true),
        'heatmapData' => json_decode(get_heatmap_data(), true)
    );
    wp_localize_script('archives-script', 'chartData', $data_to_js);
}
add_action('wp_enqueue_scripts', 'Grace_archives_scripts');

// 获取头部样式
get_header();
$post_id = get_queried_object_id();
$header_style = zib_get_page_header_style($post_id);
?>

<!-- 页面主体 -->
<main class="container">
    <div class="content-wrap">
        <div class="content-layout">
            <?php if ($header_style != 1) { echo zib_get_page_header($post_id);} ?>
            <div class="theme-box radius8">
                <?php if ($header_style == 1) { echo zib_get_page_header($post_id);} ?>
                <article>
                        <div id="post" class="zib-widget" style="height:450px;"></div>
                        <div id="time" class="zib-widget" style="height:300px;"></div>
                        <div class="zib-widget">
                            <div class="title-theme mb20">文章归档<div class="pull-right em09 mt3"><a class="but c-blue radius" href="javascript:;" id="toggleAll">展开全部</a></div></div>
                            <div data-nav="posts" class="theme-box wp-posts-content">
                                <?php
                                    $previous_year = 0;
                                    $previous_month = 0;
                                    $collapse_id = 0;

                                    // 获取所有文章
                                    $myposts = get_posts('numberposts=-1&orderby=post_date&order=DESC');

                                    foreach ($myposts as $post) :
                                        setup_postdata($post);

                                        $year = mysql2date('Y', $post->post_date);
                                        $month = mysql2date('n', $post->post_date);

                                        if ($year != $previous_year || $month != $previous_month) :
                                            // 如果不是第一个月,则关闭上一个折叠面板
                                            if ($collapse_id > 0) {
                                                echo '</div></div></div>';
                                            }

                                            // 开始新的月份折叠面板
                                            $collapse_id++;
                                            echo '<div class="wp-block-zibllblock-collapse">';
                                            echo '<div class="panel" data-theme="panel" data-isshow="false">';
                                            echo '<div class="panel-heading collapsed" href="#collapse_' . esc_attr($collapse_id) . '" data-toggle="collapse" aria-controls="collapseExample" aria-expanded="false">';
                                            echo '<i class="fa fa-plus"></i><strong class="biaoti">' . get_the_time('Y年n月') . '</strong>';
                                            echo '</div>';
                                            echo '<div class="collapse" id="collapse_' . esc_attr($collapse_id) . '" aria-expanded="false" style="height: 0px;">';
                                            echo '<div class="panel-body">';
                                        endif;

                                        // 使用 add_shortcode_postsbox 函数输出单篇文章内容
                                        echo do_shortcode('');

                                        $previous_year = $year;
                                        $previous_month = $month;
                                    endforeach;

                                    // 关闭最后一个折叠面板(如果有)
                                    if ($collapse_id > 0) {
                                        echo '</div></div></div>';
                                    }

                                    wp_reset_query();
                                    wp_reset_postdata();
                                    ?>
                            </div>
                        </div>
                </article>

            </div>
            <?php comments_template('/template/comments.php', true); ?>
        </div>
    </div>
    
    <div class="sidebar">
        <div class="zib-widget" id="vip-user" style="height: 400px;"></div>
        <div class="flex ab jsb col-ml6 pointer">
            <?php render_archives_widgets('day'); ?>
            <?php render_archives_widgets('post'); ?>
        </div>

        <div class="flex ab jsb col-ml6 pointer">
            <?php render_archives_widgets('comment'); ?>
            <?php render_archives_widgets('user'); ?>
        </div>
    </div>
</main>

<script type="text/javascript">

</script>

<?php
// 加载页脚
get_footer();
请登录后发表评论

    没有回复内容