普通视图

Received before yesterday

分享一下本站的博主个人状态功能

作者陶其
2025年7月30日 17:36

感谢订阅陶其的个人博客!

我想在网站上显示自己当前的心情状态,就像微信的状态一样。

但是WordPress是不自带这个功能的,我就自己搞了一个。

效果:

一、配置清单

下面是我的配置清单,我只能保证最终效果在本配置下生效。

  • 博客平台: WordPress 6.8.0
  • 主题模板: Argon 1.3.5

以下是配置步骤:

二、编辑functions.php文件

打开博客后台 > 外观 > 主题文件编辑器 > functions.php,拉到最后,新增如下配置,并更新文件:

// ------------------------------------------------ 状态start ------------------------------------------------

// 添加状态设置菜单
function custom_status_menu() {
    add_menu_page(
        '状态设置',
        '状态',
        'edit_posts',
        'custom-status-settings',
        'custom_status_settings_page',
        'dashicons-smiley',
        6
    );
}
add_action('admin_menu', 'custom_status_menu');

// 注册设置(添加输入框验证逻辑)
function custom_status_register_settings() {
    register_setting(
        'custom-status-group', 
        'current_status',
        array(
            'sanitize_callback' => 'sanitize_custom_status' // 新增:处理状态值逻辑
        )
    );
    register_setting('custom-status-group', 'status_text_color');
    register_setting('custom-status-group', 'status_bg_color');
}
add_action('admin_init', 'custom_status_register_settings');

// 新增:处理状态值(优先使用输入框内容)
function sanitize_custom_status($input) {
    // 获取输入框的值
    $custom_input = isset($_POST['custom_status_input']) ? sanitize_text_field($_POST['custom_status_input']) : '';
    // 如果输入框有内容,返回输入框值;否则返回下拉框值
    return !empty($custom_input) ? $custom_input : $input;
}

