blob: 03c8e4ddd0efa269c67be12facdb95381f1a9427 [file] [log] [blame]
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package web
import (
"html/template"
"log"
)
// Top provides the standard templates in parsed form
var Top = template.New("top").Funcs(Funcmap)
// TemplateText contains the text of the standard templates.
var TemplateText = map[string]string{
"didyoumean": `<html>
<head>
<title>Error</title>
</head>
<body>
<p>{{.Message}}. Did you mean <a href="/search?q={{.Suggestion}}">{{.Suggestion}}</a> ?
</body>
</html>
`,
// the template for the search box.
"searchbox": `
<form action="search">
Search some code: <input
autofocus
onfocus="this.value = this.value;"
{{if .Query}}value={{.Query}}
{{end}}type="text" name="q"> Max results: <input style="width: 5em;" type="text" name="num" value="{{.Num}}"> <input type="submit" value="Search">
</form>
`,
// search box for the entry page.
"search": `<html>
<head>
<style>
dt {
font-family: monospace;
}
</style>
</head>
<title>Zoekt, en gij zult spinazie eten</title>
<body>
<div style="margin: 3em; padding 3em; position: center;">
{{template "searchbox" .Last}}
</div>
<div style="display: flex; justify-content: space-around; flex-direction: row;">
<div>
Search examples:
<div style="margin-left: 4em;">
<dl>
<dt><a href="search?q=needle">needle</a></dt><dd>search for "needle"
</dd>
<dt><a href="search?q=thread+or+needle">thread or needle</a></dt><dd>search for either "thread" or "needle"
</dd>
<dt><a href="search?q=class+needle">class needle</a></dt><dd>search for files containing both "class" and "needle"
</dd>
<dt><a href="search?q=class+Needle">class Needle</a></dt><dd>search for files containing both "class" (case insensitive) and "Needle" (case sensitive)
</dd>
<dt><a href="search?q=class+Needle+case:yes">class Needle case:yes</a></dt><dd>search for files containing "class" and "Needle", both case sensitively
</dd>
<dt><a href="search?q=%22class Needle%22">"class Needle"</a></dt><dd>search for files with the phrase "class Needle"
</dd>
<dt><a href="search?q=needle+-hay">needle -hay</a></dt><dd>search for files with the word "needle" but not the word "hay"
</dd>
<dt><a href="search?q=path+file:java">path file:java</a></dt><dd>search for the word "path" in files whose name contains "java"
</dd>
<dt><a href="search?q=f:%5C.c%24">f:\.c$</a></dt><dd>search for files whose name ends with ".c"
</dd>
<dt><a href="search?q=path+-file:java">path -file:java</a></dt><dd>search for the word "path" excluding files whose name contains "java"</dd>
<dt><a href="search?q=foo.*bar">foo.*bar</a></dt><dd>search for the regular expression "foo.*bar"</dd>
<dt><a href="search?q=-%28Path File%29 Stream">-(Path File) Stream</a></dt><dd>search "Stream", but exclude files containing both "Path" and "File"</dd>
<dt><a href="search?q=-Path%5c+file+Stream">-Path\ file Stream</a></dt><dd>search "Stream", but exclude files containing "Path File"</dd>
<dt><a href="search?q=phone+r:doid">phone r:droid</a></dt><dd>search for "phone" in repositories whose name contains "droid"</dd>
<dt><a href="search?q=phone+b:aster">phone b:aster</a></dt><dd>for Git repos, find "phone" in files in branches whose name contains "aster".</dd>
<dt><a href="search?q=phone+b:HEAD">phone b:HEAD</a></dt><dd>for Git repos, find "phone" in the default ('HEAD') branch.</dd>
</dl>
</div>
</div>
<div>
<p>
Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.
<p>
To list repositories, try:
<div style="margin-left: 4em;">
<dl>
<dt><a href="search?q=r:droid">r:droid</a></dt><dd>list repositories whose name contains "droid".</dd>
<dt><a href="search?q=r:go+-r:google">r:go -r:google</a></dt><dd>list repositories whose name contains "go" but not "google".</dd>
</dl>
</div>
</p>
</div>
</div>
<hr>
<div>
<a href="about">About</a>
</div>
</body>
</html>
`,
"results": `<html>
<head>
<title>Results for {{.QueryStr}}</title>
</head>
<body>
{{template "searchbox" .Last}}
<hr>
{{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files ({{.Stats.NgramMatches}} ngram matches,
{{.Stats.FilesConsidered}} docs considered, {{.Stats.FilesLoaded}} docs ({{HumanUnit .Stats.BytesLoaded}}B) loaded,
{{.Stats.FilesSkipped}} docs skipped): for
<pre style="background: #ffc;">{{.Query}} with options {{.SearchOptions}}</pre>
in {{.Stats.Duration}} (queued: {{.Stats.Wait}})
<p>
{{range .FileMatches}}
{{if .URL}}<a href="{{.URL}}">{{end}}
<tt><b>{{.Repo}}</b>:<b>{{.FileName}}</b>{{if .URL}}</a>{{end}}:{{if .Branches}}<small>[{{range .Branches}}{{.}}, {{end}}]</small>{{end}} </tt>
<div style="background: #eef;">
{{range .Matches}}
<pre>{{if .URL}}<a href="{{.URL}}">{{end}}{{.LineNum}}{{if .URL}}</a>{{end}}: {{range .Fragments}}{{.Pre}}<b>{{.Match}}</b>{{.Post}}{{end}}</pre>
{{end}}
</div>
{{end}}
</body>
</html>
`,
"repolist": `<html>
<head>
<title>Repo search result for {{.Last.Query}}</title>
</head>
<body>
{{template "searchbox" .Last}}
<hr>
Found {{.RepoCount}} repositories:
<p>
{{range .Repos}}
<li>
<tt>{{if .URL}}<a href="{{.URL}}">{{end}}{{.Name}}{{if .URL}}</a>{{end}}
</tt> (<small>{{.IndexTime.Format "Jan 02, 2006 15:04"}}</small>). Branches:
{{range .Branches}}
{{if .URL}}<a href="{{.URL}}">{{end}}{{.Name}}{{if .URL}}</a>{{end}},
{{end}}
<small>{{HumanUnit .Files}} files ({{HumanUnit .Size}})</small>
</li>
{{end}}
</ul>
</body>
</html>
`,
"print": `
<html>
<head>
<title>{{.Repo}}:{{.Name}}</title>
</head>
<body>{{template "searchbox" .Last}}
<hr>
<p>
<tt>{{.Repo}} : {{.Name}}</tt>
</p>
<div style="background: #eef;">
<pre>{{.Content}}
</pre>
</div>
</body>
</html>
`,
"about": `
<head>
<title>About <em>zoekt</em></title>
</head>
<body>
<p>
This is <a href="http://github.com/google/zoekt"><em>zoekt</em></a>,
an open-source full text search engine.
</p>
<p>
Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.
</p>
<p>
{{if .Version}}<em>Zoekt</em> version {{.Version}}, uptime{{else}}Uptime{{end}} {{.Uptime}}
</p>
`,
}
func init() {
for k, v := range TemplateText {
_, err := Top.New(k).Parse(v)
if err != nil {
log.Panicf("parse(%s): %v:", k, err)
}
}
}