阅读视图

发现新文章,点击刷新页面。

子比主题文章归档页面美化版

前言

因为自己喜欢倒腾,所以从Corenext换成了子比,但不代表Corenext不好,Corenext主题绝对是做博客的首选。

我换成子比是为了倒腾一些小玩意,今天就给大家带来自己弄的一个美化版的文章归档页面

展示

图片[1]-新锐博客
图片[2]-新锐博客

教程

在子比主题的pages目录下创建一个新的php,名字随便命名,然后将如下代码放入进去

<?php
/**
 * Template name: 新锐-文章归档
 * Description: 文章归档页面,包含统计数据和文章列表
 */

// 获取分类统计信息并缓存
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_monthly_post_data() {
    return get_cached_data('monthly_post_data', function() {
        global $wpdb;
        $query = "
            SELECT DATE_FORMAT(post_date, '%Y-%m') AS month, COUNT(*) AS count
            FROM {$wpdb->posts}
            WHERE post_type = 'post' AND post_status = 'publish'
              AND post_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
            GROUP BY month
            ORDER BY month ASC
        ";
        $results = $wpdb->get_results($query, ARRAY_A);

        $monthly_data = [];
        foreach ($results as $result) {
            $monthly_data[] = [
                'month' => $result['month'],
                'count' => $result['count']
            ];
        }
        return json_encode($monthly_data);
    });
}

// 缓存处理函数
function get_cached_data($transient_key, $callback) {
    if (false === ($data = get_transient($transient_key))) {
        $data = call_user_func($callback);
        set_transient($transient_key, $data, 12 * HOUR_IN_SECONDS);
    }
    return $data;
}

// 统计小工具
function render_archives_widgets($type = 'day') {
    $icons = [
        'day' => ['icon' => 'fa fa-calendar', 'color' => 'c-blue', 'title' => '运营时间'],
        'post' => ['icon' => 'fa fa-file-text', 'color' => 'c-green', 'title' => '文章总数'],
        'comment' => ['icon' => 'fa fa-comments', 'color' => 'c-purple', 'title' => '评论总数'],
        'user' => ['icon' => 'fa fa-users', 'color' => 'c-orange', 'title' => '注册用户']
    ];

    switch ($type) {
        case 'day':
            $first_post = get_posts(['numberposts' => 1, 'order' => 'ASC']);
            $start_time = !empty($first_post) ? strtotime($first_post[0]->post_date) : time();
            $statistic = round((time() - $start_time) / DAY_IN_SECONDS) . ' 天';
            break;
        case 'post':
            $statistic = wp_count_posts()->publish;
            break;
        case 'comment':
            $statistic = get_comment_count()['total_comments'];
            break;
        case 'user':
            $statistic = count_users()['total_users'];
            break;
        default: return;
    }

    echo '<div class="stats-widget">';
    echo '<div class="stats-header">'.$icons[$type]['title'].'</div>';
    echo '<div class="stats-content">';
    echo '<div class="stats-icon"><i class="'.$icons[$type]['icon'].' '.$icons[$type]['color'].'"></i></div>';
    echo '<div class="stats-value">'.$statistic.'</div>';
    echo '</div></div>';
}

// 注册脚本
function grace_archives_scripts() {
  
    wp_enqueue_script('echarts', 'https://cdn.jsdmirror.com/npm/echarts@5.4.0/dist/echarts.min.js', [], null, true);
     wp_enqueue_script('archives-script', get_template_directory_uri().'/js/archives.js', ['echarts', 'jquery'], null, true);
    
    // 将数据传递给 JavaScript
    wp_localize_script('archives-script', 'graceData', [
        'postData' => json_decode(get_category_statistics()),
        'monthlyPostData' => json_decode(get_monthly_post_data()),
        'ajaxUrl' => admin_url('admin-ajax.php')
    ]);
}
add_action('wp_enqueue_scripts', 'grace_archives_scripts');

// AJAX 处理翻页请求
function load_more_posts() {
    $paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
    $posts_per_page = 20;

    $query = new WP_Query([
        'posts_per_page' => $posts_per_page,
        'paged' => $paged,
        'orderby' => 'post_date',
        'order' => 'DESC',
        'post_status' => 'publish'
    ]);

    if ($query->have_posts()) :
        $organized = [];
        while ($query->have_posts()) : $query->the_post();
            $year = get_the_time('Y');
            $month = get_the_time('m');
            $organized[$year][$month][] = $post;
        endwhile;

        ob_start();
        foreach ($organized as $year => $months) : ?>
            <div class="archive-year">
                <h2 class="year-title"><?php echo $year; ?></h2>
                <?php foreach ($months as $month => $posts) : ?>
                    <div class="archive-month">
                        <h3 class="month-title"><?php echo date('n月', mktime(0, 0, 0, $month, 1)); ?></h3>
                        <ul class="post-list">
                            <?php foreach ($posts as $post) : setup_postdata($post); ?>
                                <li>
                                    <time><?php the_time('m-d'); ?></time>
                                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                        <?php the_title(); ?>
                                        <?php if (get_comments_number()) : ?>
                                            <span class="comment-count">(<?php echo get_comments_number(); ?>)</span>
                                        <?php endif; ?>
                                    </a>
                                </li>
                            <?php endforeach; ?>
                        </ul>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php endforeach;

        // 生成新的分页链接
        $pagination = paginate_links([
            'total' => $query->max_num_pages,
            'current' => $paged,
            'prev_next' => true,
            'prev_text' => __('« 上一页'),
            'next_text' => __('下一页 »'),
            'echo' => false
        ]);

        $output = ob_get_clean();
        wp_send_json_success([
            'data' => $output,
            'pagination' => $pagination
        ]);
    else :
        wp_send_json_error('No more posts');
    endif;
    wp_reset_postdata();
    wp_die();
}
add_action('wp_ajax_load_more_posts', 'load_more_posts');
add_action('wp_ajax_nopriv_load_more_posts', 'load_more_posts');

get_header();
?>

