使用 Hugo 生成 API 接口

本文介绍如何利用Hugo静态站点生成器输出API接口,通过自定义输出功能与模板生成,实现Markdown文件转换为JSON格式的API数据,适用于静态站点或SPA应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2018年09月14日 统计字数: 2654字 阅读时间: 6分钟阅读 本文链接: https://soulteary.com/2018/09/14/use-hugo-to-generate-the-api-interface.html


使用 Hugo 生成 API 接口

随着 SSG 静态生成工具的蓬勃发展,市面上能看到越来越多的静态站点,一般的使用方法是通过静态展点生成工具生成静态页面,然后进行发布。

我个人使用了一年多的 Hugo ,不论是稳定性还是易用性方面,都无愧于开源社区里关注度第一。

但是这类静态站点生成器就只能做一些静态站点使用了么?当然不是。

Hugo 的自定义输出功能,搭配模板生成,可以轻松输出一些静态 API 接口,而内容可以使用 Markdown 来进行编写,还允许使用目录树的方式进行管理。

不论是搭配静态生成站点使用、还是简单提供给外部其他的 SPA 应用都是很方便的。

下面就来介绍如何使用 Hugo 输出 API 接口。

声明配置

首先需要在 config.toml 中指定各种页面的输出类型为 json

 
  1. [outputs]
  2. page = ["json"]
  3. home = ["json"]
  4. teams = ["json"]
  5. section = ["json"]
  6. taxonomy = ["json"]

定义模板

接着

接着需要在 layouts/_default/ 中创建 single.json、 item.json、 list.json 并使用变量和模板函数编写即可,比如:

 
  1. {
  2. "title": "{{ .Title }}",
  3. "date": "{{ .Date }}",
  4. "type": "{{ .Type }}",
  5. "permalink" : "{{ .Permalink }}",
  6. "summary" : "{{ .Summary }}"
  7. }

即可将某个 Markdown 文件转换为 下面的内容:

 
  1. {
  2. "data": {
  3. "title": "About",
  4. "date": "2018-02-09 11:47:06 -0500 -0500",
  5. "type": "page",
  6. "permalink": "/page/about/index.json",
  7. "summary": "An API about our school athletes!"
  8. }
  9. }

列表文件、和独立的页面文件同理,可以参考我提供的示例项目代码。

调整输出

Hugo 输出 API 依赖模板,使用的是拼凑的方法,所以输出结果难免会像下面一样,掺杂大量无用的空格字符,甚至有可能包含错误结果。

 
  1. {
  2. "data" :
  3. {
  4. "name": "Frank J. Robinson",
  5. "contact" : "+1 (555) 555 5555",
  6. "permalink" : "/players/frank-j-robinson/index.json",
  7. "year" : "junior"
  8.  
  9.  
  10. ,"practices" : "Monday, Thursday"
  11.  
  12.  
  13.  
  14. ,"sports" : "soccer, baseball"
  15.  
  16.  
  17.  
  18. }
  19.  
  20. }

为了最后产物的可用性(性能、预发正确),需要使用脚本对产物进行额外处理,这里我使用 Node.js :

 
  1. 'use strict';
  2.  
  3. const {readdirSync, statSync, readFileSync, writeFileSync} = require('fs');
  4. const {join} = require('path');
  5.  
  6. function getAllFiles(dirPath, ext) {
  7. function flatten(arr) {
  8. return arr.reduce((flat, toFlatten) => flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten), []);
  9. }
  10.  
  11. function scanDir(dirPath, ext) {
  12. const result = readdirSync(dirPath);
  13. if (!result.length) return [];
  14. return result.map((dirName) => {
  15. const filePath = join(dirPath, dirName);
  16. if (statSync(filePath).isDirectory()) {
  17. return scanDir(join(dirPath, dirName), ext);
  18. } else {
  19. if (!ext) return filePath;
  20. if (filePath.lastIndexOf(ext) === filePath.indexOf(ext) && filePath.indexOf(ext) > -1) return filePath;
  21. return '';
  22. }
  23. });
  24. }
  25.  
  26. return flatten(scanDir(dirPath, ext)).filter((file) => file);
  27. }
  28.  
  29. const allMarkdownFiles = getAllFiles('./public', '.json');
  30. allMarkdownFiles.forEach((item) => {
  31. try {
  32. const jsonData = JSON.stringify(JSON.parse(readFileSync(item, 'utf8')));
  33. writeFileSync(item, jsonData);
  34. } catch (e) {
  35. console.error(`${item} content error.`);
  36. writeFileSync(item, JSON.stringify({code: 500, desc: 'Unexpected token'}));
  37. }
  38. });

将脚本保存为 checker.js 执行 node checker 即可批量对 Hugo 的产物进行正确性校验和结果压缩。

比如上面的产物在执行完毕处理脚本后会变成:

 
  1. {"data":{"name":"Frank J. Robinson","contact":"+1 (555) 555 5555","permalink":"/players/frank-j-robinson/index.json","year":"junior","practices":"Monday, Thursday","sports":"soccer, baseball"}}

把这个脚本配置到 CI 中,即可完成修改 Markdown 文件,就能够自动生成高性能可用的静态 API 了。

其他

相关示例代码,可以访问:

Hugo 还有一堆其他的玩法,后面有机会再聊。

-EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值