三无青年

热爱生活,重新开始

分类: 折腾

关于博客在运营中所遇到的问题及解决方法

  • WordPress 展示 GoToSocial 的说说内容(朋友圈风格插件 + Access Token 获取教程)

    写在前面

    最近折腾了一套自己的 Fediverse 微博系统 —— GoToSocial,并搭配自己博客做了一个说说页面,把我日常发布的内容聚合进来,就像一个“朋友圈”一样。

    为了方便管理和扩展,我写了一个 WordPress 插件,通过短代码 [...gotosocial_say_ajax] (去掉...)实现在页面中展示自己的 GoToSocial 说说内容,支持图片、评论、点赞数展示,还实现了“加载更多”的功能。

    今天这篇文章,我就把这个插件和实现方法分享出来,并附上完整使用教程与 Access Token 的获取方法,希望能帮到也想整合去中心化社交内容的博友们。


     插件介绍:GoToSocial 说说展示 for WordPress

    这个插件的主要功能包括:

    • 展示指定 GoToSocial 用户的说说内容
    • 支持图片展示,点击放大,自动横排布局
    • 展示评论内容(头像 + 用户名 + 评论)
    • 显示点赞(❤️)、转发(🔁)、评论(💬)统计
    • 加载更多功能,自动分页
    • 样式优化为“朋友圈”风格
    • 兼容手机端,响应式布局

    插件完全开源,使用无门槛:

    GitHub 地址:
    https://github.com/2443266417/gotosocial-wordpress-plugin

    插件效果演示:
    https://www.duanxiansen.com/gotosocial


     插件安装教程(详细步骤)

    第一步:下载插件

    直接访问 GitHub:
    https://github.com/2443266417/gotosocial-wordpress-plugin

    下载 ZIP 压缩包后解压上传:

    1. 登录 WordPress 后台 → 插件 → 安装插件 → 上传插件 → 选择 ZIP 上传
    2. 或者 FTP 上传到 wp-content/plugins/ 目录

    安装并启用插件。


    第二步:配置插件参数

    插件启用后,在后台「设置」菜单下会多出一项「GoToSocial 设置」。

    需要配置以下参数:

    配置项 示例值 说明
    GoToSocial 用户名 duanxiansen 即你的帐号名
    实例地址 https://duanbo.cc 必须是完整网址
    每页加载数量 10 建议为 10 或更小
    Access Token xxxxxxx 用于私密 API 授权

    注意:Access Token 为必选字段,必须填写。


    如何获取 GoToSocial Access Token?

    如果你使用的是我推荐的 duanbo.cc 实例部署方式或自建并启用了后台面板,那获取 Access Token 非常简单。

     推荐方法:后台面板直接获取

    进入你部署的 GoToSocial 实例后台,使用管理员账号登录后台控制面板。

    进入【Applications / 应用】管理页面。

    新建一个应用。

    点击应用详情,点击Request access token。

    复制其中的 Access Token(访问令牌)。


    在页面中插入短代码

    插件通过短代码实现动态展示。

    • 进入 WordPress → 页面 → 新建页面
    • 输入如下短代码: [...gotosocial_say_ajax] (去掉...
    • 发布页面,访问即可看到你发布的 GoToSocial 动态内容。

    支持“加载更多”、“评论展示”、“点击放大图片”等功能。


    展示效果

    以下是插件展示效果:

    说说展示

    • 显示头像、昵称、时间
    • 自动分页加载

    多图支持

    • 多图自动横排布局
    • 图片点击放大

    评论展示

    • 显示评论者头像、昵称、内容
    • 支持点击跳转查看更多评论

    常见问题 FAQ

    1. 为什么图片不显示?

    • 检查实例地址是否 https:// 开头
    • 检查是否填写 Access Token

    2. 评论为什么不全?

    • 默认最多显示 3 条评论,其余通过“查看更多评论”跳转查看

    3. 多图为什么没有横排?

    • 检查主题是否影响 p 标签自动嵌套问题,可用插件或主题兼容

    4. 插件是否支持 Mastodon?

    • 原生接口兼容 Mastodon,但评论结构等差异较大,仅建议用于 GoToSocial

    总结

    这个插件是我用来展示 GoToSocial 说说内容的轻量方案,基于 AJAX 动态加载,并优化了移动端和展示样式。

    功能虽然简单,但基本满足了“朋友圈”展示的需求,非常适合喜欢折腾博客 + 去中心化社交的朋友。

    如果你也搭建了自己的 GoToSocial 实例,不妨试试这款插件,轻松打造你自己的公开“朋友圈”页面。

  • 宝塔面板部署GoToSocial实例全流程指南

    宝塔面板部署GoToSocial实例全流程指南

    一、GoToSocial 项目简介

    GoToSocial 是一款基于 ActivityPub 协议  的轻量级联邦社交网络服务器,支持去中心化内容分享,强调用户隐私与数据自主。通过本教程,你将在宝塔面板环境中完成以下目标:

    • 搭建独立社交网络实例
    • 配置 HTTPS 访问与反向代理
    • 创建管理员账户并管理普通用户
    • 实现数据持久化与定期备份

    二、服务器与宝塔初始化

    1. 基础设施准备

     服务器选型

    • 推荐配置:2核4GB内存 + 20GB存储(阿里云/腾讯云轻量服务器)
    • 操作系统:Ubuntu 22.04 LTS(兼容性最佳)
    • 防火墙开放端口:22(SSH)、80(HTTP)、443(HTTPS)、8080(GoToSocial服务)

    域名解析

    注册域名(如 social.example.com),在域名服务商处添加 A记录指向服务器IP,等待解析生效(约10分钟)。

    2. 宝塔面板安装

    登录服务器终端,执行以下命令:

    sudo apt update && sudo apt install -y wget  
    wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh  
    sudo bash install.sh

    安装完成后,复制宝塔登录链接(如 http://服务器IP:8888/xxx),使用生成的账号密码登录。

    3. 安装必备组件

    在宝塔「软件商店」依次安装:

    • Docker(容器化运行环境)
    • Docker Compose(容器编排工具)
    • Nginx(反向代理服务器)

    三、项目目录与权限配置

    1. 创建专用数据目录

    在宝塔「终端」执行:

    mkdir -p /opt/gotosocial/data  # 创建项目数据目录  
    chown -R 1000:1000 /opt/gotosocial/data  # 匹配容器默认用户权限

    原理:GoToSocial 容器默认以用户 1000 运行,需确保宿主目录所有者为相同 UID/GID,避免权限错误。

    2. 下载 Docker Compose 模板

    cd /opt/gotosocial  
    wget https://raw.githubusercontent.com/superseriousbusiness/gotosocial/main/example/docker-compose/docker-compose.yml -O docker-compose.yaml

    若下载失败,手动从 [官方仓库]复制内容保存。

    四、容器配置与启动

    1. 编辑 docker-compose.yaml

    在宝塔「文件」中打开  /opt/gotosocial/docker-compose.yaml ,修改以下关键参数:

    services:  
      gotosocial:  
        image: docker.io/superseriousbusiness/gotosocial:latest  
        environment:  
          GTS_HOST: social.example.com  # 替换为你的域名  
          TZ: Asia/Shanghai  
          GTS_LETSENCRYPT_ENABLE: false  # 关闭容器内HTTPS,由宝塔处理  
        ports:  
          - "127.0.0.1:9090:8080"  # 仅本地监听,通过Nginx反代到公网  
        volumes:  
          - /opt/gotosocial/data:/gotosocial/storage

    2. 启动容器

    cd /opt/gotosocial  
    docker-compose up -d  # 后台启动容器(首次拉取镜像需等待2-3分钟)

    验证状态:执行  docker ps ,若显示 127.0.0.1:9090->8080/tcp 且状态为 Up ,表示启动成功。

    五、宝塔反向代理与 HTTPS 配置

    1. 创建站点并申请 SSL 证书

    步骤1:添加站点

    在宝塔「网站」→「添加站点」中填写:

    • 域名:social.example.com
    • 数据库:不创建(GoToSocial 使用内置数据库)

    步骤2:申请证书

    进入站点「SSL」→「Let's Encrypt」,勾选「强制HTTPS」和「HTTP/2」,点击「申请」生成证书。

    2. 配置 Nginx 反向代理

    在站点「设置」→「反向代理」中添加:

    • 目标URL:http://127.0.0.1:9090
    • 高级设置:勾选「终止SSL」,自动填充证书路径
    • 完整配置:
      location / {  
          proxy_pass http://127.0.0.1:9090;  
          proxy_set_header Host $host;  
          proxy_set_header X-Forwarded-Proto $scheme;  
          proxy_http_version 1.1;  
          proxy_set_header Upgrade $http_upgrade;  
          proxy_set_header Connection "upgrade";  
          proxy_ssl_server_name on;  # 解决502错误关键配置  
      }

    保存后 Nginx 自动重载配置。

    3. 验证 HTTPS 访问

    打开浏览器访问 https://social.example.com ,若显示登录页面且地址栏有锁图标,说明配置成功。若遇  502 Bad Gateway ,检查:

    1. 容器状态(docker ps
    2. 反向代理目标 URL 是否正确
    3. 宝塔防火墙是否放行 9090 端口

    六、用户管理与权限配置

    1. 查询容器 ID

    docker ps -a  # 复制 CONTAINER ID(如 98999461e756)

    2. 进入容器终端

    docker exec -it 98999461e756 /bin/sh  # 替换为实际容器 ID

    3. 创建管理员账户

    ./gotosocial --config-path /gotosocial/config.yaml admin account create \  
        --username admin_user \  
        --email admin@example.com \  
        --password 'Strong!Pass2025' \  
        --local-only  # 创建本地管理员账户(非联邦)

    密码要求:至少10位,包含大小写字母、数字、符号(如 MyPass!@#2025)。

    4. 提升普通用户为管理员

    ./gotosocial --config-path /gotosocial/config.yaml admin account promote --username demo_user

    验证方法:使用该账户登录后访问 /_admin ,若显示后台则提权成功。

    5. 删除用户(不可逆操作)

    ./gotosocial --config-path /gotosocial/config.yaml admin account delete --username demo_user

    七、常见问题与解决

    问题1:容器启动失败

    排查步骤:

    1. 检查数据目录权限:ls -ld /opt/gotosocial/data
    2.  查看容器日志:docker logs gotosocial
    3. 确保 GTS_HOST 与域名完全一致

    问题2:HTTPS 页面显示不安全

    解决方法:

    1. 在宝塔「SSL」中重新申请证书
    2. 清除浏览器缓存,使用无痕模式访问

    问题3:用户创建失败(邮箱已存在)

    处理流程:

    1. 进入容器:docker exec -it 容器ID /bin/sh
    2. 列出所有用户:./gotosocial admin account list
    3. 删除冲突账户:./gotosocial admin account delete --username 冲突用户名

    八、后续维护与升级

    1. 数据备份

    在宝塔「计划任务」中添加每周备份:

    任务类型:Shell脚本  
    命令:docker exec gotosocial tar czvf /gotosocial/storage/backup_$(date +\%Y\%m\%d).tar.gz /gotosocial/storage  
    执行周期:每周日0点

    2. 版本升级

    cd /opt/gotosocial  
    docker-compose pull  # 拉取最新镜像  
    docker-compose down --remove-orphans  
    docker-compose up -d  # 启动新版本

    3. 开放公共注册

    登录管理员后台 →「设置」→「注册」,勾选「允许新用户注册」,可选开启邀请码或邮箱域名限制。

    九、成功标志

    1. 浏览器访问 https://你的域名 显示登录页面,地址栏有锁图标。
    2. 管理员账户可登录后台,查看实例统计信息。
    3. 通过 [Fediverse 实例检测工具]验证联邦通信功能正常。

    通过本教程,你已完成从服务器初始化到用户管理的全流程操作,可根据实际需求扩展功能(如邮件通知、存储扩展)。部署过程中遇到问题时,建议对照步骤逐一排查,或参考 [GoToSocial 官方文档]获取更多细节。

    参考:博友阿均的教程文档

    我的gotosocial实例:段先森, @duanxiansen@duanbo.cc

  • 搭建 Discourse 论坛的实践与心得

    搭建 Discourse 论坛的实践与心得

    很久以来,我一直怀有搭建论坛的想法。从 2021 年开始,我尝试使用了多种论坛系统,比如 Discuz、Xiuno BBS、youBBS、HYPHP 和 Flarum 等等。经过不断摸索和比较,最终选择了 Discourse。

    Discourse 与传统论坛系统有所不同,尽管其官网教程看起来很简单,但实际操作并不容易。在我看来,相比其他论坛程序,Discourse 的安装和配置确实有一定的技术门槛。

    曾经,我记得有一个 Discourse 中文社区,但后来不知为何关闭了,现在只能依赖官网的资源来解决问题。此前,我尝试安装 Discourse 多次未果。这次借助 GPT,经过几天努力,总算完成了部署。接下来,我将分享我的一些经验,希望对其他博友有所帮助。

     安装 Discourse 的注意事项

    1. 端口问题

    我使用的是 VPS,并在上面安装了宝塔面板,其中已有多个网站运行。为了避免端口冲突,需要修改默认的 80 和 443 端口。可以直接在 `app.yml` 文件中进行更改。

    2. SMTP 邮件配置

    SMTP 设置是我遇到的最大难题之一。起初,我尝试使用 QQ 邮箱(端口 465),但邮件一直无法正常发送。奇怪的是,大约半小时后,QQ 邮箱开始大量发送邮件,但 Discourse 后台却显示邮件发送失败,且任务一直在进行。随后,我改用 587 端口,问题依旧。最终,我选择了 Gmail 邮箱,才成功解决邮件问题。

    QQ 邮箱并非完全不可用,但配置上可能存在不确定性;相比之下,Gmail 更稳定可靠。

    3. 安装目录的选择

    在安装 Discourse 之前,一定要选择好安装目录。如果需要重建容器但未指定目录位置,可能会导致数据丢失。因此,提前规划目录非常重要。

    4. 服务器配置要求

    Discourse 的内存和 CPU 占用较高,部署之前选择合适的机器非常关键。我之前安装失败的一个主要原因就是 VPS 内存不足。

     安装过程中的关键提示

    1. 耐心等待

    Discourse 的部署过程相对较慢,尤其是运行重建容器的命令时,可能需要 20 到 30 分钟甚至更久。尽管看似卡住了,其实后台一直在运行。所以安装过程中务必要确认 `app.yml` 配置无误,每次修改后都需要重构容器。

    2. 防止垃圾注册

    为了避免恶意注册,我部署的论坛采取了邀请注册的方式。此前使用 Discuz 时,因开放注册频频受到垃圾用户的骚扰,实在是令人头疼。

     欢迎加入我的社区

    经过多次努力,我成功部署了自己的论坛 Bokeuquan 社区。目前,该社区采取邀请注册机制,主要是为了维护良好的讨论环境。希望有兴趣的博友能加入,一起交流学习。如果你在部署过程中也有心得或疑问,欢迎分享你的经验!

    这里放一下我的邀请链接:http://bkq.net.cn/invites/jtAvmM8WzQ

    总结

    虽然 Discourse 的部署过程略显繁琐,但只要掌握基本流程和注意的点,安装和配置其实相对简单。以上是我在搭建过程中总结的一些要点和注意事项,希望能帮助到想要尝试的博友们。

  • 如何在 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页面,继续完善吧。

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

  • 利用Leaflet的想法构建足迹地图

    前言

    足迹地图我很早就知道咯,一直没有办法实现它,大发的地图插件Marker Pro很喜欢,但只是看看而已。直到发现了它——Leaflet,一个开源JavaScript库,适用于适合移动设备的交互式地图。
    只不过我的博客在国内,想着多一事不如少一事,图源换成国内的应该好点儿(我换成高德了),原理它差不多。就像博友说的,使用国外图源,一不小心,把一小块地画给国外,就是勾结外部势力了。话不多说,上教程。

    步骤

    我的想法是新建页面模版,独立页面显示。

    1、准备工作

    新建footprint.js文件,footprint.js文件应包含你的足迹点数据,上传这个文件到你主题目录的js文件里,比如:

    /wp-content/themes/your-theme/js/footprint.js

     

    footprint.js文件的内容

    const footprint = [ ["<b>银川</b><i>Yinchuan</i><a href='https://www.duanxiansen.com/84.html/'>银川镇北堡西部影视城三日游</a>", 38.46667, 106.26667], ["<b>榆中</b><i>Yuzhong</i><a href='https://www.duanxiansen.com/1303.html/'>记第一次滑雪</a>", 36.0620781, 103.8318566], ["<b>白银</b><i>Baiyin</i><a href='https://www.duanxiansen.com/1115.html/'>游黄河石林景区(公司第一次团建)</a>", 36.5340173, 104.1467575], // 添加更多点 ];

     

    2、创建自定义页面模版文件

    新建page-map.php文件,放在你的主题页面模版文件夹里。

    <?php
    /*
    Template Name: 足迹地图
    */
    
    get_header(); ?>
    
    <style>
    #map {
        width: 100%;
        max-width: 1200px; 
        height: 500px; 
        margin: 0 auto; 
    }
    </style>
    
    <div id="map" class="other-map"></div>
    
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=您的高德地图API密钥"></script>
    
    <script type="text/javascript" src="<?php echo get_stylesheet_directory_uri(); ?>/js/footprint.js"></script>
    
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
        var map = new AMap.Map('map', {
            center: [116.397128, 39.916527],
            zoom: 4
        });
    
        if (typeof footprint !== 'undefined' && footprint.length > 0) {
            for (let i = 0; i < footprint.length; i++) {
                const [popupText, lat, lng] = footprint[i];
    
                var marker = new AMap.Marker({
                    position: new AMap.LngLat(lng, lat),
                    map: map
                });
    
                marker.on('click', function() {
                    var infoWindow = new AMap.InfoWindow({
                        content: popupText,
                        offset: new AMap.Pixel(0, -30)
                    });
                    infoWindow.open(map, marker.getPosition());
                });
            }
        } else {
            console.error('footprint array is undefined or empty');
        }
    });
    </script>
    
    <?php get_footer(); ?>

    自行申请高德地图API密钥。注意上述代码中js的路径

    /js/footprint.js"

    结尾

    过程很复杂,我简化了步骤,直接操作会很简单,不过相比较使用Leaflet,任有许多不完美之处,比如点击标记点显示文章图片,Leaflet会自动生成缩略图,而这个显示原图,所以我去掉了图片显示。鼠标滑过标记点,Leaflet会自动显示标记点文章,而这个需要点击标记点,而且点开之后需要手动关闭才能浏览下个标记点。Leaflet则不需要,随便点击空白处就关闭了。相比较,Leaflet更完美,体验感更足。

     

  • 跟风利用FreshRSS实现朋友圈

    前言

    最开始我用的是阿锋的朋友圈插件,这是我第一次见把友链整合到RSS订阅把它展现出来,那会儿很好奇,就使用了阿锋的晨风自定义插件。后面看到了hexo-circle-of-friends,网上找了半天没看到WordPress上面实现的方法。后面才看到了若志的这篇文章,索性就搞了起来。

    实现步骤

    首先要搭建FreshRSS,这个教程很多,我使用的是服务器搭建,纯宝塔操作,简单不复杂。

    1、添加站点,注意:需要确认已经安装了 PHP 扩展 fileinfo(我的默认安装了)。接下来在宝塔面板创建新站点,设置好数据库与 PHP 版本。数据库我选择的是mysql,PHP版本是0。然后,删去网站根目录下默认添加创建的所有文件,确保文件夹全部清空。打开站点根目录,把 FreshRSS 源代码上传到网站根目录,域名访问开始安装。

    2、安装完成后进入设置-账户-API 管理,填写api密码提交。

    3、进入设置-认证,勾选允许 API 访问 (用于手机应用),提交。

    4、添加你的友链feed地址,我试了一下,直接输入友链域名大部分的rss地址可以自动获取,少部分不知道rss地址的可以安装浏览器插件查看或者问博主本人。

    5、不知道是不是我安装的有问题,点击添加的友链管理,会弹出502 Bad Gateway nginx。不过双击还是就进去了,可以进行删除修改等操作,凑合着用吧。

    6、在自己站点根目录下创建一个php文件,用于放FreshRSS api调用函数,例如:rss.php。访问https://你的博客域名/rss.php,显示数据已保存到JSON文件中。

    <?php
    /**
     * 获取最新订阅文章并生成JSON文件
     */
    function getAllSubscribedArticlesAndSaveToJson($user, $password)
    {
        $apiUrl = 'https://你部署FreshRSS的域名/p/api/greader.php';
        $loginUrl = $apiUrl . '/accounts/ClientLogin?Email=' . urlencode($user) . '&Passwd=' . urlencode($password);
        $loginResponse = curlRequest($loginUrl);
        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);
            $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);
                $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) {
                        $desc_length = mb_strlen(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 'UTF-8');
                        if ($desc_length > 20) {
                            $short_desc = mb_substr(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 0, 99, 'UTF-8') . '...';
                        } else {
                            $short_desc = strip_tags(html_entity_decode($article['summary']['content'], 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 = 'https://你部署FreshRSS的域名/p/'.substr($iconUrl, strrpos($iconUrl, '/') + 1);
                            $formattedArticle['icon'] = $filename;
                        }
    
                        $formattedArticles[] = $formattedArticle;
                    }
    
                    saveToJsonFile($formattedArticles);
                    return $formattedArticles;
                } else {
                    echo 'Error retrieving articles.';
                }
            } else {
                echo 'Error retrieving articles.';
            }
        } else {
            echo 'Login failed.';
        }
        return null;
    }
    function curlRequest($url, $authToken = null)
    {
        $ch = curl_init($url);
        if ($authToken) {
            $headers = array(
                'Authorization: GoogleLogin auth=' . $authToken,
            );
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * 将数据保存到JSON文件中
     */
    function saveToJsonFile($data)
    {
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        file_put_contents('output.json', $json);
        echo '数据已保存到JSON文件中';
    }
    
    // 调用函数并提供用户名和密码
    getAllSubscribedArticlesAndSaveToJson('这里是FreshRSS的用户名', '这里是第3步设置的api密码');

    注意:'https://你部署FreshRSS的域名/p/,没证书是http(最好带上证书,不然图标获取不到),还有后面的/p/. 新建页面,在正文里面输入简码:

    7、我是用的是添加页面使用简码将其显示出来,在子主题的funtions.php里添加以下代码:

    // 在 functions.php 中添加 shortcode 函数
    function display_articles_shortcode() {
        // 获取JSON数据
        $jsonData = file_get_contents('./output.json');
        // 将JSON数据解析为PHP数组
        $articles = json_decode($jsonData, true);
        // 对文章按时间排序(最新的排在前面)
        usort($articles, function ($a, $b) {
            return strtotime($b['time']) - strtotime($a['time']);
        });
        // 设置每页显示的文章数量
        $itemsPerPage = 30;
    
        // 生成文章列表
        ob_start(); // 开始缓存输出
        foreach (array_slice($articles, 0, $itemsPerPage) as $article) {
        ?>
            <div class="article">
                <h3>
                    <img src="<?php echo htmlspecialchars($article['icon']); ?>" alt="Icon" class="icon">
                    <a href="<?php echo htmlspecialchars($article['link']); ?>" target="_blank"><?php echo htmlspecialchars($article['title']); ?></a>
                </h3>
                <p>作者:<?php echo htmlspecialchars($article['site_name']); ?></p>
                <p><?php echo htmlspecialchars($article['description']); ?></p>
                <time><?php echo htmlspecialchars($article['time']); ?></time>
            </div>
        <?php
        }
        return ob_get_clean(); // 返回缓存的输出并清除缓存
    }
    
    // 注册简码
    add_shortcode('display_articles', 'display_articles_shortcode');

    8、可以自定义css样式让其精致的显示,这是我的css代码:

    /* Article container */
    .article {
        border: 1px solid #ccc;
        border-radius: 5px;
        padding: 15px;
        margin-bottom: 20px;
    }
    
    /* Article title */
    .article h3 {
        margin-top: 0;
    }
    
    /* Article icon */
    .icon {
        width: 50px;
        height: 50px;
        margin-right: 10px;
        border-radius: 50%;
    }
    
    /* Article metadata */
    .article p, .article time {
        margin: 5px 0;
    }
    
    /* Article time */
    .article time {
        font-style: italic;
    }
    
    /* Hover effect on article */
    .article:hover {
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        transition: box-shadow 0.3s ease;
    }
    /* Article icon */
    .icon {
        width: 1.5em; /* 使用 em 单位可以根据标题字体大小调整图标大小 */
        height: auto; /* 自动调整高度以保持宽高比 */
        margin-right: 10px;
        vertical-align: middle; /* 垂直居中对齐 */
        border-radius: 50%;
    }
    

    9、在宝塔添加一个计划任务,定时访问执行第6步创建的php文件,以更新订阅数据。官网里说的那个自动刷新订阅源的方法,我按照官网设置了每隔30分钟刷新,不知道咋回事儿不管用,每次都要自己刷新后才更新订阅源。

    结语

    自己部署rss订阅源是一件非常有成就感的事儿,过程也是艰辛,尤其是我这种不会代码的,更是辛苦,一步一步地查看错误,幸好有GPT,帮我可以查找问题,解决问题,不至于求人。

  • bokequan.cn怎么样呀

    前言

    距离上篇文章已经有4天时间了,事情往往就有些出乎意料,本来这篇文章是在当天就可以产出的,奈何电脑以及个人的问题延时到了今天上班。

    起因

    上篇文章写完的当天下午,博友阿锋就给我发了邮件告诉我bokequan.cn可以注册,令我十分惊喜,赶忙注册了,生怕迟一秒就被别人注册,上一个域名bokequan.net的抢注到现在还令我心有余悸。本来是可以直接更换的,不料宝塔面板进不去了,不知道是我代理有问题还是其他原因,反正是折腾了一下午没有结果遂放弃了,那天刚好放假需要回家就再没折腾。

    经过

    家里的电脑也差强人意,电脑自动开启代理模式令人很烦,找了好久没找到解决办法,每次使用都要关闭代理,过几分钟代理自动连接,又得关。这样子的后果就是让我对于碰电脑成了一种抗拒。而且我想到宝塔面板进不去应该不是代理的缘故,因为我手机上进去了一次,刷新一下后又进不去了。可能是宝塔端口之类的缘故。

    更换域名啥的需要进入宝塔后台操作,所以一直等到了今天,今日我把vps重启更换密码之后莫名其妙的进去了,好吧,那就赶紧更改吧。

    我使用的是Velvet Blues Update URLs这个插件,虽然是英文插件,但是还是比较直观的,第一步就是分别输入旧域名和新域名的网址,第二部就是勾选数据库中相应的数据表,默认替换所有文章、页面、自定义类型文章、修订版等,想要彻底替换新旧域名的话,建议全部勾选,然后点击【Update URLs NOW】按钮即可。适合小白使用,像我进去数据库一不小心把其他地方动了之后得不偿失。

    在域名解析里我把bkq.net.cn域名解析映射到了bokequan.cn,好像没反应,不知道是不是我的设置有失误之处还是没反应过来。

    结语

    博客圈的全称bokequan.cn是不是比bkq.net.cn更令人可以记住呀!

  • 博客圈的发展历程

     

    前言

    很早之前,我的心里就产生了这种想法,把喜欢的博客收集起来,供自己随时随地的查看他们,这种想法在脑子里想之又想,最开始是看到了blogwe(博客我们),界面非常清新,舒服,很佩服这位大佬,尽管很长一段时间没有更新了。然后就是十年之约,不错的组织,一种约定,不知多少人能够坚持下来。后来又发现了了小志的优秀个人独立博客导航,里面按年份收集了非常优秀的个人博客,非常简单的页面,汇集了优秀的博客,还有各种工具以及建博方面的知识。后面又出现了各种各样的博客聚合平台,比如很精致的个站商店等等等等,就不一一列举了。还有小胡的中文博客圈微信群,相比较其他各种博客聚合平台,中文博客圈微信群具有很好的交流性,在里面也认识了很多大佬,学到了较多的知识。

    经过

    在2021年7月24日,我的这个想法终于可以实现了,尽管自己是个小白,不懂得自己研究。但还是根据自己很长时间的探索发现了一个优秀的导航网站可以供自己收集博客,那就是OneNav导航主题,基于WordPress。关于这个主题在另一个免费开源的同名导航的争论,我也就不说明,也不管,自己用着就行。在这之前我也尝试着用过zblog的轻导航系列收集过博客,因为小白不懂问问题而被其站长那啥,索性转行进入了WordPress。尽管WordPress有些臃肿,但是它比任何程序适合小白,各式各样的主题与插件极好的满足了我的需求。

    域名

    最开始时博客圈用的是子域名dh.duanxiansen.com博客圈-致力于个人独立博客 | 段先森 (duanxiansen.com),后面经过仔细了解在2021年11月25日换成了bokequan.net郑重声明,博客圈换域名了 | 段先森 (duanxiansen.com),这个域名其实很好的诠释了博客圈这三个字,不过仅仅的坚持了一年多,由于工作生活等种种原因域名过期后没续费导致被某体育sq网站抢注(应该是抢续),由于之前备案过而导致我被警察叔叔问候过。没办法还没想好新域名所以迁移到了博客的子域名bkq.duanxiansen.com上,近期才注册了bkq.net.cn,重新起航了。

    博客圈的功能

    博客排行榜:也就是热度排行榜,根据查看次数也就是点击次数决定,分别为今日、昨日、本月以及点击总榜,每种呈现50个博客。

    RSS聚合:简单的聚合展示了博友们的最新文章,有的博友的博客由于rss抓取不到所以展示不出来。

    博友社区:其实就是简单的问答页面,由于没有嵌入主题,所以显得有点儿不搭,等后面更新吧。

    博客详情页:抓取了博主博文的最新5条文章。

    提交收录:填写博客地址后一键获取其他信息,如果没有只能手动填写了,图标可以不上传,后台就获取了。

    最后,如果方便合适,可以把博客圈加在您博客的底部或者其他位置,哈哈

    页脚添加代码

    <a href="https://bokequan.cn/" title="博客圈" target="_blank" > <img src="https://bokequan.cn/bokequan.cn.png" alt="本站已加入博客圈" style="width:auto;height:16px;"> </a>
  • 浅谈中文博客圈

    浅谈中文博客圈

    很早以前,我就萌生了建立中文博客圈的想法。不是心血来潮,而是源自我作为一名独立博客写作者,在互联网的各个角落摸爬滚打之后,对那种去中心化、自由表达的空间的一种执念。过去也动手尝试过几次,但总是半途而废。有时候是时间不够,有时候是现实太杂,但更多的时候,是找不到一个持续的动力。

    昨天,在一个中文博客微信群里,大家又一次聊到了“中文博客圈”这个话题。没想到,这个想法一下子又被点燃了。我发现,真正让人放弃的从来不是能力,也不是资源,而是“是否还愿意出发”。

    说干就干:再次启航

    这次,我没有再犹豫。行动起来很快,甚至可以说是迫不及待。主机选择了群里朋友们推荐的 CloudCone,对我来说是第一次使用这家服务商的 VPS,性价比还不错。用得好的话,后续再续费也不迟。

    域名沿用了以前的:bbs.bokequan.cn。虽然原来的主机因为容量太小早已到期,甚至没有留下什么备份,但我仍然想让它重新活起来。回过头来看,那些曾经“荒废”的项目,也许只是一个更好版本的铺垫。

    初心不改,欢迎加入

    我想再次说一声:欢迎各位博友加入博客圈。虽然现在论坛功能还很简陋,许多地方还在调试和建设中,但博客圈承诺会尽最大努力生存下去,不管访问量如何,不管是否被热议。

    在这个充满短视频和算法内容的时代,博客论坛类平台越来越稀缺。那些仍然愿意记录生活、认真写字的人,也在逐渐被算法边缘化。但我相信,只要有人愿意坚持写作,博客就不会消失

    中文博客圈(bbs.bokequan.cn)正式成立于2023年6月2日,是一个非营利性、完全自愿加入的博客交流平台。它的初衷很简单——让写博客的人有地方可以说话,有机会互相认识。

    论坛的定位就是:交流、连接、互助。无论你是程序员、设计师、自由职业者,还是纯粹记录生活的写作者,只要你还有博客、还有分享的欲望,这里就有你的位置。

    未完成的建设,期待你的建议

    博客圈还在摸索当中,目前的页面还很基础,功能也在逐步完善中。如果你有兴趣参与、或者对论坛功能有好的建议,欢迎随时提出。我们相信,真正好的社区,不是一开始就完美的,而是在使用者的反馈和参与中逐步成型的

    如果你也曾有过“做一个中文博客社区”的念头,或者还在坚持写自己的独立博客,不妨关注一下中文博客圈。即使只是偶尔上线看看,也能让这个小小的圈子多一分温度。

  • 博客圈-致力于个人独立博客

    这个博客,主要是我的生活记录本。没有高深的见解,也不是为了迎合谁,只是习惯在这里写点东西,可能是一句牢骚、一段回忆、一点感悟,又或是一顿饭、一次出行、一个念头。文笔平平,但真实;内容杂乱,却有我自己的节奏。

    这里的每一篇日志,都是我和这个世界小小互动的痕迹。

    除了写自己的生活,我还搭建了一个小小的“博客圈”,希望能聚集一群有同样习惯的朋友——喜欢写博客,喜欢记录生活,哪怕只是偶尔更新,也没关系。
    这个圈子不收录纯技术站点,也不追求什么流量、排名,只欢迎那些用博客表达生活、记录日常的人加入。

    博客圈的最初地址是:https://bkq.duanxiansen.com/
    在 2024 年 3 月 4 日,我们更换了独立域名:https://bokequan.cn

    博客圈(bokequan.cn)成立于 2021 年 7 月 24 日,是一个非营利、开放自愿加入的独立博客收录计划,由我——段先森,独立维护运营。我们按照地区对博客进行简单分类,希望让大家更容易找到“身边的朋友”。
    这里的博客不追热点、不搞营销,只有真实的人,安静地记录自己的生活。

    在博客圈,你会看到有人晒晒阳光下的阳台和猫,也有人聊聊上班的琐事、偶尔的旅行,甚至是和父母的一次对话、一次夜晚的失眠。这里没有KPI,也不讲算法,只有一篇篇来自生活的、带着体温的文字。

    加入我们,请记得:只收录个人独立博客。

    我始终觉得,博客是一种慢下来的方式。

    在这个快节奏、碎片化、短内容泛滥的时代,能坚持用博客写字,是一件值得尊重的事情。

    多年以后,当我们回头翻看这些旧文,或许也会微笑着说一句:“嗯,那时的我,还挺可爱的。”

  • 谈从typecho迁移到WordPress,支持WordPress最新版

    用了一个多月的typecho,感觉typecho的有些功能实在是不尽人意,而且段先森也不是技术高手,懒得开发(工作一天忙的要死),还是决定转移阵地,来到了WordPress这个大家庭,毕竟WordPress不必太在意技术问题,大量的插件以及美观的主题够你享用了

    言归正传,从网上找了好久,从WordPress迁移到typecho的文章很多,但从typecho迁移到WordPress的文章寥寥无几,为什么要迁移呢,如果是新博客的话,我还迁个毛!!!

    首先会遇到一款typecho的插件ByeTyp,它迁移的原理是:将Typecho中的数据导出为WordPress可识别的WXR文件。

    访问ByeTyp项目主页:https://github.com/panxianhai/TypExport 下载最新版的插件。下载后将插件上传并安装到Typecho上。注意上传的时候要为插件的文件夹命名为ByeTyp,否则插件将无法正常运行。

    启用插件后:控制台→数据导出→导出XML文件

    然后在WordPress后台里按照这个顺序操作:工具->导入->WordPress->运行导入器(未安装的话就先安装)->选择文件->上传并导入->选择导入的文章所属的用户,之后提示是否导入媒体,随便点就行

    最后,打开你的新博客,是不是已经迁过来了呢