<main class="grace-archives">
    <div class="archive-container">
        <div class="archive-main">
            <article class="archive-article">
                <header class="archive-header">
                    <h1><?php the_title(); ?></h1>
                    <!-- 统计小工具 -->
                    <div class="stats-grid">
                        <?php 
                        render_archives_widgets('day');
                        render_archives_widgets('post');
                        render_archives_widgets('comment');
                        render_archives_widgets('user');
                        ?>
                    </div>
                </header>
                
                <!-- 图表区域 -->
                <div class="charts-container">
                    <div class="chart-box" id="postChart"></div>
                    <div class="chart-box" id="monthlyPostChart"></div>
                </div>

                <!-- 文章列表 -->
                <div class="archives-list">
                    <?php
                    // 获取当前页码
                    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
                    $posts_per_page = 20;
                    
                    $query = new WP_Query([
                        'posts_per_page' => $posts_per_page,
                        'paged' => $paged,
                        'orderby' => 'post_date',
                        'order' => 'DESC',
                        'post_status' => 'publish'
                    ]);

                    if ($query->have_posts()) :
                        $organized = [];
                        while ($query->have_posts()) : $query->the_post();
                            $year = get_the_time('Y');
                            $month = get_the_time('m');
                            $organized[$year][$month][] = $post;
                        endwhile;

                        foreach ($organized as $year => $months) : ?>
                            <div class="archive-year">
                                <h2 class="year-title"><?php echo $year; ?></h2>
                                <?php foreach ($months as $month => $posts) : ?>
                                    <div class="archive-month">
                                        <h3 class="month-title"><?php echo date('n月', mktime(0, 0, 0, $month, 1)); ?></h3>
                                        <ul class="post-list">
                                            <?php foreach ($posts as $post) : setup_postdata($post); ?>
                                                <li>
                                                    <time><?php the_time('m-d'); ?></time>
                                                    <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                                        <?php the_title(); ?>
                                                        <?php if (get_comments_number()) : ?>
                                                            <span class="comment-count">(<?php echo get_comments_number(); ?>)</span>
                                                        <?php endif; ?>
                                                    </a>
                                                </li>
                                            <?php endforeach; ?>
                                        </ul>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        <?php endforeach; 
                    else :
                        echo '<p>暂无文章</p>';
                    endif;
                    wp_reset_postdata();
                    ?>
                </div>

                <!-- 传统分页 -->
<div class="archive-pagination">
    <?php
    echo paginate_links([
        'total'     => $query->max_num_pages,
        'current'   => $paged,
        'prev_next' => true,
        'prev_text' => __('« 上一页'),
        'next_text' => __('下一页 »'),
        'type'      => 'plain', // 修改这里
        'mid_size'  => 2 // 控制显示页码数量
    ]);
    ?>
</div>
            </article>
        </div>
    </div>
</main>


<script>
// 仅保留图表初始化代码
jQuery(document).ready(function($) {
    // 初始化 ECharts 图表
    const postChart = echarts.init(document.getElementById('postChart'));
    const monthlyPostChart = echarts.init(document.getElementById('monthlyPostChart'));

    postChart.setOption({
        title: { text: '文章分类分布' },
        tooltip: { trigger: 'item' },
        series: [{
            type: 'pie',
            data: graceData.postData
        }]
    });

    monthlyPostChart.setOption({
        title: { text: '每月发文数量' },
        tooltip: { trigger: 'axis' },
        xAxis: {
            type: 'category',
            data: graceData.monthlyPostData.map(item => item.month)
        },
        yAxis: { type: 'value' },
        series: [{
            type: 'line',
            data: graceData.monthlyPostData.map(item => item.count)
        }]
    });
});
</script>

<style>
.grace-archives {
    padding: 2rem 20px;
    background: #f8f9fa;
    min-height: 100vh;
}
/* 分页容器 */
.archive-pagination {
    margin-top: 3rem;
    text-align: center;
}

/* 分页链接基础样式 */
.archive-pagination a, 
.archive-pagination span {
    display: inline-block;
    padding: 8px 16px;
    margin: 0 4px;
    border: 1px solid #e0e0e0;
    border-radius: 4px;
    color: #3498db;
    text-decoration: none;
    transition: all 0.3s;
}

/* 当前页样式 */
.archive-pagination span.current {
    background: #3498db;
    color: white;
    border-color: #3498db;
}

/* 悬停效果 */
.archive-pagination a:hover {
    background: #f8f9fa;
    border-color: #3498db;
}

/* 移动端适配 */
@media (max-width: 480px) {
    .archive-pagination a, 
    .archive-pagination span {
        padding: 6px 12px;
        margin: 2px;
        font-size: 14px;
    }
}
.archive-container {
    max-width: 1400px;
    margin: 0 auto;
}

.archive-main {
    background: #fff;
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}

.archive-header {
    margin-bottom: 2rem;
    border-bottom: 2px solid #f0f0f0;
    padding-bottom: 1.5rem;
}

.archive-header h1 {
    font-size: 2.2rem;
    color: #2c3e50;
    margin: 0 0 1.5rem;
}

/* 统计小工具 */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.5rem;
    margin: 2rem 0;
}

.stats-widget {
    background: #ffffff;
    border: 1px solid #eaeaea;
    padding: 1.5rem;
    border-radius: 10px;
    transition: transform 0.3s ease;
}

.stats-widget:hover {
    transform: translateY(-3px);
    box-shadow: 0 6px 16px rgba(0,0,0,0.1);
}

.stats-header {
    color: #7f8c8d;
    font-size: 0.95rem;
    margin-bottom: 0.8rem;
    font-weight: 500;
}

.stats-content {
    display: flex;
    align-items: center;
    gap: 1.2rem;
}

.stats-icon i {
    font-size: 2rem;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}

.stats-value {
    font-size: 1.8rem;
    font-weight: 600;
    color: #2c3e50;
}

