-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.html
90 lines (71 loc) · 3.23 KB
/
search.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
---
layout: default
---
<!-- TODO: can we make this search any better? Maybe search only within given categories etc.? How would the UI for that look?
Also, can we use autoSuggest in any way to get complections? without bogging down the entire site in js?
-->
<h2 id="search-page-title">Are you not searching for anything? Enable JS or something if search term is given, but this title still shows :smirk:</h2>
<p>(Hint: click on a result to open it! Results with a good score are marked with :trophy:)</p>
<br />
<div id="search-result-container">
</div>
<script src="https://cdn.commento.io/js/count.js"></script>
<!-- Thank you minisearch for helping me NOT write my own search engine xD -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/index.min.js"></script>
<script>
(function() {
const siteUrl = new URL(document.URL);
const searchInput = siteUrl.searchParams.get('term');
if (null === searchInput) {
return;
}
const searchTerm = decodeURIComponent(searchInput);
// TODO: include tags in search?
const searchEngine = new MiniSearch({
fields: ['title', 'body'],
storeFields: ['title', 'excerpt', 'url'],
searchOptions: {
boost: { title: 5 },
fuzzy: 0.2
}
});
// populate js search engine with data
let posts = [];
let currentId = 1;
{% for post in site.posts %}
posts.push({
id: currentId++,
title: `{{ post.title }}`,
excerpt: `{{ post.excerpt | strip_html | strip_newlines | escape }}`,
body: decodeURIComponent('{{ post.content | strip_html | url_encode }}'),
url: '{{ post.url | relative_url }}'
});
{% endfor %}
searchEngine.addAll(posts);
// search engine with some leeway on spelling
const results = searchEngine.search(searchTerm);
const title = document.getElementById('search-page-title');
const container = document.getElementById('search-result-container');
title.innerHTML = `${results.length} search results for "${searchTerm}" sorted by relevance`;
// simple calculation on how big the score needs to be for it to be considered good...
// numbers pulled straight out of my ass by trial and error
const goodScoreLimit = 14 + Math.pow(10, searchTerm.split(' ').length - 1);
results.forEach(elem => {
const resultEntry = document.createElement('div');
resultEntry.onclick = () => {
window.open(elem.url, '_self');
};
const heading = document.createElement('h3');
heading.innerHTML = (elem.score > goodScoreLimit ? ':trophy: ' : '') + elem.title;
resultEntry.appendChild(heading);
const comments = document.createElement('a');
comments.href = `{{site.url}}${elem.url}#commento`;
resultEntry.appendChild(comments);
const excerpt = document.createElement('p');
excerpt.innerHTML = elem.excerpt;
resultEntry.appendChild(excerpt);
resultEntry.appendChild(document.createElement('br'));
container.appendChild(resultEntry);
});
})();
</script>