Hugo添加搜索
感谢:ZISHU ,分享了“用原生 js 给网站写个搜索功能”这篇文章。
大体步骤差不多,但是按照上面链接操作,打开搜索页面为空。以下为修改后的顺序。
具体操作步骤:
1,在主题\layouts文件夹,新建index.json文件,此时本地预览http://localhost:1313/index.json查看,如有显示标题,地址这些就表示这一步成功。
{{- $.Scratch.Set "posts" slice -}}
{{- range where .Site.RegularPages "Type" "post" -}}
{{- $.Scratch.Add "posts" (dict "title" .Title "permalink" .Permalink "summary" .Summary "content" .Content) -}}
{{- end -}}
{{- $.Scratch.Get "posts" | jsonify -}}
2,在\layouts\page文件夹,新建search.html文件,每个主题文件有差异,可参考同主题的single.html
{{ partial "header.html" . }}
<main>
<div class="header">
</div>
<article class="post-content markdown-body">
{{ .Site.Params.postHeaderContent | safeHTML }}
{{ .Content }}
<form id="searchForm">
<input autocomplete="off" type="text" id="searchInput" placeholder="输入搜索内容..." required>
<button type="submit">Saerch</button>
</form>
<ul id="resultsList" style="list-style-type: none;padding: 20px 0;word-wrap: break-word;color: #6b7280;"></ul>
</article>
<script>
let data = [];
// 从 /index.json 加载数据
fetch('/index.json')
.then(response => response.json())
.then(json => {
data = json; // 保存数据
})
.catch(error => console.error('Error loading data:', error));
document.getElementById('searchForm').addEventListener('submit', function (event) {
event.preventDefault();
const query = document.getElementById('searchInput').value.toLowerCase();
const resultsList = document.getElementById('resultsList');
resultsList.innerHTML = ''; // 清空之前的结果
if (query) {
const results = data.filter(item =>
item.title.toLowerCase().includes(query) ||
item.summary.toLowerCase().includes(query) ||
item.content.toLowerCase().includes(query) // 添加全文内容的搜索
);
if (results.length > 0) {
results.forEach(item => {
const listItem = document.createElement('li');
const truncatedContent = getTruncatedContent(item.content, query);
listItem.innerHTML = `
<a href="${item.permalink}" target="_blank">${highlightKeywords('<h999 style="color: #f7828a;margin-right: 10px;">➤</h999> ' + item.title, query)}</a>
<p>${highlightKeywords(truncatedContent, query)}</p>
`;
resultsList.appendChild(listItem);
});
} else {
resultsList.innerHTML = '<li>没有找到相关内容。</li>';
}
}
});
function highlightKeywords(text, query) {
const regex = new RegExp(`(${query})`, 'gi');
return text.replace(regex, '<span class="keyword-highlight">$1</span>');
}
function getTruncatedContent(content, query) {
const index = content.toLowerCase().indexOf(query);
if (index === -1) return highlightKeywords(content, query); // 如果没有找到关键词,返回高亮的内容
const start = Math.max(0, index - 50); // 前50个字符
const end = Math.min(content.length, index + query.length + 50); // 后50个字符
const truncated = content.substring(start, end);
// 添加省略号
if (start > 0) {
return '...' + highlightKeywords(truncated, query); // 在开头添加省略号
} else if (end < content.length) {
return highlightKeywords(truncated, query) + '...'; // 在结尾添加省略号
}
return highlightKeywords(truncated, query); // 返回高亮的截断内容
}
</script>
</main>
3,在\content,新建search.md
---
slug: search
title: search
layout: search
---
4,在config.toml设置
[[params.socials]]
name = "搜索"
link = "/search/"
[outputs]
home = ["HTML", "JSON"]
5,最后一步,添加相应的css
#searchForm {
margin-top: 20px;
display: flex;
align-items: center;
max-width: 800px;
width: 100%;
}
#searchForm input {
flex: 1;
height: 50px;
padding: 0 15px;
outline: none;
border: 2px solid #ccc;
border-radius: 3px;
}
#searchForm input:focus {
border-color: #666;
}
#searchForm button {
height: 50px;
padding: 0 15px;
cursor: pointer;
background: #c4c3c3;
outline: none;
border: 2px solid #ccc;
margin-left: 10px;
border-radius: 3px;
width: 20%;
}
#resultsList {
padding-left: 18px;
}
#resultsList .keyword-highlight {
background: #f6f694;
padding: 0 2px;
border-radius: 3px;
}
#resultsList > li {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 2px solid #ccc;
}
#resultsList > li > a {
color: #6b7280;
}
#resultsList * {
padding: 0;
margin: 0;
font-size: inherit;
color: inherit;
}
至此hugo即可。