/* 颜色定义 */
.c-blue { background: #e3f2fd; color: #2196f3; }
.c-green { background: #e8f5e9; color: #4caf50; }
.c-purple { background: #f3e5f5; color: #9c27b0; }
.c-orange { background: #fff3e0; color: #ff9800; }

/* 图表容器 */
.charts-container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    margin: 3rem 0;
}

.chart-box {
    height: 400px;
    background: #fff;
    border: 1px solid #eee;
    border-radius: 10px;
    padding: 1rem;
}

/* 文章列表 */
.archives-list {
    margin-top: 2rem;
}

.archive-year {
    margin-bottom: 3rem;
    background: #fafafa;
    border-radius: 8px;
    padding: 1.5rem;
}

.year-title {
    font-size: 1.8rem;
    color: #2c3e50;
    margin: 0 0 1.5rem;
    padding-bottom: 0.8rem;
    border-bottom: 2px solid #eee;
}

.archive-month {
    margin-bottom: 2rem;
    background: #fff;
    border-radius: 6px;
    padding: 1rem;
    box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}

.month-title {
    font-size: 1.4rem;
    color: #34495e;
    margin: 0 0 1rem;
    padding-left: 0.5rem;
}

.post-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.post-list li {
    padding: 1rem 1.2rem;
    border-bottom: 1px solid #f5f5f5;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    transition: background 0.3s;
}

.post-list li:hover {
    background: #f8f9fa;
}

.post-list time {
    color: #7f8c8d;
    min-width: 70px;
    font-family: monospace;
    font-size: 0.95rem;
}

.post-list a {
    color: #2c3e50;
    transition: color 0.3s;
    flex-grow: 1;
    text-decoration: none;
    font-weight: 500;
}

.post-list a:hover {
    color: #3498db;
}

.comment-count {
    color: #95a5a6;
    font-size: 0.85em;
    margin-left: 0.8rem;
    font-weight: normal;
}

/* 分页样式 */
.archive-pagination {
    margin-top: 3rem;
    text-align: center;
    padding: 1.5rem 0;
}

.archive-pagination .page-numbers {
    display: inline-block;
    padding: 8px 16px;
    margin: 0 5px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    color: #3498db;
    text-decoration: none;
    transition: all 0.3s;
}

.archive-pagination .page-numbers.current {
    background: #3498db;
    color: #fff;
    border-color: #3498db;
}

.archive-pagination .page-numbers:hover:not(.current) {
    background: #f8f9fa;
    border-color: #3498db;
}

/* 加载提示 */
.loading {
    text-align: center;
    padding: 1.5rem;
    color: #7f8c8d;
    font-size: 0.95rem;
}

/* 响应式设计 */
@media (max-width: 1200px) {
    .charts-container {
        grid-template-columns: 1fr;
    }
    .chart-box {
        height: 350px;
    }
}

@media (max-width: 768px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 1rem;
    }
    
    .stats-value {
        font-size: 1.6rem;
    }
    
    .archive-main {
        padding: 1.5rem;
    }
    
    .year-title {
        font-size: 1.6rem;
    }
}

@media (max-width: 480px) {
    .stats-grid {
        grid-template-columns: 1fr;
    }
    
    .stats-content {
        gap: 1rem;
    }
    
    .archive-pagination .page-numbers {
        padding: 6px 12px;
        margin: 3px;
    }
    
    .post-list li {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
        padding: 1rem;
    }
    
}
</style>
<?php get_footer(); ?>

再到子比主题根目录里的JS文件夹里创建一个archives.js的文件,然后将如下代码放进去

// archives.js 完整代码

document.addEventListener('DOMContentLoaded', function() {
    
     const chartContainers = [
        'postChart', 
        'monthlyPostChart'
    ];

    chartContainers.forEach(id => {
        const el = document.getElementById(id);
        if (!el) {
            console.warn(`图表容器 #${id} 未找到`);
            return;
        }
        
        try {
            // 初始化图表代码...
        } catch (error) {
            console.error(`初始化图表 ${id} 失败:`, error);
        }
    });
    // 获取图表容器
    const postChartEl = document.getElementById('postChart');
    const monthlyChartEl = document.getElementById('monthlyPostChart');
    
    // 检查元素是否存在
    if (!postChartEl || !monthlyChartEl) {
        console.warn('图表容器未找到,请检查元素ID是否正确');
        return;
    }

    // 初始化图表实例
    const postChart = echarts.init(postChartEl);
    const monthlyPostChart = echarts.init(monthlyChartEl);

    // 配置分类分布饼图
    postChart.setOption({
        title: { text: '文章分类分布', left: 'center' },
        tooltip: { trigger: 'item' },
        series: [{
            type: 'pie',
            radius: '55%',
            data: graceData.postData,
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }]
    });

    // 配置月度趋势折线图
    monthlyPostChart.setOption({
        title: { text: '月度发文趋势', left: 'center' },
        tooltip: { trigger: 'axis' },
        xAxis: {
            type: 'category',
            data: graceData.monthlyPostData.map(item => item.month),
            axisLabel: { rotate: 45 }
        },
        yAxis: { type: 'value' },
        series: [{
            type: 'line',
            smooth: true,
            data: graceData.monthlyPostData.map(item => item.count),
            areaStyle: { color: 'rgba(52, 152, 219, 0.2)' }
        }],
        grid: { containLabel: true }
    });

    // 窗口大小变化时自适应
    window.addEventListener('resize', function() {
        postChart.resize();
        monthlyPostChart.resize();
    });
});

最后再到页面中选择新锐-文章归档模版即可

宝塔网站加速插件 - 让WordPress加载更快速

前言

WordPress是一个动态博客框架,所以加载的时候就会很慢,就需要类似wp-super-cache这类插件让网站静态化

我发现wp-super-cache加上宝塔的网站加速插件能让加载变得更加快速

教程

1.宝塔面板的软件商店下载堡塔网站加速插件

图片[1]-新锐博客

2.打开网站加速插件,并且启用想要加速网站的开关

图片[2]-新锐博客

3.专属规则可以选择WordPress

4.在不缓存url地址中添加/wp-admin

图片[3]-新锐博客

5.至此配置完成了,享受网站加速的快感吧

WordPress解决feed文件首行换行

前言

访问各个大佬博客的时候,有个类似开往的项目,名为blogsclub,站点地址:https://www.blogsclub.org/

过程

闲来无事就加入了其中,它有个功能是通过WordPress的feed抓取文章,但是我设置了feed却提示没有抓取成功
随后就收到了他们官方发出的邮件,提示feed文件首行出现了换行,众所周知,feed是由WordPress自行生成的,不像sitemap可以通过插件来生成
所以遇到此类麻烦就很难受,于是只能由最新大热的deepseek来解决,AI告诉我,需要检查各种php文件来确保之前并没有出现换行或空格
但是那样就很麻烦,所以我就让deepseek帮我把feed顶部的空格直接删掉就行了。
于是就有了以下教程

教程

将如下代码放到主题的function.php文件中

function remove_xml_declaration_whitespace() {
    // 检查当前页面是否是 feed 页面
    if (is_feed()) {
        // 清空所有现有的输出缓冲区
        while (ob_get_level() > 0) {
            ob_end_clean();
        }

        // 启动一个新的输出缓冲区,并指定回调函数
        ob_start(function($buffer) {
            // 使用正则表达式删除 XML 声明前的所有空格和换行符
            return preg_replace('/^s*(<?xml)/', '$1', $buffer);
        });
    }
}

// 将函数挂载到 WordPress 的 'wp' 动作上,优先级为 1
add_action('wp', 'remove_xml_declaration_whitespace', 1);

WordPress解决用户名枚举漏洞禁用REST API

前言

今天群里有人说会通过某个地址泄露用户名导致有被爆破的风险,并且给出了解决方案

教程

首先检查一下自己的网站有没有这个漏洞,访问如下网站即可

https://博客域名.com/wp-json/wp/v2/users/

如果有就到主题的function.php文件中添加如下代码

add_filter('rest_authentication_errors', function ($access) { return new wp_error('rest_cannot_access', 'REST API不再提供访问', ['status' => 403]); });

此代码禁用了REST API

零成本使用cloudflare和vercel部署AI文章摘要

前言

搭建网站的各位朋友应该都听说过AI摘要,而其中最出名的就是Tianli,但是呢,五万就需要10米,对我来说还是有点多,穷人一个。

所以就想着研究一下有没有免费的AI摘要项目,今天逛博客的时候就遇到了一个

博客地址

Floatsheep:https://blog.hesiy.cn/posts/qwen-summary

项目地址

Github:https://github.com/FloatSheep/Qwen-Post-Summary/

教程

1.首先将项目地址fork到自己的github中

2.登录并且找到cloudflare的workers,选择LLM APP模版创建,一定要选择此模版

3.编辑代码,将workers.js的代码放到里面并且部署

4.记录好cloudflare提供的域名,然后到vercel中部署

5.部署好以后,找到项目的storage,然后新建一个数据库

6.有kv的选择kv没有kv的数据库选择Upstash for Redis

7.重新部署项目

8.然后到 FloatBlog / cfai.html 或者 client 找到相应的js和css代码部署到网站中即可

nginx反向代理github

前言

因为众所周知的缘故,github时常访问不了,于是就想着反代一下,刚好有台华为云的香港服务器,于是火毅盾的负责人就给了我以下代码

此反代除了登录其他基本没啥问题

教程

1.打开宝塔面板,找到网站的反向代理,设置代理地址为https://github.com,发送域名为$host,然后确定之后可以看到有个配置文件,将如下代码放进去

location ^~ / {
    # 将请求代理到 GitHub
    proxy_pass https://github.com;

    # 设置转发到后端服务器的请求头
    proxy_set_header Host github.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;

    # 清空 Accept-Encoding 头,防止后端返回压缩内容
    proxy_set_header Accept-Encoding "";

    # 替换响应内容中的字符串
    sub_filter "github.githubassets.com" "assets-github.xrbk.cn";
    sub_filter "github.com" "github.xrbk.cn";
    sub_filter "api.github.com" "api-github.xrbk.cn";
    sub_filter 'raw.githubusercontent.com' 'raw.github.xrbk.cn';
    sub_filter_once off;
    sub_filter_types *;

    # 处理 302 重定向中的地址替换
    proxy_redirect ~^https://raw.githubusercontent.com(.*)$ https://raw.github.xrbk.cn$1;

    # 隐藏后端服务器返回的 Content-Security-Policy 头
    proxy_hide_header Content-Security-Policy;

    # 添加自定义的 Content-Security-Policy 头
    add_header Content-Security-Policy "default-src 'self'; img-src *; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";

    # 静态文件缓存设置
    set $static_fileHbPPNEua 0;
    if ($uri ~* ".(gif|png|jpg|css|js|woff|woff2)$") {
        set $static_fileHbPPNEua 1;
        expires 1m;
    }
    if ($static_fileHbPPNEua = 0) {
        add_header Cache-Control no-cache;
    }
}

2.其中为xrbk.cn的后缀都需要更改为你的域名

3.在宝塔的网站里比如github.xrbk.cn中再添加其他例如api-github.xrbk.cn的域名

4.去服务商那解析这几个子域名即可

WordPress添加回复评论邮件通知

前言

之前就想要弄这个功能了,但是主题不支持,今天果核更新了主题终于支持了

教程

将如下代码放到子主题的function.php 中即可

/**
 * 新评论回复邮件通知函数(带按钮,美化界面)
 */
function comment_mail_notify($comment_id) {
    // 获取评论对象
    $comment = get_comment($comment_id);
    if (!$comment || $comment->comment_approved === 'spam') {
        return; // 如果评论不存在或标记为垃圾评论,直接返回
    }

    // 获取父评论 ID
    $parent_id = $comment->comment_parent ? $comment->comment_parent : '';
    if (empty($parent_id)) {
        return; // 如果没有父评论,直接返回
    }

    // 获取父评论对象
    $parent_comment = get_comment($parent_id);
    if (!$parent_comment || empty($parent_comment->comment_author_email)) {
        return; // 如果父评论不存在或邮箱为空,直接返回
    }

    // 获取收件人邮箱
    $to = trim($parent_comment->comment_author_email);

    // 构造邮件内容
    $wp_email = 'no-reply@' . preg_replace('#^www.#', '', strtolower($_SERVER['SERVER_NAME']));
    $subject  = '您在 [' . get_option("blogname") . '] 的留言有了回复';
    $comment_link = get_comment_link($comment_id);
    $message  = '
    <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px; background-color: #f9f9f9;">
        <h2 style="color: #333; font-size: 24px; margin-bottom: 20px;">' . trim($parent_comment->comment_author) . ', 您好!</h2>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            您曾在文章《' . get_the_title($comment->comment_post_ID) . '》中留言:
        </p>
        <blockquote style="margin: 20px 0; padding: 10px 20px; background-color: #fff; border-left: 4px solid #0073aa; color: #666; font-style: italic;">
            ' . trim($parent_comment->comment_content) . '
        </blockquote>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            ' . trim($comment->comment_author) . ' 给您的回复:
        </p>
        <blockquote style="margin: 20px 0; padding: 10px 20px; background-color: #fff; border-left: 4px solid #0073aa; color: #666; font-style: italic;">
            ' . trim($comment->comment_content) . '
        </blockquote>
        <p style="color: #555; font-size: 16px; line-height: 1.6; text-align: center;">
            点击下方按钮查看完整回复内容:
        </p>
        <div style="text-align: center; margin: 20px 0;">
            <a href="' . $comment_link . '" style="display: inline-block; padding: 12px 24px; font-size: 16px; color: #fff; background-color: #0073aa; border-radius: 4px; text-decoration: none;">
                查看回复
            </a>
        </div>
        <p style="color: #555; font-size: 16px; line-height: 1.6;">
            感谢您对 ' . get_option('blogname') . ' 的支持!
        </p>
        <p style="color: #999; font-size: 14px; margin-top: 20px; text-align: center;">
            此邮件由系统自动发送,请勿直接回复。
        </p>
    </div>';

    // 设置邮件头
    $headers = [
        'From: "' . get_option('blogname') . '" <' . $wp_email . '>',
        'Content-Type: text/html; charset=' . get_option('blog_charset'),
    ];

    // 发送邮件
    wp_mail($to, $subject, $message, $headers);
}

// 挂载钩子
add_action('comment_post', 'comment_mail_notify', 5, 1);
add_action('wp_insert_comment', 'comment_mail_notify', 5, 1);

PixPro-支持三种存储的图床程序

前言

今天给大家带来一个小巧简洁的图床程序

开源地址

github:https://github.com/JLinMr/PixPro/

简介

一款专为个人需求设计的高效图床解决方案,集成了强大的图片压缩功能与优雅的前台后台管理界面。

项目结构精简高效,提供自定义图片压缩率与尺寸设置,有效降低存储与带宽成本。

支持上传JPEG、PNG、GIF格式图片并转换为WEBP格式,支持上传SVG、WEBP图片。

支持本地储存,阿里云OSS储存,S3存储。可通过把储存桶挂载到本地的方式解锁更多储存方式。

简洁美观的前端,支持点击、拖拽、粘贴、URL、批量上传。

瀑布流管理后台,便捷查看图片信息,支持图片灯箱、AJAX无加载刷新。

支持自定义压缩率,默认60。支持设置每日上传限制,单次上传限制,文件大小限制

演示站点

 

前端:https://dev.ruom.top/

后台:https://dev.ruom.top/admin/

安装教程

 

首先下载源码ZIP,将文件上传到网站根目录,访问网址 ,填写相关信息,即可完成安装。

运行环境

 

推荐PHP 8.1 + MySQL >= 5.7

本程序依赖PHP的 Fileinfo 、 Imagick 、 exif拓展,需要自行安装。依赖 pcntl 扩展(宝塔PHP默认已安装)

要求 pcntl_signal 和 pcntl_alarm 函数可用(需主动解除禁用)

WordPress底部添加页面生成时间和数据库查询次数

前言

今天有个群友要在网站底部添加页面生成时间和数据库查询次数,虽然wpopt插件可以实现这个功能,但是仅能管理员查看

效果图

图片[1]-新锐博客

教程

1.首先在function.php 文件中添加如下代码,有子主题可以添加到子主题中

function display_query_count_with_timer() {
    $query_count = get_num_queries();
    $query_time = timer_stop(0, 3);
    $output = "<p>本次数据库查询" . $query_count . "次,页面生成花费".$query_time."秒</p>";
    return $output;
}
add_shortcode('query_timer', 'display_query_count_with_timer');

2.如果想添加在底部可以使用WordPress的小工具中的文本,只需要输入[query_timer] 即可。

华为云白嫖13个月Flexus服务器

前言

现在许多厂家都有免费送券的活动,今天就介绍一个华为云的送卷活动

教程

活动地址

华为云:https://developer.huaweicloud.com/space/program/list

1.打开活动地址然后登录账号

2.然后在沃土云创中申请计划

图片[1]-新锐博客

3.就可以在激励管理中领取卷了

图片[2]-新锐博客

4.华为云上方搜索Flexus L服务器然后选购2H1G的香港服务器

5.千万不要选择一年而是要选择9个月,然后再续费就可以白嫖十三个月的服务器了,当然多花五块钱是可以多白嫖一个月的。

acmex可视化申请SSL证书

前言

前一篇文章教大家如何自签证书,但是有人会想自签证书得不到浏览器的认可啊,会不会有些cdn回源不支持自签证书啊,所以就用acmex申请一个SSL证书就好了。

开源地址

Github:https://github.com/sometiny/acmex

教程

1.首先下载工具包:https://github.com/sometiny/acmex/releases

2.系统不能是centos7.9,至少是ubuntu22.04这种,亲测

3.上传工具包到网站根目录,然后解压找到linux-x64里面的acmex脚本

4.终端执行如下代码

./acmex setup --listen-at "0.0.0.0:1084"

5.会让你填写yes/no,填写yes即可

6.继续执行如下两条命令(都需要执行)

./acmex --runas console
./acmex --install-as acmex

第一个是启动脚本,第二是将脚本变成名为acmex的系统任务

7.访问外网ip+1084端口就可以访问页面了。

结语

这样我们就可以通过这个页面申请免费的SSL证书了,可视化的,避免不懂代码搞错了。

WordPress侧边栏添加欢迎语

前言

今天逛博客看到一个好玩的东西,分享给大家

参考

原地址:https://blog.shiguang666.eu.org/2024/10/25/479d38b5fc12/

教程

1.首先去青桔API申请key,目前我们使用到的API是完全免费且无次数限制的。

2.访问api接口:https://api.76.al/api/ip/query?key=your_key

3.将如下代码添加到WordPress小工具中的自定义html内

<div id="announcement-widget">
    <div class="card-widget card-ip-info">
        <div class="announcement_content">
            <div id="welcome-info" style="display: none;">
                <div class="loading-spinner"></div>
            </div>
        </div>
    </div>
</div>

<style>
    #welcome-info {
        display: flex;
        justify-content: center;
        align-items: center;
        height: auto;
    }
    .loading-spinner {
        width: 50px;
        height: 50px;
        border: 3px solid rgba(0, 0, 0, 0.1);
        border-radius: 50%;
        border-top: 3px solid #3498db;
        animation: spin 1s linear infinite;
    }
    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
</style>

<script>
    const createAnnouncementComponent = () => {
        const ipInfoElement = document.createElement('div');
        ipInfoElement.className = "card-widget card-ip-info";
        ipInfoElement.innerHTML = `
            <div class="announcement_content">
                <div id="welcome-info">
                    <div class="loading-spinner"></div>
                </div>
            </div>
        `;
        return ipInfoElement;
    };

    const fetchIpInfo = () => {
        fetch('https://api.76.al/api/ip/query?key=your_key')
            .then(response => response.ok ? response.json() : Promise.reject('Network response was not ok'))
            .then(data => showWelcome(data))
            .catch(() => showErrorMessage());
    };

    const getDistance = (e1, n1, e2, n2) => {
        const R = 6371; // Earth radius
        const toRadians = (degree) => degree * (Math.PI / 180);
        const a = Math.sin(toRadians(n1)) * Math.sin(toRadians(n2)) +
                  Math.cos(toRadians(n1)) * Math.cos(toRadians(n2)) *
                  Math.cos(toRadians(e1 - e2));
        return Math.round(R * Math.acos(a));
    };

    const showWelcome = (ipLocationData) => {
        if (!ipLocationData || !ipLocationData.data) {
            return showErrorMessage();
        }

        // 修改为你自己的经纬度 
            const myLng = 121.38206; //经度
            const myLat = 31.11325; //维度
        const { lng, lat, country, prov, city, district } = ipLocationData.data; // 获取区的信息
        const dist = getDistance(myLng, myLat, lng, lat);
        const pos = country === "中国" ? `${prov} ${city} ${district}` : `${city}, ${district}`; // 包含区的信息

        const welcomeInfoElement = document.getElementById("welcome-info");
        welcomeInfoElement.style.display = 'block';
        welcomeInfoElement.innerHTML = `
            💖 欢迎来自 <b><span style="color:#3390ff;">${pos}</span></b> 的朋友<br>
            📏 您距博主约 <b><span style="color: #3390ff;">${dist}</span></b> 公里<br>
        `;
    };

    const showErrorMessage = () => {
        const welcomeInfoElement = document.getElementById("welcome-info");
        welcomeInfoElement.style.display = 'block';
        welcomeInfoElement.innerHTML = `<p>获取IP信息失败,请检查网络.</p>`;
    };

    const initialize = () => {
        document.body.appendChild(createAnnouncementComponent());
        fetchIpInfo();
    };

    window.onload = initialize;
</script>

4.将其中的your_key改为你自己申请的key

5.访问api接口,将其中的lat和lng替换代码中的经纬度

// 修改为你自己的经纬度  
const myLng = 121.38206; //经度
const myLat = 31.11325; //维度

6.访问主页就可以看到了

腾讯云国际推出 EdgeOne Pages,免费静态网站托管服务

简介

腾讯云国际站推出了一项令人振奋的新服务——EdgeOne Pages。这项服务与 Cloudflare Pages 类似,专为静态网页托管而设计。腾讯给出的承诺是“提供近乎无限制的免费版本,该版本将始终可用”,目前来讲是完全免费的,不用验证信用卡,一个邮箱就能直接注册使用,同时免费提供 SSL 证书。

官网

https://edgeone.ai/products/pages

功能特点

1,海外CDN节点,无需域名备案,目前国内可流畅访问

2,支持React、Vue、Next.js、Hexo 等构建的网站

3,与 GitHub 集成实现自动化构建部署

4,仅需一个邮箱,无需绑银行卡,手机号等等

5,基于EdgeOne 的 全球CDN(无国内节点)加速和防护

免费限制

目前官宣完全免费!我们提供几乎无限的免费版本,该版本将始终可用,允许无限制地使用我们产品的基本功能。我们将继续增强我们的高级功能,同时确保我们服务的稳定性。随着我们走向商业化,免费版本可能会有一定的限制,例如每日构建限制,我们会及时通知您。

容量限制:每个账号所有项目总大小不能超过5G,否则无法完成构建。

目前仅支持绑定Github账号,以后可能会开发Gitlab等平台的绑定。

注册账号

1,访问 https://edgeone.ai/register,填写邮箱密码接收验证码完成注册!更简单的方式直接Google授权登录!

2,注册成功后,页面重定向到腾讯云国际站,14天试用不用领取没啥用。

3,如果界面不是中文的,可在右上角切换语言到中文简体。

开通Pages

访问 https://console.tencentcloud.com/edgeone/pages 或者左侧菜单点击【Pages】点击立即开通就哦了~

绑定Github

点击【绑定Github】,登录自己的Github账号,给所有的授权即可!

部署项目

选择Github仓库,部署的时候会自动编译。

结语

尝试了部署一下,可能因为是新产品的缘故,所以功能较为简陋,而且官方给出的预览地址只有三个小时,需要你绑定自己的域名。不过免费的还要什么自行车

利用uptimerobot检测站点状态并且部署监控页面

前言

之前介绍过如何使用哪吒监控监控自己的服务器和站点,但那是需要服务器的。

今天教大家如何不用服务器监控自己的站点。

教程

1.首先打开uptimerobot官网,点击右上角的Register fo FREE注册一个账号

2.找到页面中的Add New monitor添加自己的网站

3.输入网站,可以选择邮件通知或其他通知方式,当你网站访问不了的时候它就会通知你

4.添加完网站就去首页的Integrations & API中找到API

5.新建一个Read-only API key,这样别人就不能通过你的API捣乱了

6.访问https://github.com/Qikaile/uptime-status项目

7.Fork到自己的仓库然后更改config.js文件里的内容

8.打开Vercel,然后添加刚刚fork的项目等待部署完成

9.到项目的setting中找到domain,然后填写自己准备好的域名即可

记一次可能因宝塔版本导致重装系统的遭遇

前言

因为习惯了宝塔的操作习惯,所以一直以来建站使用的都是宝塔。

碎语

之前安装的是宝塔的9.2.0的版本,然后日常使用中也并没有发现什么问题。

但是有天早上有人告诉我,我网站打不开了,于是我就开电脑查看,发现CPU占用一直是百分之百。

当然,这种查看是在阿里云的云监控中进行的,因为那时候宝塔连接不上去,连SSH也无法连接服务器。

幸亏我有瞎倒腾的习惯,所以在阿里云的云监控中开启了主机监控。

我还发现了不仅CPU占用达到了百分之百,硬盘的占用也是高达100M/s。

这么高的读写让我意识到了事情的不对劲,于是我先重启服务器然后连接宝塔之后在监控中查看了日志。

在cpu和硬盘达到百分百的时候,一个名为php-fpm的程序占用非常之大,但因为我是小白,所以不太懂这个是干嘛的。

但是重启服务器后就没事了,所以也就没管。但是几天后又出现了相同的情况,于是我就百度查了一下。

并且在宝塔的论坛中找了一下,发现相关的问题宝塔的工作人员要么没回复,要么就说网站可能被CC之类的了。

我就怀疑是不是我设置了啥导致的这个问题,于是我就重装了系统。但是过了一天这个问题又出现了。

最后我就怀疑是宝塔版本的bug,因为宝塔没有指定版本安装的脚本,于是我就找到了宝塔的9.0.0长期稳定版本安装了一下。

到如今已经过去四天了,问题没有出现。所以我觉得可能是宝塔9.2.0的bug。

现在就继续使用9.0.0版本然后等宝塔更新后看看更新日志会不会有相关的bug修复。

无需服务器利用vercel搭建typecho博客

前言

众所周知,vercel可以搭建静态内容,但是不知道的是也可以搭建typecho博客吧。

教程

准备工作

Github账号,Vercel账号,域名

开始

1.首先访问https://github.com/zycwer/vercel-typecho/并且fork到自己的仓库(最好是下载然后上传到自己仓库)

2.为了防止数据库的泄露,最好将仓库变成私有

3.上传主题文件到usr/theme文件夹下,上传插件到usr/plugins文件夹下

4.使用github登录vercel,点击页面右上角的ADD NEW中的Project

5.找到刚刚fork的项目或者上传的项目点击import并且点击deploy等待部署完成

6.找到项目中的storage,再点击Connect Database,选择其中的Postgres,剩下的直接点右下角的确定就行了,

7.找到项目中的settings,再点击Domains,输入框中输入自己的域名再点击ADD

8.到域名服务商处添加cname解析,记录为cname.vercel-dns.com

9.访问域名,会跳转到typecho安装,数据库选择Po驱动postgres数据库

10.数据库的地址是刚刚创建的postgres数据库中的@后面以及:5432前面的内容

11.数据库用户名是default,数据库密码是default:后面到@前面的内容,数据库名是verceldb

12.它会提示你到在github仓库中创建一个名为config.inc.php的文件,然后将代码填写到其中。

13.等待vercel重新部署完成,期间不要动任何东西,然后点击我已创建,开始安装。

14.之后就是填写管理员账号和密码就可以了。至此typecho就创建成功了。

问题

本项目的最大问题就是有些主题和插件会更改文件内容,不仅仅是更改数据库的内容,比如handsome主题插件,所以很多主题是用不了的,这就要我们一个个试。

 

python项目关闭终端照样运行的方法

前言

因为想使用一个python项目,所以经历了以下事件并且成功部署好了项目

过程

首先项目就两件事一个是安装环境,另一个就是启动python脚本。

但是呢当我用pip install -r requirements.txt 安装环境的时候,提示pip不存在,突然想到之前遇到过这种情况是版本不对,于是将pip改为pip3就行了。

安装好后就是需要启动python脚本了,于是我就用finalshell连接了服务器,用CD到目录,然后同样的将python改为python3执行了python脚本。

虽然脚本运行起来了,但是我发现只要我关闭了终端,任务好像就停止了。

于是我就百度如何关闭终端不停止任务,最后发现了一个方法。

使用nohup python3 your_script.py & 这个命令就好了。

这样哪怕关闭终端也可以运行了。

使用CDN给Vercel部署的项目加速

前言

因为最近搭建了不少项目,都是基于vercel的,但是因为众所周知的原因速度真的是一言难尽。

所以就想用cdn给vercel加速。

教程

因为本人使用的是免费CDN套餐,所以只能添加三个域名,所以本次教程教大家如何使用泛域名来给不同项目加速。

1.首先在CDN添加泛域名,比如*.xxx.com

2.vercel部署的项目填写的域名为比如nav.xxx.com

3.域名控制台填写就nav.xxx.com,cname的值为CDN提供的cname的值

4.CDN控制台一般都有子域名或者别名设置,将nav.xxx.com添加进去

5.关闭CDN的缓存功能,一定要关闭否则会出现串流的情况。

6.访问网站即可

结语

经过CDN加速,访问速度明显比使用vercel原始服务快多了。

记一次数据库查询操作

前言

前两天有群友找到我想让我给他把一个美化插件改一下,插件本来只显示注册用户,浏览量,运行天数等信息。

他想给插件添加一个vip用户数量的信息,所以让我看看能不能搞。

过程

首先我想到的是用数据库来查询,但是需要一个关键词。

我在WordPress后台查看的时候发现虽然会员被区分为黄金会员和钻石会员,但是它们共同的点是都是永久的。

于是我打算从永久这一点来入手,而子比赋予永久会员的值为Permanent ,我就去数据库查找这个词。

wp_usermeta这个数据表中有一个vip_exp_date 的参数的值就是Permanent 。

我就用AI帮我写了一个php代码,查询到Permanent 的数量一共为73个,而WordPress后台显示的黄金会员和钻石会员的总数为70个。

经过查询发现有三个普通会员也被赋予了永久会员这一身份,所以得出结论,无论是普通会员还是黄金会员亦或者钻石会员都可以被赋予永久会员这一身份。

看来只能找其他的值来区别这一点了,最后让我发现vip_level 这一参数的值要么没有要么就是1或2,于是我就认为1代表黄金会员2则代表钻石会员。

想做就做,我就用AI帮我写了一段PHP代码,贴在下面了。

<?php
global $wpdb;
// 查询用户数量
$vipusers = $wpdb->get_var(
    $wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->usermeta} WHERE meta_key = %s AND meta_value IN (%d, %d)",
        'vip_level', 1, 2
    )
);

