Hugo的站内搜索有很多方案,Hugo官网了列出了7种,大家用的应该是hugo-lunr-zh吧,这里我们不引入任何第三方库,另辟蹊径地解决Hugo站内搜索功能。
思路
Hugo会默认生成index.xml文件,里面包含全站内容,以此文件进行内容搜索。这种方法不需要引用第三方库,在前端进行搜索,简洁且速度快!
步骤
- 在主题的layouts/_default目录下新建search.html模板文件
- 在站点的content目录新建search.md文章
- 分别在站点的header中添加css样式,在footer中添加js脚本
- 搜索页面的url为http://localhost:1313/search/,可以添加到站点菜单中
实现代码
js代码:
1 // search
2 function search() {
3 key = document.getElementById("search-key").value;
4 if (key === "") {
5 return;
6 }
7 document.getElementById("search-key").value = "";
8
9 // tip
10 document.getElementById("search-tip").innerText = "搜索中,请稍后 ...";
11 document.getElementById("search-tip").style.display = "block";
12
13 // clear
14 var el = document.getElementById('result');
15 var childs = el.childNodes;
16 for (var i = childs.length - 1; i >= 0; i--) {
17 el.removeChild(childs[i]);
18 }
19
20 // xml
21 xmltext = new XMLHttpRequest;
22 xmltext.open("GET", "/index.xml", false);
23 xmltext.send();
24 resp = xmltext.responseXML;
25 items = resp.getElementsByTagName("item");
26 // search
27 var i = 0;
28 haveResult = false;
29 while (i < items.length) {
30 txt = items[i].getElementsByTagName("title")[0].innerHTML + items[i].getElementsByTagName("description")[0].innerHTML
31 if (txt.toLowerCase().indexOf(key.toLowerCase()) > -1) {
32 haveResult = true;
33 title = items[i].getElementsByTagName("title")[0].innerHTML;
34 link = items[i].getElementsByTagName("link")[0].innerHTML;
35 time = items[i].getElementsByTagName("pubDate")[0].innerHTML;
36 mark = items[i].getElementsByTagName("description")[0].innerHTML;
37 addItem(title, link, time, mark)
38 }
39 i++;
40 }
41 if (!haveResult) {
42 document.getElementById("search-tip").innerText = "搜索完毕,未发现结果 ...";
43 document.getElementById("search-tip").style.display = "block";
44 }
45 }
46
47 // add
48 function addItem(title, link, time, mark) {
49 document.getElementById("search-tip").style.display = "none";
50 tmpl = "<article class=\"post\" style=\"border-bottom: 1px solid #e6e6e6;\" >" +
51 "<header class=\"post-header\">" +
52 "<h1 class=\"post-title\"><a class=\"post-link\" href=\"" + link + "\" target=\"_blank\">" + title + "</a></h1>" +
53 "<div class=\"post-meta\">" +
54 " <span class=\"post-time\">" + time + "</span>" +
55 "</div>" +
56 " </header>" +
57 "<div class=\"post-content\">" +
58 "<div class=\"post-summary\">" + mark + "</div>" +
59 "<div class=\"read-more\">" +
60 "<a href=\"" + link + "\" class=\"read-more-link\" target=\"_blank\">阅读更多</a>" +
61 "</div>" +
62 " </div>" +
63 "</article>"
64 div = document.createElement("div")
65 div.innerHTML = tmpl;
66 document.getElementById('result').appendChild(div)
67 }
68/*********************search.js end***************** */
css样式如下:
1 /* 手机适配 */
2 @media screen and (max-width: 500px) {
3 .search{
4 padding-right: 25px;
5 }
6
7 .search input{
8 width: 100%;
9 }
10
11 .search button{
12 display: none;
13 }
14 }
15 /* 电脑适配 */
16 @media screen and (min-width: 500px) {
17 .search{
18 width: 500px;
19 }
20
21 .search input{
22 width: 444px;
23 }
24 }
25
26 /* 通用样式 */
27 .search{
28 margin: auto;
29 width: 70%;
30 padding-top: 10%;
31 }
32
33 .search input{
34 outline: none;
35 border: 2px solid var(--accent);
36 height: 50px;
37 padding: 10px;
38 }
39 .search button{
40 outline: none;
41 border: 0px;
42 height: 50px;
43 width:59px;
44 position:absolute;
45 background-color:var(--accent) ;
46 display: inline-block;
47 }
48 .search .icon{
49 width: 28px;
50 height: 28px;
51 }
search.html模板:
1{{ define "main" }}
2<!-- All of the site's posts grouped by year -->
3<section id="main">
4 <div class="container">
5 <section id="archives" >
6 <div class="search">
7 <input type="text" placeholder="请输入搜索内容..." id="search-key" />
8 <button onclick="search()">
9 <svg t="1583982313567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1271"
10 width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink">
11 <defs>
12 <style type="text/css"></style>
13 </defs>
14 <path d="M694.857143 475.428571q0-105.714286-75.142857-180.857142T438.857143 219.428571 258 294.571429 182.857143 475.428571t75.142857 180.857143T438.857143 731.428571t180.857143-75.142857T694.857143 475.428571z m292.571428 475.428572q0 29.714286-21.714285 51.428571t-51.428572 21.714286q-30.857143 0-51.428571-21.714286l-196-195.428571q-102.285714 70.857143-228 70.857143-81.714286 0-156.285714-31.714286t-128.571429-85.714286-85.714286-128.571428T36.571429 475.428571t31.714285-156.285714 85.714286-128.571428 128.571429-85.714286T438.857143 73.142857t156.285714 31.714286 128.571429 85.714286 85.714285 128.571428T841.142857 475.428571q0 125.714286-70.857143 228l196 196q21.142857 21.142857 21.142857 51.428572z"
15 p-id="1272" fill="#ffffff"></path>
16 </svg>
17 </button>
18</div>
19<h1 id="search-tip" style="color: #c05b4d;text-align: center;display: none;">搜索中,请稍后 ...</h1>
20<br />
21<div id="result" style="padding-left: 10px;"></div>
22 </section>
23
24 </div>
25</section>
26{{ end }}
search.md文章内容:
1---
2title: "Search"
3date: "2019-07-10"
4author: "joe"
5layout: search
6type: search
7---