// 设置页面内容(新增输入框)
function custom_status_settings_page() {
        $statuses = array(
            '<i class="fa fa-meh-o"></i> emo',                  // 情绪低落:中性表情(存在)
            '<i class="fa fa-bed"></i> 疲惫',                   // 疲惫:床(关联休息,存在)
            '<i class="fa fa-cloud"></i> 等天晴',               // 等天晴:云朵(存在)
            '<i class="fa fa-snapchat-ghost"></i> 活人微死',    // 消极状态:幽灵(存在)
            '<i class="fa fa-smile-o"></i> 美滋滋',             // 开心:微笑(存在)
            '<i class="fa fa-bolt"></i> 裂开',                  // 崩溃:闪电(存在)
            '<i class="fa fa-meh-o"></i> 发呆',                 // 茫然:中性表情(存在)
            '<i class="fa fa-lightbulb-o"></i> 胡思乱想',       // 思考:灯泡(存在)
            '<i class="fa fa-hand-peace-o"></i> 元气满满',      // 活力:比耶(存在)
            '<i class="fa fa-android"></i> bot',               // 机器人:安卓图标(存在)
            '<i class="fa fa-briefcase"></i> 搬砖ing',          // 工作:公文包(存在)
            '<i class="fa fa-book"></i> 沉迷学习',              // 学习:书本(存在)
            '<i class="fa fa-spinner"></i> 忙',                 // 忙碌:旋转加载(存在)
            '<i class="fa fa-coffee"></i> 摸鱼ing',             // 摸鱼:咖啡(存在)
            '<i class="fa fa-child"></i> 带娃',                 // 带娃:小孩图标(存在)
            '<i class="fa fa-shield"></i> 拯救世界',            // 守护:盾牌(存在)
            '<i class="fa fa-home"></i> 宅',                    // 宅家:家(存在)
            '<i class="fa fa-bed"></i> 想睡觉',                 // 困倦:床(存在)
            '<i class="fa fa-moon-o"></i> 困死',                // 极度困倦:月亮(存在)
            '<i class="fa fa-music"></i> 听歌ing',              // 听歌:音乐符号(存在)
            '<i class="fa fa-rocket"></i> 逃离地球'             // 逃离:火箭(存在)
        );

    $color_presets = array(
        'text' => array(
            '#FFFFFF' => '白色',
            '#D1D5DB' => '浅灰',
            '#9CA3AF' => '中灰',
            '#4B5563' => '深灰',
            '#000000' => '黑色',
        ),
        'bg' => array(
            '#FFF9C4' => '浅柠黄', '#E8F5E9' => '嫩芽绿',
            '#FFD6BA' => '暖橙', '#C8E6C9' => '浅草绿', '#B3E5FC' => '天青蓝', '#E1BEE7' => '淡罗兰', '#FFCDD2' => '浅绯红',
            '#FFE0B2' => '蜜橙', '#F5F5F5' => '米白灰', '#BBDEFB' => '雾蓝', '#D7CCC8' => '浅棕灰', '#F8BBD0' => '柔粉', '#C5CAE9' => '淡靛蓝',
            '#9FA8DA' => '灰蓝', '#CE93D8' => '灰紫', '#A1887F' => '深棕灰', '#EF9A9A' => '绯红', '#7986CB' => '靛蓝', '#5C6BC0' => '暗靛蓝', '#616161' => '深炭灰',
        )
    );
    ?>
    <div class="wrap">
        <h1>个人状态设置</h1>
        <form method="post" action="options.php">
            <?php settings_fields('custom-status-group'); ?>
            <?php do_settings_sections('custom-status-group'); ?>
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">当前状态</th>
                    <td style="display: flex; gap: 10px; align-items: center;">
                        <!-- 原有下拉框 -->
                        <select name="current_status" id="current_status" style="padding:5px;min-width:200px;">
                            <option value="">-- 选择状态 --</option>
                            <?php 
                            $current = get_option('current_status');
                            foreach($statuses as $status) {
                                // 下拉框默认选中状态(排除手动输入的情况)
                                $is_custom = !in_array($current, $statuses);
                                $selected = (!$is_custom && $current == $status) ? 'selected' : '';
                                echo "<option value='$status' $selected>$status</option>";
                            }
                            ?>
                        </select>

                        <!-- 新增手动输入框 -->
                        <input 
                            type="text" 
                            name="custom_status_input" 
                            id="custom_status_input" 
                            placeholder="或手动输入状态" 
                            style="padding:5px;min-width:100px;"
                            value="<?php 
                                // 回显手动输入的值(如果是自定义状态)
                                $current = get_option('current_status');
                                echo !in_array($current, $statuses) ? esc_attr($current) : '';
                            ?>"
                        >
                    </td>
                </tr>
                <tr valign="top">
                    <th scope="row">文字颜色</th>
                    <td>
                        <select name="status_text_color" id="status_text_color" style="padding:5px;min-width:200px;">
                            <?php 
                            $current_text_color = get_option('status_text_color', '#ffffff');
                            foreach($color_presets['text'] as $value => $label) {
                                $selected = ($current_text_color == $value) ? 'selected' : '';
                                echo "<option value='$value' $selected style='color: $value;'>$label</option>";
                            }
                            ?>
                        </select>
                    </td>
                </tr>
                <tr valign="top">
                    <th scope="row">背景颜色</th>
                    <td>
                        <select name="status_bg_color" id="status_bg_color" style="padding:5px;min-width:200px;">
                            <?php 
                            $current_bg_color = get_option('status_bg_color', '#8d9deb');
                            foreach($color_presets['bg'] as $value => $label) {
                                $selected = ($current_bg_color == $value) ? 'selected' : '';
                                echo "<option value='$value' $selected style='background-color: $value; color: white;'>$label</option>";
                            }
                            ?>
                        </select>
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

// 为后台状态配置页面添加自定义CSS
function custom_status_admin_css() {
    // 只在状态配置页面加载该CSS
    global $pagenow;
    if ($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page'] == 'custom-status-settings') {
        ?>
        <style type="text/tailwindcss">
            @layer utilities {
                .status-color-option {
                    @apply relative pl-8 text-black;
                }
                .status-color-option::before {
                    @apply absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 rounded border border-gray-200;
                }
            }
        </style>
        <style type="text/css">
            /* 颜色选项显示优化 */
            #status_text_color option,
            #status_bg_color option {
                @apply status-color-option;
            }

            /* 文本颜色选项的文字和背景 */
            #status_text_color option[value="#FFFFFF"] { background-color: #6B7280 !important; color: #FFFFFF !important; }
            #status_text_color option[value="#D1D5DB"] { color: #D1D5DB !important; }
            #status_text_color option[value="#9CA3AF"] { color: #9CA3AF !important; }
            #status_text_color option[value="#4B5563"] { color: #4B5563 !important; }
            #status_text_color option[value="#000000"] { color: #000000 !important; }

            /* 文本颜色选项的颜色块 */
            #status_text_color option[value="#FFFFFF"]::before { background-color: #FFFFFF; }
            #status_text_color option[value="#D1D5DB"]::before { background-color: #D1D5DB; }
            #status_text_color option[value="#9CA3AF"]::before { background-color: #9CA3AF; }
            #status_text_color option[value="#4B5563"]::before { background-color: #4B5563; }
            #status_text_color option[value="#000000"]::before { background-color: #000000; }

            /* 背景颜色选项的颜色块 */
            #status_bg_color option[value="#FFF9C4"]::before { background-color: #FFF9C4; }
            #status_bg_color option[value="#E8F5E9"]::before { background-color: #E8F5E9; }
            #status_bg_color option[value="#FFD6BA"]::before { background-color: #FFD6BA; }
            #status_bg_color option[value="#C8E6C9"]::before { background-color: #C8E6C9; }
            #status_bg_color option[value="#B3E5FC"]::before { background-color: #B3E5FC; }
            #status_bg_color option[value="#E1BEE7"]::before { background-color: #E1BEE7; }
            #status_bg_color option[value="#FFCDD2"]::before { background-color: #FFCDD2; }
            #status_bg_color option[value="#FFE0B2"]::before { background-color: #FFE0B2; }
            #status_bg_color option[value="#F5F5F5"]::before { background-color: #F5F5F5; }
            #status_bg_color option[value="#BBDEFB"]::before { background-color: #BBDEFB; }
            #status_bg_color option[value="#D7CCC8"]::before { background-color: #D7CCC8; }
            #status_bg_color option[value="#F8BBD0"]::before { background-color: #F8BBD0; }
            #status_bg_color option[value="#C5CAE9"]::before { background-color: #C5CAE9; }
            #status_bg_color option[value="#9FA8DA"]::before { background-color: #9FA8DA; }
            #status_bg_color option[value="#CE93D8"]::before { background-color: #CE93D8; }
            #status_bg_color option[value="#A1887F"]::before { background-color: #A1887F; }
            #status_bg_color option[value="#EF9A9A"]::before { background-color: #EF9A9A; }
            #status_bg_color option[value="#7986CB"]::before { background-color: #7986CB; }
            #status_bg_color option[value="#5C6BC0"]::before { background-color: #5C6BC0; }
            #status_bg_color option[value="#616161"]::before { background-color: #616161; }
        </style>
        <?php
    }
}
add_action('admin_head', 'custom_status_admin_css');

