如何在JSON数据中添加超链接并在Pug模板中渲染?
为JSON文本中的特定词汇添加超链接并在Pug模板渲染的解决方案
我基于ExpressJS开发超文本博客原型,博客数据存储在JSON文件中。希望为JSON数据里的特定词汇(如Mikan、Arigachi na Renai等)添加超链接,在Pug模板中渲染为可点击的链接,但直接在JSON中写入HTML标签无效,求可行实现方法。
相关代码片段
JSON数据结构:
{ "id": 1, "name_kanji": "井上和 ", "trivia": [ "Favorite food are Mikan and bell pepper stuffed with meat", "Lightstick Colors are red and white", "Favorite color is mustard yellow", "Favorite Nogizaka46song is Arigachi na Renai", "Her favorite animes are 86 Eighty Six, Vivy and No Game No Life", "She likes anime songs, vocaloid, Yonezu Kenshi and Yorushika", "Her favorite mangas are Magi and Tokimeki Tonight", "She was the first Nogizaka46 5th Generation Member to be announced" ], "tv_participation": [ "Nogizaka Shin Star Tanjo!", "Nogizaka Under Construction", "Music Blood" ], "single_participation": [ "Actually...", "Suki to Iu no wa Rock daze!", "Koko ni wa Nai Mono" ] }
Pug模板代码:
block col-2 ul each val in member.trivia li= val
可行解决方案
方法1:后端文本替换(推荐)
在Express路由层处理JSON数据,把目标词汇替换为带<a>标签的HTML字符串,再传递给Pug模板渲染。
- 先定义词汇与链接的映射表(可单独抽成配置文件维护):
const linkMap = { 'Mikan': '/tags/mikan', 'Arigachi na Renai': '/songs/arigachi-na-renai', '86 Eighty Six': '/animes/86-eighty-six', 'Vivy': '/animes/vivy', 'No Game No Life': '/animes/no-game-no-life', 'Yonezu Kenshi': '/artists/yonezu-kenshi', 'Yorushika': '/artists/yorushika', 'Magi': '/mangas/magi', 'Tokimeki Tonight': '/mangas/tokimeki-tonight' };
- 读取JSON数据后,处理
trivia字段:
// 假设已读取到member数据 member.trivia = member.trivia.map(item => { let processedText = item; // 遍历映射表完成替换,\b确保匹配完整词汇 Object.entries(linkMap).forEach(([term, url]) => { const regex = new RegExp(`\\b${term}\\b`, 'g'); processedText = processedText.replace(regex, `<a href="${url}">${term}</a>`); }); return processedText; });
- 修改Pug模板,用
!=替代=(=会自动转义HTML,!=渲染原始HTML):
block col-2 ul each val in member.trivia li!= val
方法2:Pug模板全局函数处理
如果不想修改后端逻辑,可以在Express中注册全局函数,在Pug模板中调用完成替换。
- 在Express中注册全局函数:
app.locals.addLinks = (text) => { const linkMap = { 'Mikan': '/tags/mikan', // 其他词汇映射... }; let result = text; Object.entries(linkMap).forEach(([term, url]) => { const regex = new RegExp(`\\b${term}\\b`, 'g'); result = result.replace(regex, `<a href="${url}">${term}</a>`); }); return result; };
- 修改Pug模板:
block col-2 ul each val in member.trivia li!= addLinks(val)
关键注意点
- 必须用
!=渲染HTML内容,=会把<a>标签转义成纯文本显示。 - 正则中的
\b用于匹配单词边界,避免误替换包含目标词汇的长单词(如不会把"Mikanjuice"拆分开替换)。 - 词汇映射表单独维护,新增或修改词汇时只需调整配置,无需改动业务代码。
内容的提问来源于stack exchange,提问作者Cauã Almeida
相关产品推荐
相关产品推荐

