为 Hugo 静态网站添加全文检索功能
Hugo 是一种使用 Go 语言编写的静态网站构建工具。在其官网文章《Search for your Hugo Website》中,介绍几种为静态网站添加全文检索功能的方法。本文采用 Pagefind 为纯静态网站实现全文检索功能。
Pagefind 是一个独立的命令行工具,可以通过 npm install pagefind
来安装。其原理是:运行 Pagefind 命令,扫描所有静态网页并生成索引;用户搜索时,通过网页中内嵌的 JavaScript 脚本来访问预先生成的索引,从而实现静态全文检索。
Windows 系统下,使用 npm i pagefind
安装后,需要将 node_modules\pagefind\bin\pagefind_extended
文件重命名为 pagefind_extended.exe
才能正常使用。
实现原理
第一步,安装 Pagefind 工具。在 Hugo 项目根目录中运行:
bashnpm i pagefind
第二步,生成 Hugo 网站的静态文件:
bashhugo --minify
第三步,生成 Pagefind 索引:
bashnpx pagefind --source public --bundle-dir search
此命令会扫描 public 目录下的静态文件,并将生成的索引保存到 search 目录下(默认是 _pagefind 目录)。也可以通过配置文件来实现相同的操作。
在项目根目录下新建 pagefind.yml
配置文件,保存如下内容:
yamlsource: public
bundle_dir: search
然后直接运行:
bashnpx pagefind
Pagefind 会自动在当前目录下查找 pagefind.yml
配置文件,使用参数或配置文件的效果是等价的。其他参数可以参考官方文档。
第四步,在静态网页中添加全文搜索的入口:
html<link href="/search/pagefind-ui.css" rel="stylesheet">
<script src="/search/pagefind-ui.js" type="text/javascript"></script>
<div id="search"></div>
<script>
window.addEventListener('DOMContentLoaded', (event) => {
new PagefindUI({ element: "#search" });
});
</script>
自定义索引
可以通过在静态网页中添加特殊的 HTML 属性来控制 Pagefind 的行为。比如,HTML 元素添加属性 data-pagefind-body
表示需要索引此处的内容,添加属性 data-pagefind-ignore
表示不要索引此处内容。
html<article data-pagefind-body>
<h1 data-pagefind-meta="title">文章标题</h1>
<p>发布时间:<span data-pagefind-meta="日期">2022/10/18</span></p>
<p>作者:<span data-pagefind-meta="作者">Fournoas</span></p>
<p>正文内容</p>
<aside data-pagefind-ignore>目录</aside>
</article>
data-pagefind-meta
属性用于标记元数据。Pagefind 默认将网页中的 <h1>
元素中的文本当作标题。如果一个网页中包含多个 <h1>
标签,会导致搜索结果中的标题丢失。可以采取为元素添加属性 data-pagefind-meta="title"
指定网页的标题。
此外,还能通过 data-pagefind-filter
属性自定义搜索过滤器:
html<h1>文章标题</h1>
<p>分类: <span data-pagefind-filter="分类">小说</span></p>
<p>标签: <a data-pagefind-filter="标签">科幻</span> / <a data-pagefind-filter="标签">穿越</span></p>
上面的代码会让搜索结果的左侧会出现 分类
和 标签
两个过滤器。
配置 GitHub Actions
在文章《使用 GitHub Actions 自动部署 Hugo 站点》中提供了自动部署 Hugo 站点的 Workflow 配置,在此基础上进行简单修改,即可实现自动生成索引并发布。
编辑 .github/workflows/hugo.yml
文件,在 steps
小结中的 Build
和 Deploy
操作之间添加如下内容:
yml - name: Install nodejs
uses: actions/setup-node@v3
with:
node-version: 18
- run: npm i pagefind
- run: npx pagefind --source public --bundle-dir search
最后实现效果可以查看本站的搜索页面。