// ------------------------------------------------ 状态end ------------------------------------------------

三、编辑sidebar.php文件

打开博客后台 > 外观 > 主题文件编辑器 > 编辑sidebar.php,找到你头像的位置,新增如下配置,并更新文件:

位置确定技巧:如果点击你的头像能跳转你的“关于我”的页面,那么你复制“关于我”的网址,搜索这个文件,就能确定:

<!-- 状态代码start -->
                                <?php $status = get_option('current_status'); ?>
                                <?php $text_color = get_option('status_text_color', '#ffffff'); ?>
                                <?php $bg_color = get_option('status_bg_color', '#8d9deb'); ?>
                                <?php if (!empty($status)): ?>
                                    <!-- 关键修改:用 wp_kses_post() 替换 esc_html(),允许<i>标签解析 -->
                                    <span class="status-badge" style="color: <?php echo esc_attr($text_color); ?>; background-color: <?php echo esc_attr($bg_color); ?>;">
                                        <?php echo wp_kses_post($status); // 保留HTML标签,正常渲染图标 ?>
                                    </span>
                                <?php endif; ?>
                                <!-- 状态代码end -->

四、新增自定义CSS样式

打开博客后台 > 外观 > 自定义 > 额外CSS > 拉到最后新增如下内容并发布:

