--- title: "基于 INFINI Pizza 为 Hugo 静态站点添加搜索功能" date: 2024-08-28 lastmod: 2024-08-28 description: "INFINI Pizza 是一款基于 Rust 开发的开源搜索引擎,提供轻量级 WASM 核心,适用于静态网站和博客。通过 INFINI Pizza Docsearch,只需简单配置即可为静态站点添加离线搜索功能,快速便捷。" tags: ["Pizza", "Rust", "docsearch", "文档搜索", "搜索引擎"] summary: "INFINI Pizza 是 INFINI Labs 即将发布的一个基于 Rust 编写的搜索引擎(即将完全开源),目前已经完成基本的搜索能力,并且基于 INFINI Pizza 的核心引擎,提供了一个 WASM 版本的超轻量级内核,可以很方便的嵌入到各类应用系统,比如网站,尤其是静态站点或者小型的博客系统等。 目前 Pizza 和 INFINI Labs 官网已经集成了 INFINI Pizza for WebAssembly,具体的搜索效果如下图: [Pizza 官网] [INFINI Labs 中文官网] 打开上面的网站( https://infinilabs.cn),通过按下快捷 s即可调出搜索框,然后就可以体验到 INFINI Pizza 提供的搜索能力。值得特别提出的是,在搜索的过程你所有的操作都是在浏览器本地执行,也就是不会像传统的搜索实现方式那样,需要每次输入一个查询条件都会和后端的搜索服务器进行一次交互,相比之下, INFINI Pizza for WebAssembly 则是完全离线操作,即使断网,也能愉快的搜索。 废话不多说,接下来为大家介绍一下如何在你自己的站点来使用 INFINI Pizza for WebAssembly。 首先,INFINI Pizza for WebAssembly 是开源的,Github 地址在这里: https://github.com/infinilabs/pizza-wasm 编译好的 WASM 包在这里可以直接下载: https://github.com/infinilabs/pizza-wasm/tree/main/pkg ➜ wasm git:(main) ✗ du -sh pkg/* 4.0K pkg/README.md 4.0K pkg/package.json 4.0K pkg/pizza_wasm.d.ts 4." --- **INFINI Pizza 是 INFINI Labs 即将发布的一个基于 Rust 编写的搜索引擎(即将完全开源)**,目前已经完成基本的搜索能力,并且基于 INFINI Pizza 的核心引擎,提供了一个 WASM 版本的超轻量级内核,可以很方便的嵌入到各类应用系统,比如网站,尤其是静态站点或者小型的博客系统等。 目前 Pizza 和 INFINI Labs 官网已经集成了 INFINI Pizza for WebAssembly,具体的搜索效果如下图: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/1.png)
[Pizza 官网]
![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/2.jpg)
[INFINI Labs 中文官网]
打开上面的网站([https://infinilabs.cn](https://infinilabs.cn)),通过按下快捷 `s`即可调出搜索框,然后就可以体验到 INFINI Pizza 提供的搜索能力。值得特别提出的是,在搜索的过程你所有的操作都是在浏览器本地执行,也就是不会像传统的搜索实现方式那样,需要每次输入一个查询条件都会和后端的搜索服务器进行一次交互,相比之下, INFINI Pizza for WebAssembly 则是完全离线操作,即使断网,也能愉快的搜索。 废话不多说,接下来为大家介绍一下如何在你自己的站点来使用 INFINI Pizza for WebAssembly。 首先,INFINI Pizza for WebAssembly 是开源的,Github 地址在这里:[https://github.com/infinilabs/pizza-wasm](https://github.com/infinilabs/pizza-wasm) 编译好的 WASM 包在这里可以直接下载:[https://github.com/infinilabs/pizza-wasm/tree/main/pkg](https://github.com/infinilabs/pizza-wasm/tree/main/pkg) ```sh ➜ wasm git:(main) ✗ du -sh pkg/* 4.0K pkg/README.md 4.0K pkg/package.json 4.0K pkg/pizza_wasm.d.ts 4.0K pkg/pizza_wasm.js 12K pkg/pizza_wasm_bg.js 580K pkg/pizza_wasm_bg.wasm 4.0K pkg/pizza_wasm_bg.wasm.d.ts 256K pkg/pizza_wasm_bg.wasm.gz ``` 可以看到,WASM 的包只有 500 多 KB,通过 Gzip 压缩之后,只有 200 多 KB,比较轻量级。 Pizza-WASM 是 INFINI Pizza 核心引擎的 WebAssembly 接口封装,只对外暴露了几个简单的访问接口,对于目前的前端搜索应用足够了,在 [https://github.com/infinilabs/pizza-wasm/tree/main/web](https://github.com/infinilabs/pizza-wasm/tree/main/web) 里面有一个非常简单的 WASM 方法调用的例子,可以简单进行了解。 当然,只是有 Pizza 的 WASM 还是不够的,我们如果要在现有的静态站点上添加搜索框的,还需要考虑数据怎么来,结果如何展现,所以针对这个场景,我们封装好了一个 Pizza-DocSearch 的一个项目,可以直接进一步简化使用,项目也是开源的,Github 地址是:[https://github.com/infinilabs/pizza-docsearch](https://github.com/infinilabs/pizza-docsearch) 由于示例项目里面默认已经将编译好的代码和样例上传了,我们直接下载这个源代码并本地进行功能预览: ```sh ➜ /tmp git clone https://github.com/infinilabs/pizza-docsearch.git Cloning into 'pizza-docsearch'... remote: Enumerating objects: 174, done. remote: Counting objects: 100% (174/174), done. remote: Compressing objects: 100% (112/112), done. remote: Total 174 (delta 86), reused 147 (delta 59), pack-reused 0 (from 0) Receiving objects: 100% (174/174), 941.94 KiB | 1.20 MiB/s, done. Resolving deltas: 100% (86/86), done. ➜ /tmp cd pizza-docsearch/example/dist ➜ dist git:(main) python3 -m http.server 8083 Serving HTTP on :: port 8083 (http://[::]:8083/) ... ``` 打开浏览器,并访问:http://localhost:8083,如下: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/3.gif) 观察浏览器的网络请求,可以看到会加载示例的 index.json 数据: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/4.png) 实际的情况,如果是我们自己的静态网站或者是博客,只有保证网站根目录有这个文件及相应的格式,即可快速将这个你看到的搜索功能集成到你自己的网站上去。OK,功能验证完毕了,我们开始集成到我们的站点吧。 Pizza/INFINI Labs 的官网,使用的 Hugo 来静态生成的,index.json 文件不需要手动生成,首先我们需要让 Hugo 生成 JSON 格式的内容,这个是 Hugo 自带的能力,我们需要修改 Hugo 项目的配置: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/5.png) 将 outputs 参数这里新增一个 JSON 的输出,然后我们在主题的模版里面再定义一下 JSON 输出的格式模版: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/6.png) 文本格式的内容如下,方便复制粘贴,保存文件名为 `index.json`: ```sh {{- $index := slice -}} {{- range where .Site.RegularPages.ByDate.Reverse "Type" "not in" (slice "page" "json") -}} {{- $index = $index | append (dict "title" (.Title | plainify) "url" .Permalink "tags" .Params.tags "category" .Params.category "subcategory" .Params.subcategory "summary" (.Params.Summary | markdownify | plainify) "content" (.Content | markdownify | plainify)) -}} {{- end -}} {{- $index | jsonify -}} ``` OK,接下来就是将站点内每篇文章或者博客的元数据里面加上我们上面已经用到了的标签: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/7.png) OK, 启动 Hugo 站点: ```sh | EN -------------------+------ Pages | 181 Paginator pages | 5 Non-page files | 0 Static files | 110 Processed images | 0 Aliases | 52 Sitemaps | 1 Cleaned | 0 Built in 323 ms Watching for changes in /Users/medcl/Documents/rust/pizza/website/{assets,content.en,static,themes} Watching for config changes in /Users/medcl/Documents/rust/pizza/website/config.yaml Environment: "development" Serving pages from memory Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender Web Server is available at //localhost:1313/ (bind address 127.0.0.1) Press Ctrl+C to stop ``` 打开 Hugo 的站点地址,并尝试访问 `http://localhost:1313/index.json`, 应该就可以访问到这个 JSON 文件了: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/8.png) 至此,数据准备完毕,接下来我们集成前端搜索控件。 还记得我们之前从 Pizza-docsearch 下载的资源文件么,我们主要用到 `assets` 里面的 3 个文件: ```sh /tmp/pizza-docsearch/example/dist ➜ dist git:(main) tree . ├── assets ├── index-C1z1vz3D.css ├── index-D_gOo737.js └── pizza_wasm_bg-BRCuviY_.wasm ├── index.html └── index.json 1 directory, 5 files ➜ dist git:(main) ``` 打开 index.html 文件,我们可以看到里面的内容如下: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/13.png) 拷贝这个 assets 目录文件到我们的 Hugo 站点,位置如下: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/9.png) 然后修改 Hugo 的主题模版,在所有页面的头模版 `html-head.html`里面增加一段代码来加载我们的 CSS 样式文件: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/10.png) 然后继续修改 Hugo 的主题模版文件,在所有页面的页脚模版,增加一段代码来加载 JS 脚本文件: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/11.png) 然后,在页面模版的适当位置,插入一下 Docsearch 的一段标签,用于放置搜索框,如图: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/14.png) 至此,大功告成! 打开浏览器即可看到最终效果: ![](/img/blog/2024/adding-docsearch-to-hugo-static-sites-based-on-pizza/12.png) 最后,总结一下,借助 INFINI Pizza Docsearch 的 3 个小文件,只需 3 行代码,你可以在 5 分钟内为你的静态站点添加一个轻量级的离线搜索功能,快去试试吧。 相关链接: - [Pizza](https://pizza.rs) - [Pizza Wasm](https://github.com/infinilabs/pizza-wasm) - [Pizza Docsearch](https://github.com/infinilabs/pizza-docsearch)