Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

Commit 04c3621

Browse files
committed
Add sidebar with GUI filters to the search results page
1 parent b1730d8 commit 04c3621

File tree

2 files changed

+150
-39
lines changed

2 files changed

+150
-39
lines changed

web/server.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ var Funcmap = template.FuncMap{
4242
"More": func(orig int) int {
4343
return orig * 3
4444
},
45+
"IsLangFilterChecked": func(query, lang string) bool {
46+
return strings.Contains(query, "lang:"+lang)
47+
},
48+
"IsRepoFilterChecked": func(query, repo string) bool {
49+
return strings.Contains(query, "r:"+repo)
50+
},
51+
"Repos": func(fileMatches []*FileMatch) map[string]int {
52+
repos := make(map[string]int)
53+
for _, fileMatch := range fileMatches {
54+
repos[fileMatch.Repo]++
55+
}
56+
57+
return repos
58+
},
59+
"Languages": func(fileMatches []*FileMatch) map[string]int {
60+
languages := make(map[string]int)
61+
for _, fileMatch := range fileMatches {
62+
languages[fileMatch.Language]++
63+
}
64+
65+
return languages
66+
},
4567
"HumanUnit": func(orig int64) string {
4668
b := orig
4769
suffix := ""

web/templates.go

Lines changed: 128 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -205,49 +205,102 @@ var TemplateText = map[string]string{
205205
window.location.href = "/search?q=" + escape("{{.QueryStr}}" + " " + atom) +
206206
"&" + "num=" + {{.Last.Num}};
207207
}
208+
209+
function addFilter(filter) {
210+
var searchBox = document.getElementById("navsearchbox");
211+
var search = document.querySelector(".btn.btn-primary");
212+
213+
var oldQuery = searchBox.value.trim();
214+
215+
if (oldQuery.includes(filter)) {
216+
searchBox.value = oldQuery.replace(filter, '');
217+
search.click();
218+
return;
219+
}
220+
221+
searchBox.value = (oldQuery + ' ' + filter).trim();
222+
search.click();
223+
}
224+
208225
</script>
226+
<style>
227+
.search-main {
228+
display: flex;
229+
}
230+
231+
.container-sidebar {
232+
flex: 1;
233+
padding: 1rem;
234+
}
235+
236+
.container-results {
237+
flex: 3;
238+
}
239+
240+
.sidebar-title {
241+
font-weight: bold;
242+
}
243+
244+
.sidebar-repo-info {
245+
margin-bottom: 0.5rem;
246+
display: flex;
247+
justify-content: space-between;
248+
}
249+
250+
.sidebar-count {
251+
background-color: black;
252+
min-width: 30px;
253+
padding: 2.5px;
254+
border-radius: 25%;
255+
color: white;
256+
}
257+
</style>
209258
<body id="results">
210259
{{template "navbar" .Last}}
211-
<div class="container-fluid container-results">
212-
<h5>
213-
{{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
214-
{{ $fileCount := len .FileMatches }}
215-
Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
216-
showing top {{ $fileCount }} files (<a rel="nofollow"
217-
href="search?q={{.Last.Query}}&num={{More .Last.Num}}">show more</a>).
218-
{{else}}.{{end}}
219-
</h5>
220-
{{range .FileMatches}}
221-
<table class="table table-hover table-condensed">
222-
<thead>
223-
<tr>
224-
<th>
225-
{{if .URL}}<a name="{{.ResultID}}" class="result"></a><a href="{{.URL}}" >{{else}}<a name="{{.ResultID}}">{{end}}
226-
<small>
227-
{{.Repo}}:{{.FileName}}</a>:
228-
<span style="font-weight: normal">[ {{if .Branches}}{{range .Branches}}<span class="label label-default">{{.}}</span>,{{end}}{{end}} ]</span>
229-
{{if .Language}}<button
230-
title="restrict search to files written in {{.Language}}"
231-
onclick="zoektAddQ('lang:{{.Language}}')" class="label label-primary">language {{.Language}}</button></span>{{end}}
232-
{{if .DuplicateID}}<a class="label label-dup" href="#{{.DuplicateID}}">Duplicate result</a>{{end}}
233-
</small>
234-
</th>
235-
</tr>
236-
</thead>
237-
{{if not .DuplicateID}}
238-
<tbody>
239-
{{range .Matches}}
240-
<tr>
241-
<td style="background-color: rgba(238, 238, 255, 0.6);">
242-
<pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}}</pre>
243-
</td>
244-
</tr>
260+
<div class="search-main">
261+
{{template "sidebar" .}}
262+
<div class="container-fluid container-results">
263+
<h5>
264+
{{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
265+
{{ $fileCount := len .FileMatches }}
266+
Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
267+
showing top {{ $fileCount }} files (<a rel="nofollow"
268+
href="search?q={{.Last.Query}}&num={{More .Last.Num}}">show more</a>).
269+
{{else}}.{{end}}
270+
</h5>
271+
{{range .FileMatches}}
272+
<table class="table table-hover table-condensed">
273+
<thead>
274+
<tr>
275+
<th>
276+
{{if .URL}}<a name="{{.ResultID}}" class="result"></a><a href="{{.URL}}" >{{else}}<a name="{{.ResultID}}">{{end}}
277+
<small>
278+
{{.Repo}}:{{.FileName}}</a>:
279+
<span style="font-weight: normal">[ {{if .Branches}}{{range .Branches}}<span class="label label-default">{{.}}</span>,{{end}}{{end}} ]</span>
280+
{{if .Language}}<button
281+
title="restrict search to files written in {{.Language}}"
282+
onclick="zoektAddQ('lang:{{.Language}}')" class="label label-primary">language {{.Language}}</button></span>{{end}}
283+
{{if .DuplicateID}}<a class="label label-dup" href="#{{.DuplicateID}}">Duplicate result</a>{{end}}
284+
</small>
285+
</th>
286+
</tr>
287+
</thead>
288+
{{if not .DuplicateID}}
289+
<tbody>
290+
{{range .Matches}}
291+
<tr>
292+
<td style="background-color: rgba(238, 238, 255, 0.6);">
293+
<pre class="inline-pre"><span class="noselect">{{if .URL}}<a href="{{.URL}}">{{end}}<u>{{.LineNum}}</u>{{if .URL}}</a>{{end}}: </span>{{range .Fragments}}{{LimitPre 100 .Pre}}<b>{{.Match}}</b>{{LimitPost 100 .Post}}{{end}}</pre>
294+
</td>
295+
</tr>
296+
{{end}}
297+
</tbody>
245298
{{end}}
246-
</tbody>
299+
</table>
247300
{{end}}
248-
</table>
249-
{{end}}
250301
302+
</div>
303+
</div>
251304
<nav class="navbar navbar-default navbar-bottom">
252305
<div class="container">
253306
{{template "footerBoilerplate"}}
@@ -262,12 +315,48 @@ var TemplateText = map[string]string{
262315
</p>
263316
</div>
264317
</nav>
265-
</div>
266318
{{ template "jsdep"}}
267319
</body>
268320
</html>
269321
`,
270-
322+
"sidebar": `
323+
<div class="container-sidebar">
324+
<div id="sidebar-repositories">
325+
<p class="sidebar-title">Repositories<p>
326+
{{range $key, $value := Repos .FileMatches}}
327+
<div class="sidebar-repo-info">
328+
<div>
329+
{{if IsRepoFilterChecked $.QueryStr $key}}
330+
<input type="checkbox" checked onclick="addFilter('r:{{$key}}')"/>
331+
{{else}}
332+
<input type="checkbox" onclick="addFilter('r:{{$key}}')"/>
333+
{{end}}
334+
{{$key}}
335+
</div>
336+
<div class="badge badge-pill">{{$value}}</div>
337+
</div>
338+
{{end}}
339+
<hr/>
340+
</div>
341+
<div id="sidebar-languages">
342+
<p class="sidebar-title">Languages<p>
343+
{{range $key, $value := Languages .FileMatches}}
344+
<div class="sidebar-repo-info">
345+
<div>
346+
{{if IsLangFilterChecked $.QueryStr $key}}
347+
<input type="checkbox" checked onclick="addFilter('lang:{{$key}}')"/>
348+
{{else}}
349+
<input type="checkbox" onclick="addFilter('lang:{{$key}}')"/>
350+
{{end}}
351+
{{$key}}
352+
</div>
353+
<div class="badge badge-pill">{{$value}}</div>
354+
</div>
355+
{{end}}
356+
<hr/>
357+
</div>
358+
</div>
359+
`,
271360
"repolist": `
272361
<html>
273362
{{template "head"}}

0 commit comments

Comments
 (0)