/* 状态代码start */
.profile-avatar {
    position: relative;
    display: inline-block;
}

.status-badge {
    position: absolute;
    left: calc(100% - 90px);
    top: 63px;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 12px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    white-space: nowrap;
    text-align: left;
}

/* 状态代码end */

这个lefttop部分,可以根据“状态”标签的实际位置进行适当调整。

五、开始分享个人状态

上面配置好之后,刷新后台,会增加一个菜单:

选择好之后,保存更改。

前端页面就能显示:

预设的状态带有图标,输入的状态没有图标。

如果您想更换其他状态或者颜色,可以修改上面在functions.php的代码。

喜欢分享一下本站的博主个人状态功能这篇文章吗?您可以点击浏览我的博客主页 发现更多技术分享与生活趣事。

分享一下本站“朋友圈”的制作过程

作者陶其
2025年7月30日 11:33

感谢订阅陶其的个人博客!

本来我很少会写建站相关的博文,因为这些在网上一翻一大堆,写了也是重复造轮子。

不过昨天有个博主问到了本站的“朋友圈”是如何实现的,正巧这个“朋友圈”的创建并非是完全参考某一个教程搭建的,中间也有不少我的魔改,所以就记录一下。

PS1:本站“朋友圈”其实是对订阅的其他网站的RSS的内容的一个集合展示。

PS2:实现原理:

  1. 部署 FreshRSS 用于订阅其他博主/网站的 RSS 订阅源;
  2. 使用宝塔做了两个定时任务:
    1. 一个定时任务让 FreshRSS 刷新订阅源的最新内容;
    2. 另一个定时任务是将最新的前 n 条内容覆写到一个指定的 json 文件中。
  3. 在网站后台(WordPress)魔改了说说模块文件,其目的是读取的这个 json 内容并展示;
  4. 最后就形成了我现在的 “朋友圈” 的效果。

PS3:博主不会php语言,所以下面的魔改部分都是我摸索着配出来的,本着能用就行的态度写的,所以会有很多写的不对的地方,多多包涵,欢迎指正。

一、配置清单

下面是我的配置清单,我只能保证最终效果在本配置下生效。

  • 服务器系统: CentOS 7.9
  • 博客平台: WordPress 6.8.0及之后
  • 主题模板: Argon 1.3.5
  • 配置托管平台: 宝塔Linux面板(没有配置托管平台的,其过程也可以手搓)
  • RSS订阅工具: Fresh RSS

二、安装配置FreshRSS

点击跳转☞:【FreshRSS官网】

点击跳转☞:【FreshRSS官方安装文档】

点击跳转☞:【FreshRSS官方下载页面(发文时版本)】

2.1 下载FreshRSS

打开下载页面,拉到最下面,根据自己的需要下载zip或者tar.gz版本。