可以看到是在wp_usermeta这个表中查询了关于vip_level为1或2的数量,最后显示的结果是70。

结语

搭建网站的时候不可避免的需要用到数据库,所以我们得学习好怎么操作数据库才行。

免费利用cloudflare的ZeroTrust进行内网穿透

前言

因为有些web项目需要在本地运行然后进行测试,所以就需要用到内网穿透,但是大多数的内网穿透服务都需要付费,于是就想到了cloudflare。

教程

1.首先注册并登录cloudflare

2.托管一个域名到cloudflare,这里就不细讲了不懂的自行百度

3.点击zero trust

4.然后选择套餐为免费的,这时候提示需要绑定信用卡。

5.直接返回到主界面就可以跳过绑定这一步骤

6.选择Networks中的tunnels

7.点击Add a tunnel

8.选择cloudflare并且点击next

9.在输入框中填写名称,随便填写即可并且点击save tunnel

10.选择系统并且安装提示安装cloudflare,最后点击Next

11.在Subdomain填写子域名,Domain选择托管的域名,path选择目录,Type选择方式,本次为http,URL为localhost:端口

12.最后点击save tunnel,这样就算部署成功了。

13.比如https://127.0.0.1:5678/1.txt就可以更改为https://xx.xxxx.com/1.txt

