热爱生活,重新开始

WordPress创建自定义读者墙功能

前言

在逛不亦乐乎博客时,我被其留言页面上读者墙的样式深深吸引。此外,在wys的友链页面,我也看到了独特的样式,这让我心痒难耐。于是,我开始在网上搜索相关的信息,偶然发现了张戈博客之前写过的一个插件。虽然这个插件由于年代久远已不再适用,但我决定根据其代码进行修改,并将其实现到自己的博客中。

步骤

1. 添加代码至 functions.php

首先,在你博客的主题目录下找到并打开 functions.php 文件。然后,将以下代码添加到文件末尾:

// 注册并加载读者墙的CSS样式
function enqueue_readers_wall_styles() {
    global $post;
    if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'readers_wall')) {
        wp_enqueue_style('readers-wall-style', get_template_directory_uri() . '/css/readers-wall.css', array(), '1.0.0');
    }
}
add_action('wp_enqueue_scripts', 'enqueue_readers_wall_styles');

// 辅助函数:生成排行列表
function generate_readers_list($title, $query, $limit) {
    global $wpdb;
    $output = '';

    // 使用 transient 缓存查询结果
    $transient_key = 'readers_wall_' . md5($query);
    $wall = get_transient($transient_key);

    if (false === $wall) {
        $wall = $wpdb->get_results($query);
        set_transient($transient_key, $wall, 3600);
    }

    $output .= '<div class="readers-section">';
    $output .= '<h2 class="entry-title">' . esc_html($title) . ' TOP' . esc_html($limit) . '</h2>';

    if ($wall) {
        $output .= "<ul class='readers-list'>";
        foreach ($wall as $comment) {
            $avatar = get_avatar($comment->comment_author_email, 64, '', '', array('loading' => 'lazy'));
            $url = esc_url($comment->comment_author_url ? $comment->comment_author_url : "#");
            $author = esc_html($comment->comment_author);
            $count = intval($comment->cnt);
            // 用作者名称替代邮箱作为 tooltip 的 ID
            $tooltip_id = sanitize_title($author);

            $tooltip = "{$author}<br>评论数: {$count}";

            $output .= "<li>
                            <a rel='friend' target='_blank' href='{$url}' aria-describedby='tooltip-{$tooltip_id}'>
                                {$avatar}
                                <div class='tooltip' id='tooltip-{$tooltip_id}' role='tooltip'>{$tooltip}</div>
                            </a>
                        </li>";
        }
        $output .= "</ul>";
    } else {
        $output .= "<p>没有找到" . esc_html($title) . "数据。</p>";
    }

    $output .= '</div>';

    return $output;
}

// 短代码函数:读者墙
function readers_wall_shortcode() {
    global $wpdb;
    $output = '';

    // 评论总排行榜
    $query2 = $wpdb->prepare(
        "SELECT COUNT(comment_ID) AS cnt, comment_author, comment_author_url, comment_author_email 
        FROM $wpdb->comments 
        LEFT JOIN $wpdb->posts ON ($wpdb->posts.ID = $wpdb->comments.comment_post_ID) 
        WHERE post_password = '' 
        AND comment_approved = '1' 
        AND comment_author != %s 
        GROUP BY comment_author_email 
        ORDER BY cnt DESC 
        LIMIT %d",
        '段先森',
        12
    );
    $output .= generate_readers_list('评论总排行榜', $query2, 12);

    // 年度评论排行
    $query1 = $wpdb->prepare(
        "SELECT COUNT(comment_ID) AS cnt, comment_author, comment_author_url, comment_author_email 
        FROM (
            SELECT * FROM $wpdb->comments 
            LEFT JOIN $wpdb->posts ON ($wpdb->posts.ID = $wpdb->comments.comment_post_ID) 
            WHERE comment_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 YEAR) AND NOW() 
            AND post_password = '' 
            AND comment_approved = '1'
            AND comment_author != %s
        ) AS tempcmt 
        GROUP BY comment_author_email 
        ORDER BY cnt DESC 
        LIMIT %d",
        '段先森',
        365
    );
    $output .= generate_readers_list('年度评论排行', $query1, 365);

    // 本月评论排行
    $query2 = $wpdb->prepare(
        "SELECT COUNT(comment_ID) AS cnt, comment_author, comment_author_url, comment_author_email 
        FROM (
            SELECT * FROM $wpdb->comments 
            LEFT JOIN $wpdb->posts ON ($wpdb->posts.ID = $wpdb->comments.comment_post_ID) 
            WHERE DATE_FORMAT(comment_date, '%%Y-%%m') = DATE_FORMAT(NOW(), '%%Y-%%m') 
            AND post_password = '' 
            AND comment_approved = '1'
            AND comment_author != %s
        ) AS tempcmt 
        GROUP BY comment_author_email 
        ORDER BY cnt DESC 
        LIMIT %d",
        '段先森',
        31
    );
    $output .= generate_readers_list('本月评论排行', $query2, 31);

    // 本周评论排行
    $query3 = $wpdb->prepare(
        "SELECT COUNT(comment_ID) AS cnt, comment_author, comment_author_url, comment_author_email 
        FROM (
            SELECT * FROM $wpdb->comments 
            LEFT JOIN $wpdb->posts ON ($wpdb->posts.ID = $wpdb->comments.comment_post_ID) 
            WHERE YEARWEEK(DATE_FORMAT(comment_date, '%%Y-%%m-%%d')) = YEARWEEK(NOW()) 
            AND post_password = '' 
            AND comment_approved = '1'
            AND comment_author != %s
        ) AS tempcmt 
        GROUP BY comment_author_email 
        ORDER BY cnt DESC 
        LIMIT %d",
        '段先森',
        7
    );
    $output .= generate_readers_list('本周评论排行', $query3, 7);

    return $output;
}
add_shortcode('readers_wall', 'readers_wall_shortcode');