2.2 部署FreshRSS

  1. 将下载的压缩包上传到centos的某目录下并解压;
  2. 然后使用宝塔,点击“网站” > “添加站点”;
    1. “域名”:可以提前对主域名进行解析出一个二级域名,可以加SSL证书做成HTTP的;
    2. “根目录”:选择刚才解压的目录;
    3. 其他的默认即可。
  3. 创建好站点之后,点击站点后的“配置”,你可以根据需要进行后续配置,比如配置SSL证书;
  4. 默认使用80和443端口,记得开启防火墙,做好二级域名的DNS解析。这样的话,你就可以通过前面的二级域名访问到自己搭建的FreshRSS网站了。

2.3 添加RSS订阅源

根据需要添加“分类”,或者添加“订阅源”,此处的订阅源就是其他站点的RSS地址,订阅源的可选择分类就是上面自己添加的分类。

添加完订阅源之后,返回首页刷新就会加载最新的订阅源的内容。

到这一步,你就成功的能在FreshRSS看到其他站点的文章了。

但是FreshRSS有一个问题,就是不能主动刷新订阅源,需要我们手动点击页面的【⟳】按钮才能刷新。

我们要的是定时自动刷新,所以我们还需要做相关配置,详情见下面第六节。

2.4 配置FreshRSS

  1. 打开你的FreshRSS的域名,并进行登陆。

  2. 点击 设置 > 管理 > 认证;

    1. 勾选“允许 API 访问”并提交。
  3. 点击 设置 > 账户 > API管理;

    1. 设置密码并提交保存,记住设置的api密码。
    2. 复制网址,将在下一步配置文件中用于${网址1}

  4. 在自己站点(WordPress)根目录下创建一个php文件,用于放FreshRSS api调用函数,例如:rss.php。
    例如:

    • 我的博客网站根目录为:/www/wwwroot/www.tqazy.com
    • 我的FreshRSS根目录为:/www/wwwroot/rss.tqazy.com
      那么我就在 /www/wwwroot/www.tqazy.com 下创建创建一个文件:rss.php,内容如下:
<?php
/**
 * 获取最新订阅文章并生成JSON文件
 */
function getAllSubscribedArticlesAndSaveToJson($user, $password)
{
$apiUrl = '${网址1}';
    $loginUrl = $apiUrl . '/accounts/ClientLogin?Email=' . urlencode($user) . '&Passwd=' . urlencode($password);
    $loginResponse = curlRequest($loginUrl);

    // 处理可能的cURL错误
    if (isset($loginResponse['error'])) {
        die('登录请求失败: ' . $loginResponse['error']);
    }

    if (strpos($loginResponse, 'Auth=') !== false) {
        $authToken = substr($loginResponse, strpos($loginResponse, 'Auth=') + 5);
        $articlesUrl = $apiUrl . '/reader/api/0/stream/contents/reading-list?&n=1000';
        $articlesResponse = curlRequest($articlesUrl, $authToken);

        // 处理可能的cURL错误
        if (isset($articlesResponse['error'])) {
            die('获取文章失败: ' . $articlesResponse['error']);
        }

        $articles = json_decode($articlesResponse, true);
        if (isset($articles['items'])) {
            usort($articles['items'], function ($a, $b) {
                return $b['published'] - $a['published'];
            });
            $subscriptionsUrl = $apiUrl . '/reader/api/0/subscription/list?output=json';
            $subscriptionsResponse = curlRequest($subscriptionsUrl, $authToken);

            // 处理可能的cURL错误
            if (isset($subscriptionsResponse['error'])) {
                die('获取订阅失败: ' . $subscriptionsResponse['error']);
            }

            $subscriptions = json_decode($subscriptionsResponse, true);
            if (isset($subscriptions['subscriptions'])) {
                $subscriptionMap = array();
                foreach ($subscriptions['subscriptions'] as $subscription) {
                    $subscriptionMap[$subscription['id']] = $subscription;
                }
                $formattedArticles = array();
                foreach ($articles['items'] as $article) {
                    // 去掉以 http 或 https 开头的链接
                    $contentWithoutLinks = preg_replace('/https?:\/\/[^\s?#]*?\.(jpg|jpeg|png|gif|mp4|mp3|webm|ogg|wav|flac|svg|bmp)\b/i', '', $article['summary']['content']);
                    $desc_length = mb_strlen(strip_tags(html_entity_decode($contentWithoutLinks, ENT_QUOTES, 'UTF-8')), 'UTF-8');
                    if ($desc_length > 20) {
                        $short_desc = mb_substr(strip_tags(html_entity_decode($contentWithoutLinks, ENT_QUOTES, 'UTF-8')), 0, 99, 'UTF-8') . '...';
                    } else {
                        $short_desc = strip_tags(html_entity_decode($contentWithoutLinks, ENT_QUOTES, 'UTF-8'));
                    }

                    $formattedArticle = array(
                        'site_name' => $article['origin']['title'],
                        'title' => $article['title'],
                        'link' => $article['alternate'][0]['href'],
                        'time' => date('Y-m-d H:i', $article['published']),
                        'description' => $short_desc,
                    );

                    $subscriptionId = $article['origin']['streamId'];
                    if (isset($subscriptionMap[$subscriptionId])) {
                        $subscription = $subscriptionMap[$subscriptionId];
                        $iconUrl = $subscription['iconUrl'];
                        $filename = '${网址2}/' . substr($iconUrl, strrpos($iconUrl, '/') + 1);
                        $formattedArticle['icon'] = $iconUrl;
                    }

                    $formattedArticles[] = $formattedArticle;
                }

                saveToJsonFile($formattedArticles);
                return $formattedArticles;
            } else {
                die('Error retrieving subscriptions.');
            }
        } else {
            die('Error retrieving articles.');
        }
    } else {
        die('Login failed: ' . $loginResponse);
    }
    return null;
}