结语

cloudflare作为最大的免费服务提供商,内网穿透速度也非常快,再说了免费的东西要什么自行车。

利用CloudFlare和Vercel助你零成本搭建网站

前言

最近浏览网站发现很多网站虽然没有备案,没有使用国内的服务器,但是速度不慢。

出于好奇于是我就使用了itdog将这些网站测了下速,发现不少网站都托管于cloudflare。

感言

作为白嫖界两个无法绕过的网站服务提供商,cloudflare和Vercel给不少不想花钱购买服务器但又想搭建网站的人提供了最好的服务。

首先,虽然cloudflare免费服务提供的东西很少,但是那是相较于它的付费服务,免费服务真的吊打众多服务商,比如ddos防御,ssl证书,cdn服务等。

虽然有不少人嘲笑它是网站减速器,但是通过优选ip等操作可以弥补这一现象,让网站的速度和很多部署在香港CN2服务器的网站相差不大。

Vercel也同样如此,我们可以通过github登录vercel,然后无论是fork的项目还是自己写的项目都可以部署在vercel上。

虽然它提供的域名已被国内"墙"了,但是可以自定义域名避开这个限制。而且vercel还提供了针对国内的服务。

比如之前的cname解析记录为:cname.vercel-dns.com,你可以更改为cname-china.vercel-dns.com。