2. 创建 CSS 文件

在你主题的目录下,找到 css 文件夹,并新建一个名为 readers-wall.css 的文件。将以下样式代码粘贴到该文件中:
/* readers-wall.css */

/* 容器样式 */
.readers-section {
    margin-bottom: 30px;
}
.readers-section h2.entry-title {
    font-size: 24px;
    margin-bottom: 15px;
    color: #333;
}

/* 头像列表样式 */
.readers-list { 
    display: flex; 
    flex-wrap: wrap; 
    list-style: none; 
    padding: 0;
    margin: 0;
}
.readers-list li {
    position: relative;
    margin: 10px;
    width: 50px; /* 调整头像大小 */
    height: 50px;
}
.readers-list li a {
    display: block;
    width: 100%;
    height: 100%;
    text-align: center;
    text-decoration: none;
    position: relative;
}
.readers-list li img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    transition: transform 0.3s ease;
}
.readers-list li a:hover img,
.readers-list li a:focus img {
    transform: scale(1.1);
}

/* 悬停信息框样式 */
.readers-list li .tooltip {
    visibility: hidden;
    opacity: 0;
    width: 160px;
    background-color: rgba(0, 0, 0, 0.75);
    color: #fff;
    text-align: center;
    border-radius: 6px;
    padding: 8px;
    position: absolute;
    bottom: 60px; /* 头像上方 */
    left: 50%;
    transform: translateX(-50%);
    transition: opacity 0.3s ease;
    z-index: 10;
    font-size: 14px;
}
.readers-list li .tooltip::after {
    content: "";
    position: absolute;
    top: 100%; /* 箭头指向头像 */
    left: 50%;
    margin-left: -5px;
    border-width: 5px;
    border-style: solid;
    border-color: rgba(0, 0, 0, 0.75) transparent transparent transparent;
}
.readers-list li:hover .tooltip,
.readers-list li a:focus .tooltip {
    visibility: visible;
    opacity: 1;
}

/* 响应式设计 */
@media (max-width: 600px) {
    .readers-list li {
        width: 40px;
        height: 40px;
    }
    .readers-section h2.entry-title {
        font-size: 20px;
    }
    .readers-list li .tooltip {
        width: 140px;
        font-size: 12px;
    }
}

3. 新建页面并插入简码

在你的 WordPress 后台,创建一个新页面或编辑现有页面,并插入以下简码:
readers_wall

结尾

以上就是我在个人博客上实现自定义读者墙功能的步骤。如果你希望根据自己的需求进行样式调整,可以随意修改 readers-wall.css 中的 CSS 代码,

[tip type="info" ]感谢 maie 的提醒,已修改funtions.php相关代码,隐藏邮箱地址。新增评论排行总榜[/tip]

评论

