前言

原作者:子夜松声

有一些RSS链接不能订阅,于是换一个方式获取RSS:cURL

上面是因为没有修改UA导致的,后面就好了。

又因为文章里面插入短代码,很容易导致样式变乱,于是添加了新样式:

因为想插入在文章列表/首页,于是想添加php代码引入插件:

为了方便多个文章切换,于是引入了swiper.js:

一、修改过程 (1.8版本)

1 修改请求RSS方式

原本插件中使用 file_get_contents($rssUrl) 的部分改为 使用 cURL 请求 RSS 内容:

1.1 修改函数 file_get_contents($rssUrl)

private static function fetchUrl($url)
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; RSSFeedBot/1.0; +https://yourdomain.com)',
        CURLOPT_SSL_VERIFYPEER => false, // 如无证书验证可设为 true
        CURLOPT_SSL_VERIFYHOST => false
    ]);

    $data = curl_exec($ch);
    $error = curl_error($ch);

    if ($data === false) {
        self::logError("cURL 获取失败:{$url},错误:{$error}");
    }

    curl_close($ch);
    return $data;
}
注意:UA里面链接修改为自己域名,不写可能会导致无法请求部分RSS

1.2 修改调用 file_get_contents($rssUrl)

$rssContent = @file_get_contents($rssUrl);

修改为:

$rssContent = self::fetchUrl($rssUrl);
只需要在 getLatestRssItems() 中 替换即可,其他不变。

1.3 确保 PHP 支持 cURL

如果是宝塔,可以查看php是否安装 cURL 扩展。

如果不会,也可以终端输入:

php -m

查看是否有 cURL

2 添加新样式

找到插件 assets/rssfeed.css

添加debug样式:

.rss-debug {
  margin-top: 10px;
  font-size: 0.9em;
  color: #999;
  text-align: right;
}

修改其他样式(添加全文阅读按钮):

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
    Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  background-color: #fff;
  color: #444;
}

.rss-feed {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 2rem;
  max-width: 800px;
  margin: 0 auto;
}

@media (max-width: 1024px) {
  .rss-feed {
    padding: 1.5rem;
  }
}

@media (max-width: 600px) {
  .rss-feed {
    padding: 1rem;
  }
}

.rss-item {
  background-color: #fafafa;
  width: 100%;
  box-sizing: border-box;
  border-radius: 10px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  padding: 1.5rem 2rem;
  transition: box-shadow 0.3s ease;
  cursor: default;
}

.rss-item:hover {
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
}

.rss-meta {
  font-size: 0.85rem;
  color: #888;
  margin-bottom: 0.8rem;
  display: flex;
  gap: 1rem;
}