经过测试,国内优化的cname的确比初始cname快了许多。亦或者可以使用第三方加速cname,比如:vercel.cdn.yt-blog.top

结语

之前使用了白嫖的免费域名搭建了不少网站,但是因为地处江苏的原因,免费域名被跳反诈了,而申诉又很麻烦并且需要备案,所以就此放弃了免费域名。

但是cloudflare和Vercel对于通过购买的域名想要搭建网站的朋友还是非常有用的,比如常见的博客框架Hexo

使用cloudflare workers遇到的小问题

前言

今天闲来无事部署了几个小项目

教程

1.不能部署

很多朋友在填写好workers代码后会发现右上角的部署并不能点击,其实可以返回到项目首页然后再编辑代码,点击弹窗中的save就可以了。

2.报错函数名

因为今天部署的代码中有个需要用到kv存储,所以在workers代码中就有kv存储的名称,但是当时不知道,所以鼓捣了很久。

比如statuslive.get和statuslive.put,其中statuslive就是用到的kv存储的名称,我们就需要根据这个来设定kv存储的名称。

3.自定义路由

今天在给项目自定义域的时候发现自定义路由的时候提示需要有包含域名的子域名,但是我子域名名称中都有域名了还是提示一直添加失败。

暂未能够解决,如果谁知道解决方法请在下方留言,所以最终只能使用了自定义域。