《 “WordPress创建自定义读者墙功能” 》 有 74 条评论

    1. 段先森 的头像
    1. 段先森 的头像

      哈哈,多来必站榜首

  1. wys 的头像
    wys📘 童生
    等级:童生
    首次评论:2024-01-01 16:45:26
    最后评论:2024-11-27 17:37:37
    总评论:5 次

    🙄 哈哈,被点名了。。
    //近两天还在啃初试笔记(/114.html),以至于今儿再次看到“三无青年”站名时,不自觉地就把“三无”与刚看过笔记里的“三无”进行匹配了:
    三无:⑴无法定扶养人,或者虽有法定扶养人,但是扶养义务人无扶养能力的;⑵无劳动能力的;⑶无生活来源的。(《2021 社会工作实务(中级)》-p169) :mrgreen:

    1. 段先森 的头像

      啊哈,哈哈哈,我的三无是网络定义 😀

    1. 段先森 的头像

      赶紧换,然后写教程咯

  2. 老麦 的头像

    怎么每次进来的主题都不一样的呢,哈哈哈。
    这样的功能能有效的提升博友间的互动,赞一个。

    1. 段先森 的头像

      嘿嘿,换主题第一人非我莫属

    1. 段先森 的头像

      兴趣使然,准备弄成插件形式,修改张戈博客的插件

        1. 段先森 的头像

          好的吧,我去看真是如此

    1. 段先森 的头像

      ai是非常强大的,哈哈

    1. 段先森 的头像

      还可以,各有各的好处,哈哈

  3. Jeffer.Z 的头像

    如果是wordpress可以给没有头像的人,设置一个默认头像,不然一堆无头像的堆里面不好看,我首页就是一个读者墙,特意加了个超链接,方便博友互相串门。😁

    1. 段先森 的头像

      可以调用本地静态,我没弄,我这是显示的太多了,哈哈

    1. 段先森 的头像
    1. 段先森 的头像

      就是根据那个改的,哈哈

    1. 段先森 的头像
    1. 段先森 的头像

      嘿嘿,榜一大哥来咯,handsome主题确实自带,所以说他优秀嘛,哈哈 😀

    1. 段先森 的头像

      加入白名单了嘛,我去看看

    1. 段先森 的头像

      嘿嘿,想一出是一出,瞎折腾

        1. 段先森 的头像

          咦,感谢提醒,已优化 :qiang:

    1. 段先森 的头像

      感谢夸奖,哈哈哈哈

  4. zwwooooo 的头像

    现在还在坚持博客的人很少,能评个论的更少,像我偶尔还会回访的甚少 :xiaoku:

    1. 段先森 的头像

      哈哈,确实呢,都是熟悉的才会呢 😀

  5. 皇家元林 的头像

    你这个文章里显示代码这段用的什么插件?很好看啊!
    你是用经典编辑器还是区块编辑器?

    1. 段先森 的头像

      用的经典,不过代码高亮是主题自带的呢

    1. 段先森 的头像

      可以的呀,可以尝试头像圆角化

        1. 段先森 的头像

          是的呢,我的代码里有,应该跟你的主题没有适配,你可以调整一下css代码

          1. Evan 的头像

            是的,我看了设置里面,你这个代码确实已经是圆形了,但是在这个主题里面是不起作用的。我暂时不知道改pix主题的什么位置。抽时间再找找

          2. Evan 的头像

            现在的效果跟你的一样了。哈哈。我用了!important 保证了优先级,然后就解决了。哈哈哈哈

    1. 段先森 的头像

      嘿嘿,自己弄起来确实挺有意思的呢

  6. Evan 的头像

    [img]https://www.evan.xin/wp-content/uploads/2024/10/20241008182831.png[/img]

    这下可以看到了吧。。晕倒。

    1. 段先森 的头像

      你第一条评论的就可以看到图片啊。横线是在一个容器里。还有你说的小圈圈都可以用css代码解决

  7. Evan 的头像

    [img]https://s21.ax1x.com/2024/10/08/pAG6RT1.png[/img]
    这个下面的横线,如何去掉???

    1. 段先森 的头像

      嘿嘿,对于你来说易如反掌

    2. 耳朵的主人 的头像

      我晚上就开抄,哈哈,好久没有折腾拓展功能了。
      这有完整教学,拿来主义。哈哈

    1. 段先森 的头像

      一动起念头就想立刻实现它,嘿嘿

回复 Kevin's✍️ 举人
等级:举人
首次评论:2021-10-18 12:02:39
最后评论:2025-06-22 18:13:03
总评论:12 次
取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注