三无青年

热爱生活,重新开始

月度归档: 2024 年 10 月

  • 如何在 WordPress 首页显示 Memos 最新动态

    准备工作

    确保已安装 WordPress 并启用了适合的主题:以我的主题为例,适用于大多数 WordPress 主题。

    获取 Memos 的 RSS 订阅地址:比如我的链接为 https://memos.duanxiansen.com/u/1/rss.xml,根据你的 Memos 实际 RSS 链接替换。

    编写函数获取 Memos 最新动态

    需要编写一个函数,使用 WordPress 的 wp_remote_get() 函数从 RSS 链接获取数据,并解析出最新的一条动态。

    首先,打开 WordPress 主题目录中的 functions.php 文件,添加以下代码:

    // 获取 Memos 最新一条动态并显示
    function display_latest_memo() {
        // 通过 wp_remote_get 获取 RSS 数据
        $response = wp_remote_get('https://memos.duanxiansen.com/u/1/rss.xml'); // 替换为你的 Memos RSS 网址
        if (is_wp_error($response)) {
            return '无法获取 Memos 数据';
        }
    
        // 获取响应的主体内容
        $body = wp_remote_retrieve_body($response);
    
        // 将 RSS 数据解析为 XML
        $data = simplexml_load_string($body);
    
        // 检查返回的数据是否为空
        if (empty($data) || !isset($data->channel->item[0])) {
            return '没有找到最新的 Memos 动态';
        }
    
        // 获取最新一条动态
        $latest_memo = $data->channel->item[0];
    
        // 将 RSS 中的时间转换为 WordPress 时区时间
        $rss_date = (string)$latest_memo->pubDate; // 获取 RSS 中的发布时间
    
        // 创建 DateTime 对象并设置为 RSS 的时间
        $date = new DateTime($rss_date);
    
        // 将时间转换为 WordPress 时区
        $date->setTimezone(new DateTimeZone(get_option('timezone_string')));
    
        // 格式化时间为 Y-m-d H:i:s 格式
        $formatted_date = $date->format('Y-m-d H:i:s');
    
        // 获取描述内容(通常是动态的主要内容)
        $content = (string)$latest_memo->description;
    
        // 限制字数(例如,显示最多300个字符)
        $excerpt = mb_substr($content, 0, 300);
        if (mb_strlen($content) > 300) {
            $excerpt .= '... <a href="' . esc_url($latest_memo->link) . '" target="_blank">阅读更多</a>'; // 链接到原文
        } else {
            $excerpt .= ' <a href="' . esc_url($latest_memo->link) . '" target="_blank">查看原文</a>'; // 如果字数较短,显示“查看原文”
        }
    
        // 输出最新动态的内容、时间和链接
        $output = '<div class="latest-memo memos-center">';
        $output .= '<h3>最新动态:</h3>';
        $output .= '<p>' . $excerpt . '</p>';
        $output .= '<p>时间:' . esc_html($formatted_date) . '</p>';
        $output .= '</div>';
    
        return $output;
    }
    
    // 创建一个短代码来显示 Memos 最新动态
    add_shortcode('latest_memo', 'display_latest_memo');
    

    在首页显示最新动态

    接下来,要让 Memos 最新动态只显示在首页文章的最上方。为此,需要修改 header.php 或者 index.php 文件,在首页判断条件下调用定义的短代码。

    1. 打开主题目录下的 header.php 文件,找到适当位置(如头部模板部分)插入以下代码:
      <!-- 在首页显示最新的 Memos 动态 -->
      <?php if ( is_home() || is_front_page() ) : ?>
          <div class="memos-latest">
              <?php echo do_shortcode('[raw][latest断开_memo][/raw]'); ?>
          </div>
      <?php endif; ?>
      
    2. is_home()is_front_page():这两个函数确保只有在首页显示动态,而其他页面不会显示。is_home() 用于判断博客文章列表页,is_front_page() 用于判断自定义的前端首页。

    样式调整(居中显示)

    将以下 CSS 代码添加到你的主题 style.css 文件中:

    .memos-latest {
        text-align: center; /* 水平居中内容 */
        margin: 20px auto; /* 上下外边距并居中容器 */
        padding: 10px;
        background-color: #f5f5f5; /* 背景颜色 */
        max-width: 600px; /* 设置容器最大宽度 */
        border-radius: 10px; /* 圆角效果 */
    }
    
    .memos-latest h3 {
        font-size: 1.5em;
    }
    
    .memos-latest p {
        font-size: 1.2em;
    }
    
    .memos-latest a {
        text-decoration: none;
        color: #0073aa; /* 链接颜色 */
    }

    结尾

    就这样吧,不完美的就是不能直接评论,需要点进去到memos页面,继续完善吧。

  • 独立博客的自省与思考

    最近看到雅余兄的《独立博客自省问卷15题》,不少博友都写了自己的回答,我也借此机会反思一下我的博客历程。

    1. 博客更新频率是多少? 更新频率不太稳定,懒癌发作的时候会好几个月不更新。但最近几周更新频繁,有时候甚至一天几篇。

    2. 博客上次更新是什么时候?上周。自从八月份以来,还是保持了比较高的更新频率。

    3. 博客文章是原创的吗? 大多数文章是原创,但有时也会借助共创的代码或教程来帮助完成一些技术性的内容。毕竟它不给我代码,我也没办法写下去。

    4. 文章对他人有帮助吗? 多少会有些意义吧。尽管有些文章是自我记录,但相信对某些读者来说,可能也有启发。

    5. 上次更换博客主题是什么时候? 这个问题对我来说很容易回答——前两天刚换!换主题对我来说就像日常活动一样,最高记录是一周内换了十个。

    6. 上一次捣腾博客代码是什么时候? 昨天刚折腾到半夜,时常在代码上摸索,有时表达不清还会和GPT沟通不顺畅(笑)。

    7. 会进行二次开发吗? 会的,虽然主题设置是为了方便,但我还是忍不住加些个人风格,比如更换字体。我每次换主题都必须用霞鹭文楷。

    8. 多久会打开博客自我陶醉一次? 几乎每天都要看几次,尤其是查看流量,虽然大多数PV可能都是我自己刷的。

    9. 近期对博客域名的感受? 域名目前没什么想法,虽然博客的主题和程序经常变动,但域名倒是一直稳定。

    10. 每天看网站流量统计吗? 是的,每天看几次,尤其是睡前看看访客来源。使用的是百度统计,非常方便。

    11. 通过博客赚到钱了吗? 没有,我拒绝广告。广告真的会影响阅读体验,所以我宁愿保持纯净的界面。

    12. 浏览别人的博客主要为什么? 主要是为了学习他们的设计和排版,看到别人的博客总觉得比自己做得好,这也是我频繁更换主题的原因之一。

    13. 看到别人分享的文章,第一反应是什么? 首先会注意网站的加载速度,尤其是图片延迟加载的效果,真的是一种丝滑的体验。

    14. 觉得博客哪方面更重要? 内容和主题都很重要,二者不可或缺,毕竟鱼与熊掌我都想兼得。

    15. 通过写博客有哪些新收获? 确实学到了不少新知识,认知也提升了。很多之前不理解的地方现在懂了,甚至在技术上有了更多的自信。

  • 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]

  • 24-九月小结

    生活

    九月份的生活有些波澜不惊。值班的两天三夜显得格外无聊,连打麻将都提不起兴趣,吃饭也成了问题。结果,两天里我吃了四顿烤肉,吃到后来再也不想碰烤肉了。原本计划国庆假期去新疆找爸爸,想着今年他可能不回家,但看了看机票价格,只好暂时放弃了这个计划。

    镇上有泸州老窖的代理宣传特曲酒,尝了尝味道还不错,扫二维码还可以领个小红包。

    家里的电信宽带本来上个月取消了一些服务,这个月按理说只需要交62元就够了,结果交了100元还显示欠费。打电话去咨询,客服一开始说套餐是72元,但上个月明明告诉我是62元。搞得我一头雾水,投诉后又说是客服看错了,确实应该是62元。最后我稀里糊涂把钱交了,如果下个月还是这样,我就准备向工信局投诉,听说这种投诉很管用。

    常点的一家烤肉拌饭店突然在美团上找不到了,点进去后发现变成了炸鸡店,过了几天又恢复了原样,完全搞不懂这是在搞什么操作。

    值得一提的是,这个月我发掘了自己做饭的技能,干煸豆角做得又咸又香,家人都说好吃。不过我做的一道叫“洋芋齐花”的面食,被岳父说成像饺子,我妹妹则说像拌面,这真的是那么不像吗?

    工作

    这个月只值了一次班,想着国庆假期出去玩,就没有申请其他值班,估计过年时就要轮到我了。

    单位新来了一位“三支一扶”的女同事,没对象的同事们都纷纷上去帮忙搬东西,结果一问,人家已经有男朋友了,真是让人哭笑不得。

    博客

    这个月折腾了好几个博客主题,换了将近十个,但没有一个真正让我满意。可能是我不太适合自定义吧,最后还是换回了“知更鸟”主题,省心省力,不用自己操心。

    恢复了memos后,越来越觉得这个工具真的好用,随时随地都能发。我用的是苹果手机,moememos的发表功能非常方便。虽然部署memos的过程有些波折,但整体上并不复杂,主要是前期没什么头绪,最后我成功部署了18.1版本,并且配上了twikoo评论系统。相比artalk,我觉得twikoo更好用一些。

    既然部署了memos,当然也不能少了木木的哔哔广场。我已经把它集成到了博客中,虽然还有很多问题需要解决,但适配的过程也不急,慢慢来。

    此外,我还搭建了足迹地图,虽然还差点意思,但打算慢慢改进,不急于求成。

    在使用“知更鸟”主题之前,我自己折腾了一个读者墙,样式跟张戈博客类似,不过由于插件没有及时更新,效果不太理想。后来我自己修改了一下,总体还算满意。现在“知更鸟”主题自带这个功能,所以我就放弃了自己做的版本。

    友链页面也是我手工编辑的,放弃了“知更鸟”自带的友链模板,效果还不错。

    评论等级系统也折腾了一阵,最终实现了我想要的效果。感谢群友们的帮助,成功解决了按邮箱获取评论数的问题,确实比用user_id更合适。

    写了一大堆白话文,九月份也就结束了。

  • 临夏短途游记:壮丽水库与松鸣岩初体验

    今年国庆,本打算去天水玩,但计划总赶不上变化。由于家里只剩下奶奶独自一人,最终决定临近去转一转,然后回来照顾她。于是,临时改了行程,决定去临夏。

    3日 | 出发兰州新区 & 游湿地公园

    一早出发去送妹妹。经过两个多小时的车程,我们抵达了中川机场。机场停车位紧张,绕了半个小时才找到位置。等妹妹安检完毕,已经是十一点半了。

    兰州新区没什么太多可玩的地方。大舅哥推荐了新区的商场、湿地公园和秦王川文创园。商场老婆喜欢,但我没兴趣;秦王川之前去过,感觉一般。于是,我们决定去湿地公园,尽管季节并不合适。

    湿地公园很大,风景虽好,但这个时节略显荒凉。高高的芦苇随风摆动,让人不禁联想到玉米地。公园里几乎没什么人,寥寥数人,让我们感觉像是包场了一样。转了一圈,觉得没什么新意,于是商量着接下来去哪儿。大舅哥提议,由于时间紧张,可以去临夏,天水太远,人又多,来不及细游。

    3日 | 刘家峡水库初体验

    下午三点,我们从新区出发,直奔临夏,先去刘家峡水库。

    刘家峡水库位于黄河上游,是中国第一个五年计划期间由自己设计、施工、建造的大型水电工程,竣工于1974年。它被誉为“高原明珠”,不仅景色壮观,还具备发电、防洪、灌溉等多功能。

    我们在六点左右抵达水库,这是我第一次来这里,身为甘肃人,竟然从未到过这壮丽的地方。黄昏下,水库静谧而震撼,水面波光粼粼,远处的高原峡谷景象让人心生敬畏。由于天色渐晚,旁边的炳灵寺没有去,只是在观景台上远眺,体验了一下水库的雄伟景观。

    稍作休息后,我们继续出发,八点左右抵达临夏州,安顿下来,准备第二天的行程。

    4日 | 松鸣岩 & 花儿盛会

    第二天早上,我们前往松鸣岩。

    位于和政县,是河州八景之一,海拔2730米。松鸣岩以每年农历四月二十六至二十八的“花儿”盛会闻名,这段时间,当地群众和外地游客会聚集于此,边欣赏美景,边漫唱“花儿”民歌,场面非常热闹。

    然而,我们刚到松鸣岩时,闹了个笑话。原本我们以为已经进入景区,转了半天,周围冷冷清清,几乎没人。后来才知道,原来我们误入了后门,停在了吃饭的地方,白白花了十元停车费,哈哈,真是有点尴尬。

    在正式景区入口,我们发现需要买票。我跟着老婆和她闺蜜一前一后走进景区,结果被工作人员拦住:“票呢?”我才意识到需要门票,乖乖地去买了一张45元的票。虽然老婆替我省了90元,但这不免让我有些小郁闷。

    进入景区后,徒步上山的过程相当累,尤其是路边的景色也没什么特别之处,只是两旁的白杨树显得格外肃穆。走到一半时,看到路标才知道我们仅仅走了一半,而精华景点还在前方。咬牙坚持了下来,最终到达了山顶,看到那里的寺庙时,我已经累得没力气再继续上去了。早知如此,真该坐观光车上来。

    稍作休息后,我们决定坐观光车下山,票价每人10元,倒也方便了不少。

    临夏美食 & 返程

    来到临夏,怎么能不尝尝他们的特色美食——手抓羊肉呢?由于时间紧迫,我们通过美团锁定了和政县城的“二洒手抓”。晚饭后,匆匆启程返家。晚上八点半终于到家,眼睛都快睁不开了,结束了这次临夏短途游。

    虽然行程不长,但一路上风景独特,美食可口,给这次国庆增添了不少色彩。