function curlRequest($url, $authToken = null)
{
    $ch = curl_init($url);
    if ($ch === false) {
        return ['error' => 'cURL初始化失败'];
    }

    $headers = [];
    if ($authToken) {
        $headers[] = 'Authorization: GoogleLogin auth=' . $authToken;
    }

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FAILONERROR, true); // 捕获HTTP错误

    $response = curl_exec($ch);
    if ($response === false) {
        $error = curl_error($ch);
        curl_close($ch);
        return ['error' => $error];
    }

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode >= 400) {
        return ['error' => "HTTP请求失败,状态码:$httpCode"];
    }

    return $response;
}

/**
 * 将数据保存到JSON文件中
 */
function saveToJsonFile($data)
{
    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    file_put_contents('friends_rss.json', $json);
    echo '数据已保存到JSON文件中';
}

// 调用函数并提供用户名和密码
getAllSubscribedArticlesAndSaveToJson('${账户}', '${密码}');

代码中的替换项:

  • ${网址1}:上一步复制的网址;
  • ${网址2}:替换成你FreshRSS的域名地址,比如:https://rss.xxx.com
  • ${账户}:FreshRSS 的账户
  • ${密码}:这里是第3步设置的api密码

调用这个rss.php文件,就能从FreshRSS中把最新的订阅文章复写到一个叫friends_rss.json的文件中。

三、配置“朋友圈”模板文件

我们拿到了需要展示的数据,那么我们就要有一个展示的模板。

我的朋友圈设计是仅展示订阅文章的“文章名”、“发布时间”、“发布网站”、“文章前n个字符”等,并不会显示全文,如图:

这个模板其实是由WordPress的说说魔改的,去掉了翻页(仅展示前n条最新文章)、去掉了评论、去掉了点赞、新增了作者栏、修改了标题名自动加书名号、修改了内容超出部分自动加…等。

在目录/www/wwwroot/www.tqazy.com/wp-content/themes/argon-theme-master下创建文件:friend_rss.php。
内容如下:

<?php 
/* 
Template Name: 朋友圈 
*/ ?>

<?php get_header(); ?>