.rss-meta .rss-site,
.rss-meta .rss-author {
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.rss-title {
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0 0 0.7rem 0;
  color: #222;
  line-height: 1.3;
  user-select: text;
}

.rss-desc {
  font-size: 0.95rem;
  color: #555;
  line-height: 1.5;
  margin-bottom: 1.2rem;
}

.rss-footer {
  font-size: 0.85rem;
  color: #aaa;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  white-space: nowrap;
}

.rss-footer .rss-readmore {
  color: #1976d2;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}

.rss-footer .rss-readmore:hover {
  border-color: #1976d2;
}

3 修改render函数

为了得到横向和纵向的样式输出,我修改很多:

    /**
     * 渲染 RSS/Atom 内容
     */

public static function render($count = null)
{
    $data = self::getLatestRssItems($count);
    $items = $data['items'];
    $pluginUrl = Helper::options()->pluginUrl . '/RssFeed/assets';

    echo '<link rel="stylesheet" href="' . $pluginUrl . '/rssfeed.css">';

    if ($count !== null) {
        // 横向幻灯片样式 - 箭头按钮
        echo <<<HTML
<style>
.rssfeed-slider {
    position: relative;
    overflow: hidden;
    width: 100%;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 10px;
}
.rssfeed-container {
    display: flex;
    transition: transform 0.5s ease;
    width: 100%;
}
.rssfeed-article {
    min-width: 100%;
    box-sizing: border-box;
    padding: 1em 2em;
}
.rssfeed-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.3);
    border: 1px solid #ccc;
    cursor: pointer;
    z-index: 10;
    padding: 0;
    user-select: none;
    transition: background-color 0.3s, box-shadow 0.3s;
    display: flex;
    justify-content: center;
    align-items: center;
}
.rssfeed-btn:hover {
    background-color: #f0f0f0;
    box-shadow: 0 0 6px rgba(0,0,0,0.15);
}
.rssfeed-btn.prev {
    left: 10px;
}
.rssfeed-btn.next {
    right: 10px;
}
.rss-meta {
    font-size: 0.8em;
    color: #666;
    margin-bottom: 0.3em;
    display: flex;
    justify-content: space-between;
}
.rss-title {
    margin: 0.2em 0 0.6em 0;
    font-weight: bold;
    font-size: 1.2em;
}
.rss-desc {
    font-size: 1em;
    color: #333;
    margin-bottom: 0.8em;
}
.rss-footer {
    font-size: 0.8em;
    color: #999;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.rss-readmore {
    color: #1976d2;
    text-decoration: none;
}
.rss-readmore:hover {
    text-decoration: underline;
}
</style>

<div class="rssfeed-slider" role="region" aria-label="RSS 文章幻灯片">
    <button class="rssfeed-btn prev" onclick="slideArticle(-1)" aria-label="上一条">
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
            <path d="M10 12L6 8L10 4" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
    </button>
    <div class="rssfeed-container" id="rssfeedContainer">
HTML;

        foreach ($items as $item) {
            $title = htmlspecialchars($item['title'], ENT_QUOTES);
            $desc = htmlspecialchars($item['description'], ENT_QUOTES);
            $source = htmlspecialchars($item['source'], ENT_QUOTES);
            $author = htmlspecialchars($item['author'], ENT_QUOTES);
            $pubDate = htmlspecialchars($item['pubDate'], ENT_QUOTES);
            $link = htmlspecialchars($item['link'], ENT_QUOTES);

            echo <<<HTML
    <article class="rssfeed-article" role="group" aria-label="RSS文章">
        <div class="rss-meta">
            <span class="rss-site">{$source}</span>
            <span class="rss-author">{$author}</span>
        </div>
        <h4 class="rss-title">{$title}</h4>
        <p class="rss-desc">{$desc}</p>
        <div class="rss-footer">
            <span class="rss-date">{$pubDate}</span>
            <a class="rss-readmore" href="{$link}" target="_blank" rel="noopener noreferrer">阅读全文 →</a>
        </div>
    </article>
HTML;
        }

        echo <<<HTML
    </div>
    <button class="rssfeed-btn next" onclick="slideArticle(1)" aria-label="下一条">
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
            <path d="M6 12L10 8L6 4" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
    </button>
</div>

<script>
(function(){
    var currentIndex = 0;
    var container = document.getElementById('rssfeedContainer');
    var total = container.children.length;

    window.slideArticle = function(direction) {
        currentIndex += direction;
        if (currentIndex < 0) currentIndex = 0;
        if (currentIndex >= total) currentIndex = total - 1;
        container.style.transform = 'translateX(-' + (currentIndex * 100) + '%)';
    }
})();
</script>
HTML;

    } else {
        // 纵向列表样式(短代码用)
        if ($items) {
            echo '<div class="rss-feed">';
            foreach ($items as $item) {
                echo <<<HTML
<div class="rss-item">
    <div class="rss-meta">
        <div class="rss-site">{$item['source']}</div>
        <div class="rss-author">{$item['author']}</div>
    </div>
    <h4 class="rss-title">{$item['title']}</h4>
    <p class="rss-desc">{$item['description']}</p>
    <div class="rss-footer">
        <span class="rss-date">{$item['pubDate']}</span>
        <a class="rss-readmore" href="{$item['link']}" target="_blank">全文阅读 →</a>
    </div>
</div>
HTML;
            }
            echo '</div>';
            echo '<div class="rss-debug">';
            echo '本次抓取条目总数:' . $data['all_count'] . ',实际显示条数:' . $data['used_count'];
            echo ',缓存:' . ($data['cache_hit'] ? '命中' : '未命中');
            echo '</div>';
        } else {
            echo '<div class="rss-feed"><p>' . _t('无法获取 RSS/Atom 内容,请检查配置。') . '</p></div>';
        }
    }
}

你可以看到后面有debug的类似功能,确保输出文章正常。

4 添加输出

4.1 短代码输出

原插件的功能

4.2 页面横向输出

    <!-- 订阅圈开始 -->
     <?php \RssFeed_Plugin::render(10); // 显示最新10篇 ?>
    <!-- 结束 -->

我的主题:

    <!-- 订阅圈开始 -->
      <?php if($this->getCurrentPage() == 1): ?> BearSimple判断是否是第一面文章的代码
          <?php \RssFeed_Plugin::render(10); // 显示最新10篇 ?>
      <?php endif; ?>
    <!-- 结束 -->        
下载swiper.js放入assets文件夹里面

5 获取修改后完整代码:

原作者:子夜松声

短代码干扰,就不贴了。

二、文件下载和使用说明

请下载最新版本2.1

1.8版本
1.8版本-RssFeed.zip

版本使用教程:

<?php \RssFeed_Plugin::render(数量); ?>

2.0版本
2.0版本

版本使用教程:

<?php \RssFeed_Plugin::render(true); ?> true表示使用纵向输出

2.1版本
2.1版本

版本使用教程:

<?php Typecho_Plugin::factory('Widget_Archive')->rssfeedList(); ?>
<?php Typecho_Plugin::factory('Widget_Archive')->rssfeedSlider(); ?>

三、更新日志

请下载最新版本

202508030738修复:

  1. 修复php代码与短代码输出文章数目的冲突:取消代码设置数量 itemCount
  2. 添加php代码纵向输出,如下代码:
<?php \RssFeed_Plugin::render(true); ?>
true表示使用横向幻灯片输出文章

202508040430修复:

  1. 修复页面嵌入时关闭插件导致报错
  2. 更换抓取方式->SimplePie库
  3. 更换缓存为目录文件缓存 cache
  4. 添加README.md
<?php Typecho_Plugin::factory('Widget_Archive')->rssfeedList(); ?>
<?php Typecho_Plugin::factory('Widget_Archive')->rssfeedSlider(); ?>