推荐几个能够通过Vercel部署的项目

前言

上篇文章告诉大家如何白嫖免费域名,于是就想着搭建几个项目

项目

1.Lobe Chat

开源地址:https://github.com/lobehub/lobe-chat

2.ChatGpt-Next-Web

开源地址:https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web

3.DailyHot

开源地址:https://github.com/imsyy/DailyHot

这个需要fork到自己仓库,然后通过Vercel部署。

4.uptimerobot api监控页面

开源地址:https://github.com/freejishu/StatusLive

也是需要fork到自己仓库,然后通过vercel部署。

5.发现导航

开源地址:https://github.com/xjh22222228/nav

也是需要fork到自己仓库,然后通过vercel部署。

注册免费域名并托管到cloudflare

前言

今天逛博客的时候逛到友链淇云博客发现了一个好玩的文章,就是教我们怎么注册免费域名并且托管到cloudflare。

于是我就自己尝试了一下

教程

1.首先打开us.kg官网注册一个账号,点击下方的sign up

图片[1]-新锐博客

2.打开美国人身份生成网站,网站不要关闭

图片[2]-新锐博客

3.按照上面生成的地址填写信息

图片[3]-新锐博客

4.打开邮箱,找到新收到的邮件并且验证

图片[4]-新锐博客

