Lawtee News

怎样给 Hugo 增加一个 RSS 边栏小工具

Featured image of post 怎样给 Hugo 增加一个 RSS 边栏小工具

今天上午本来想给 Hugo 主页边栏添加一个 RSS 小工具,用来展示其他跨站动态。本来也很简单,我甚至已经在本站 2025 页面将主要过程记了下来。结果没想到,一提交到 Github 就出了问题,不管是 Github 还是 Vercel 均部署失败。这里只好再详细记录下后续情况。

为 Hugo 添加一个 RSS 边栏小工具

在 Wordpress 中默认的小工具里边可以很方便添加 RSS 插件,但在 Hugo 上就得稍微麻烦点。不过,我的目的是将我的 WordPress 最新文章列表输出到 Hugo 上,倒也不必然使用 RSS 格式,直接调用 Wordpress API 即可。但与 RSS 相比,方法都是相同的。

  1. 在 Hugo 的边栏模板中添加调用模块

    • 方法 A:RSS 调用

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      {{ $rssUrl := "https://news.lawtee.com/feed/" }} <!-- 替换为你的 RSS 地址 -->
      {{ $rss := resources.GetRemote $rssUrl }}
      {{ $items := $rss | transform.Unmarshal }}
      <h2>RSS</h2>
      <ul>
       {{ range first 7 $items.channel.item }}
       <li>
       <a href="{{ .link }}" target="_blank">{{ .title }}</a>
       </li>
       {{ end }}
      </ul>
      
    • 方法 B:WordPress API 调用

      1
      2
      3
      4
      5
      6
      7
      8
      
      {{ $url := "https://news.lawtee.com/wp-json/wp/v2/posts?per_page=5" }} <!-- 替换为你的 WordPress 地址 -->
      {{ $posts := getJSON $url }}
      <h2>最新文章</h2>
      <ul>
       {{ range $posts }}
       <li><a href="{{ .link }}" target="_blank">{{ .title.rendered }}</a></li>
       {{ end }}
      </ul>
      
  2. 设置必要的 CSS。例如,我为了省事直接套了另一个 Hugo 边栏插件 archives 的 CSS。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    <section class="widget archives">
     <div class="widget-icon">
     {{ partial "helper/icon" "rss" }}
     </div>
     <h2 class="widget-title section-title">
     <a href="https://news.lawtee.com/" target="_blank">News</a>
     </h2>
     <div class="widget-archive--list">
     <ul>
     {{ range $posts }}
     <li><a href="{{ .link }}" target="_blank">{{ .title.rendered }}</a></li>
     {{ end }}
     </ul>
     </div>
     </section>
    

事情到这里本来就结束了,因为我在本地使用 Hugo Server 命令调试时发现一切运作正常。但没想到在提交 Github 后却出了问题。

Github 和 Vercel 无法正常构建远程调用的 RSS 源

  1. 错误情况。Github Actions 和 Vercel 在 npm run build 后均出现如下错误:
1
ERROR render of "home" failed: "/home/runner/work/lawtee.github.io/lawtee.github.io/themes/hugo-theme-stack/layouts/index.html:18:7": execute of template failed: template: index.html:18:7: executing "right-sidebar" at <partial "sidebar/right.html" (dict "Context" . "Scope" "homepage")>: error calling partial: "/home/runner/work/lawtee.github.io/lawtee.github.io/themes/hugo-theme-stack/layouts/partials/sidebar/right.html:30:36": execute of template failed: template: partials/sidebar/right.html:30:36: executing "partials/sidebar/right.html" at <.link>: can't evaluate field link in type interface {}

简单说就是在我修改后的模板中读取 .link 失败,导致模板无法渲染。而这个 .link 应当是 RSS 中输出的文章固定链接。

我反复确认了一下源 RSS 格式,发现并没问题。于是怀疑是不是 Github 无法拉取 RSS 文件导致的。

  1. 在 Workflow 中添加网络测试
1
2
3
 - name: Test Network
 run: |
 curl -v "https://news.lawtee.com/feed/"

接着,我在 .github/workflow 的部署模板中添加如上测试,想看看是不是 Github 无法访问链接。但结果似乎没问题。

  1. 四处查找问题原因

也是奇了怪了,我接下来又调试了多次,包括重新指定 Hugo 版本,修正一些环境差异;将原来模板中远程调用 RSS 文件修改为 Hugo 构建前预先拉取远程文件到构建服务器,构建时再改用本地文件构建;在 RSS 与 Wordpress API 之间切换等等。试了个把小时,除了收到一堆部署失败邮件,毫无头绪。

  1. 重新确认为网络问题

后来,我又仔细查看确认了一下 Actions 在部署过程中的网络测试结果。这一看不要紧,在第 60 多行还真发现有个 403 。原因也很清晰,就是在构建过程中,Github Vercel 的服务器 IP 被 Cloudflare 当作网络攻击给自动防御了。

更改 Cloudflare WAF 设置,确保 Github Vercel 服务器能够访问到 RSS 地址

知道问题就好解决,在 Cloudflare 中添加 WAF 自定义规则,绕过 RSS 地址即可。

然而,这并没有啥用。仔细查看 Cloudflare 才发现,WAF 规则只对零散访问生效,而 Cloudflare 的自动程序防御优先级是高于 WAF 规则的。想要调整 WAF 自定义规则的优先级,必须充值为 PRO 用户才行。

好在 Cloudflare 还有一堆配置规则可以设置,像“页面规则”,优先级都是高过防火墙的。

于是在配置规则里将构建过程中需要访问的链接的安全级别修改为低,终于算是解决问题。

提示
如果 RSS 源站没有使用 Cloudflare 等防火墙,只需要第一步即可完成。