<div class="page-information-card-container">
    <div class="page-information-card card bg-gradient-secondary shadow-lg border-0">
        <div class="card-body">
            <h3 class="text-black"><?php _e('${页面名}', 'argon'); ?></h3>
            <?php if (the_archive_description() != '') { ?>
                <p class="text-black mt-3">
                    <?php the_archive_description(); ?>
                </p>
            <?php } ?>
            <p class="text-black mt-3 mb-0 opacity-8">
                <i class="fa fa-quote-left mr-1"></i>
                <?php _e('${页面提示语}', 'argon'); ?>
            </p>
        </div>
    </div>
</div>

<?php get_sidebar(); ?>

<div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">
        <?php

    // 定义自定义模板标签函数
    function the_site_name() {
        global $post;
        echo esc_html($post->post_site_name);
    }

    function the_icon() {
        global $post;
        echo esc_url($post->post_icon);
    }

        // 获取JSON数据
        $jsonData = file_get_contents('${json所在目录地址}');
        // 检查文件读取是否成功
        if ($jsonData!== false) {
            // 将JSON数据解析为PHP数组
            $articles = json_decode($jsonData, true);
            if ($articles!== null) {
                // 对文章按时间排序(最新的排在前面)
                usort($articles, function ($a, $b) {
                    return strtotime($b['time']) - strtotime($a['time']);
                });
                // 设置每页显示的文章数量
                $itemsPerPage = ${文章数量};
                // 生成文章列表
                $displayArticles = array_slice($articles, 0, $itemsPerPage);
                if (!empty($displayArticles)) {
                    global $post;
                    foreach ($displayArticles as $article) {
                        // 模拟WordPress文章对象
                      // 将 $article['time'] 转换为 MySQL 时间戳格式
                      $formatted_time = date('Y-m-d H:i:s', strtotime($article['time']));
                      $new_article = "  作者:" . $article['site_name'];

                        $post = (object) [
                            'ID' => $article['id']?? uniqid(), // 如果JSON中没有id字段,使用唯一ID
                            'post_title' => "《" . $article['title'] . "》",
                            'post_date' => $formatted_time,
                            'post_content' => $article['description'],
                            'guid' => $article['link'],
                            'post_permalink' => $article['link'],
                            'post_site_name' => $new_article,
                            'post_icon' => $article['icon'],                         

                        ];
                        setup_postdata($post); // 设置当前文章数据

                        get_template_part('template-parts/content', 'friend');

                        wp_reset_postdata(); // 重置文章数据
                    }
                } else {
                    get_template_part('template-parts/content', 'none-tag');
                }
            } else {
                get_template_part('template-parts/content', 'none-tag');
            }
        } else {
            get_template_part('template-parts/content', 'none-tag');
        }
        ?>

<?php get_footer(); ?>

替换项:

  • ${页面名}:页面名称,比如:朋友圈;

  • ${页面提示语}:在页面名称下面显示的提示语,比如:这里是已交换友链的网站发布的内容,通过RSS方式订阅,每1小时更新一次内容。

  • ${json所在目录地址}:前面rss.php生成的json所在地址,比如:/www/wwwroot/www.tqazy.com/friends_rss.json

  • ${文章数量}:即你要展示的文章数量,比如:38。可以写50及以内,如果经常看朋友圈的话,设置展示太多了没意义。

四、配置“朋友圈”配套文件

在目录/www/wwwroot/www.tqazy.com/wp-content/themes/argon-theme-master/template-parts下创建文件:content-friend.php,上面的文件用得到,属于样式配置。

内容如下,这个文件没有替换项:

<div class="shuoshuo-container">
    <div class="shuoshuo-meta shadow-sm">
        <span>

            <i class="fa fa-calendar-o" aria-hidden="true"></i> 
             <span class="shuoshuo-date-month"><?php echo get_the_time('n')?></span> <?php _e('月', 'argon');?> 
            <span class="shuoshuo-date-date"><?php echo get_the_time('d')?></span> <?php _e('日', 'argon');?> , 
            <span class="shuoshuo-date-year"><?php echo get_the_time('Y')?></span>
            <div class="post-meta-devide">|</div>
            <i class="fa fa-clock-o" aria-hidden="true"></i> 
            <span class="shuoshuo-date-time"><?php echo get_the_time('G:i:s')?></span>
        </span>
        <?php if ( is_sticky() ) : ?>
            <div class="post-meta-devide">|</div>
            <div class="post-meta-detail post-meta-detail-words">
                <i class="fa fa-thumb-tack" aria-hidden="true"></i>
                <?php _ex('置顶', 'pinned', 'argon');?>
            </div>
        <?php endif; ?>
    </div>
    <article class="card shuoshuo-main shuoshuo-foldable bg-white shadow-sm border-0" id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <?php if ( get_the_title() != '' ) : ?>
            <a class="shuoshuo-title" href="<?php the_guid(); ?>" target="_black"><?php the_title(); ?></a>
            <font style="font-weight:900;"><?php the_site_name(); ?></font>
        <?php endif; ?>

        <div class="shuoshuo-content">
            <?php the_content(); ?>
        </div>
        <?php
            global $withcomments;
            $withcomments = true;
//          comments_template( '/comments-shuoshuo-preview.php' );
        ?>
    </article>
</div>

此时,“朋友圈”的模板部分就编写完毕了。

在网站后台可以看到:外观 > 主题文件编辑器 > friend_rss.php

五、展示“朋友圈”页面

第一步:博客后台 > 页面 > 添加页面:

  1. 页面名称:朋友圈
  2. 正文不用填写任何内容
  3. 设置右边的页面属性:
    1. 父级:无
    2. 模板:朋友圈
    3. 发布

第二步:博客后台 > 外观 > 菜单 > 选择要编辑的菜单,然后在左侧的页面里找到“朋友圈”,添加到菜单,至于剩下的可以自行配置了。

比如我的朋友圈就是放在“友链”菜单下的:

到此,“朋友圈”功能已经成功的添加到了你的网站上了。

六、自动刷新朋友圈

最重要的一步来了,我们要想自动刷新朋友圈,而不是每次都去调用rss.php文件,那么我们就要做定时任务。

我也不知道为什么我单调rss.php文件是不能刷新FreshRSS的订阅源的,所以我做了两个定时任务。

我是使用宝塔的,如果您没有宝塔,可以通过写脚本方式实现。

打开宝塔面板 > 计划任务:

6.1 第一个定时任务

  1. 添加任务;
  2. 选择:Shell脚本;
  3. 任务名称:定时刷新FreshRSS;
  4. 执行周期:每小时 1分钟;
  5. 脚本内容:php /www/wwwroot/rss.tqazy.com/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
  6. 确定

需要把这里的/www/wwwroot/rss.tqazy.com替换成你的rss解压文件所在的目录地址。

6.2 第二个定时任务

  1. 添加任务;
  2. 选择:访问URL-GET;
  3. 任务名称:朋友圈订阅数据更新;
  4. 执行周期:每小时 5分钟;
  5. URL地址:https://xxx.com/xxx/xxx/rss.php
  6. 确定

需要把这里的https://xxx.com/xxx/xxx/rss.php换成你的博客网站能访问到rss.php的域名地址。

你可以执行一下,看看日志,是否成功的写入了。

至此,朋友圈的功能全部完成。

效果:
该功能会将在FreshRSS中订阅的订阅源,以每小时1次的频率自动刷新订阅源并读取到friends_rss.json中,然后模板通过读取friends_rss.json文件将最新的n条文章展示到“朋友圈”的页面中。

注意:每次您的网站新增友链时,需要将对方的rss地址手动的添加到你的FreshRSS中。

喜欢分享一下本站“朋友圈”的制作过程这篇文章吗?您可以点击浏览我的博客主页 发现更多技术分享与生活趣事。

❌