5.按照下图选择验证方式

图片[5]-新锐博客

6.到Fake SID中生成学生卡ID

图片[6]-新锐博客

7.截图并且保存学生卡到电脑

8.上传学生卡

图片[7]-新锐博客

9.登录网站并且注册域名

10.登录cloudflare绑定域名

图片[8]-新锐博客

11.返回网站填写好cloudflare的给予的DNS服务器就行了

CloudFlare自选IP并配置dns,达到加速目的

前言

网上有不少的cloudflare优选ip的cname,但是别人的终归是别人能不能自己搭建一个呢?

开源地址

Github:https://github.com/ddgth/cf2dns

教程

此次教程使用的是自己服务器搭建

1.安装运行脚本所需依赖

pip install -r requirements.txt

2.登录腾讯云后台或者阿里云后台,获取 SecretId、SecretKey,如果使用阿里云DNS,注意需要添加DNS控制权限AliyunDNSFullAccess

3.将脚本下载到本地修改cf2dns.py中的SecretId、SecretKey

4.修改脚本中域名配置信息,可配置多个域名和多个子域名,注意选择DNS服务商

5.(可选)从商店购买KEY,当然也可以用脚本中自带的,区别是脚本中自带的KEY是历史优选的Cloudflare IP(也可以从这个网站查到IP的信息),而购买的KEY是15分钟内获取到的最新的Cloudflare IP。

6.运行程序,如果能够正常运行可以选择cron定时执行(建议15分钟执行一次)

python cf2dns.py

安装libmysqlclient库并设置环境变量

前言

在部署某个项目的时候提示缺失libmysqlclient库。

教程

安装

在Ubuntu或Debian系统上,可以使用以下命令安装:

sudo apt-get update 
sudo apt-get install libmysqlclient-dev

在CentOS或RHEL系统上,可以使用以下命令安装:

sudo yum install mysql-devel

设置环境变量

将如下的/path/to/your/libmysqlclient.so.16 替换成实际目录

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/your/libmysqlclient.so.16

不知道具体目录的可以使用如下命令查询

sudo find / -name libmysqlclient.so.*

结语

本文仅作记录,方便以后再次部署该项目时用到

❌