internal/web: move SrcBreadcrumb SrcPkgLink, invoke into templates
There's no real need for these to be written in Go.
Change-Id: Ifb3ebc99a06bb9670a39238a1ddf370c2dcd6a22
Reviewed-on: https://go-review.googlesource.com/c/website/+/339402
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/_content/lib/godoc/example.html b/_content/lib/godoc/example.html
deleted file mode 100644
index be4d1b1..0000000
--- a/_content/lib/godoc/example.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{{with .Data}}
-<div id="example_{{.Name}}" class="toggle">
- <div class="collapsed">
- <p class="exampleHeading toggleButton">▹ <span class="text">Example{{.Page.ExampleSuffix .Name}}</span></p>
- </div>
- <div class="expanded">
- <p class="exampleHeading toggleButton">▾ <span class="text">Example{{.Page.ExampleSuffix .Name}}</span></p>
- {{with .Doc}}<p>{{.}}</p>{{end}}
- {{$output := .Output}}
- {{with .Play}}
- <div class="play">
- <div class="input"><textarea class="code" spellcheck="false">{{.}}</textarea></div>
- <div class="output"><pre>{{html $output}}</pre></div>
- <div class="buttons">
- <button class="Button Button--primary run" title="Run this code [shift-enter]">Run</button>
- <button class="Button fmt" title="Format this code">Format</button>
- {{if not $.GoogleCN}}
- <button class="Button share" title="Share this code">Share</button>
- {{end}}
- </div>
- </div>
- {{else}}
- <p>Code:</p>
- <pre class="code">{{.Code}}</pre>
- {{with .Output}}
- <p>Output:</p>
- <pre class="output">{{.}}</pre>
- {{end}}
- {{end}}
- </div>
-</div>
-{{end}}
diff --git a/_content/lib/godoc/package.html b/_content/lib/godoc/package.html
index 9189dcc..e2cbd4d 100644
--- a/_content/lib/godoc/package.html
+++ b/_content/lib/godoc/package.html
@@ -39,7 +39,7 @@
<div class="expanded">
<h2 class="toggleButton" title="Click to hide Overview section">Overview ▾</h2>
{{$pkg.Comment .Doc}}
- {{range $pkg.FmtExamples ""}}{{$.Invoke "example.html" .}}{{end}}
+ {{range $pkg.FmtExamples ""}}{{template "example" .}}{{end}}
</div>
</div>
@@ -126,7 +126,7 @@
</h2>
<pre>{{$pkg.Node .Decl}}</pre>
{{$pkg.Comment .Doc}}
- {{range $pkg.FmtExamples .Name}}{{$.Invoke "example.html" .}}{{end}}
+ {{range $pkg.FmtExamples .Name}}{{template "example" .}}{{end}}
{{end}}
{{range .Types}}
{{$typeName := .Name}}
@@ -148,7 +148,7 @@
<pre>{{$pkg.Node .Decl}}</pre>
{{end}}
- {{range $pkg.FmtExamples .Name}}{{$.Invoke "example.html" .}}{{end}}
+ {{range $pkg.FmtExamples .Name}}{{template "example" .}}{{end}}
{{range .Funcs}}
<h3 id="{{.Name}}">func <a href="{{$pkg.SrcPosLink .Decl}}">{{.Name}}</a>
@@ -158,7 +158,7 @@
</h3>
<pre>{{$pkg.Node .Decl}}</pre>
{{$pkg.Comment .Doc}}
- {{range $pkg.FmtExamples .Name}}{{$.Invoke "example.html" .}}{{end}}
+ {{range $pkg.FmtExamples .Name}}{{template "example" .}}{{end}}
{{end}}
{{range .Methods}}
@@ -169,7 +169,7 @@
</h3>
<pre>{{$pkg.Node .Decl}}</pre>
{{$pkg.Comment .Doc}}
- {{range $pkg.FmtExamples (printf "%s_%s" $typeName .Name)}}{{$.Invoke "example.html" .}}{{end}}
+ {{range $pkg.FmtExamples (printf "%s_%s" $typeName .Name)}}{{template "example" .}}{{end}}
{{end}}
{{end}}
{{end}}
@@ -211,7 +211,7 @@
</td>
{{end}}
{{else}}
- <td class="pkg-name" style="padding-left: {{multiply .Depth 20}}px;">
+ <td class="pkg-name" style="padding-left: {{mul .Depth 20}}px;">
<a href="{{.Path}}/{{$pkg.ModeQuery}}">{{.Name}}</a>
</td>
{{end}}
@@ -223,3 +223,36 @@
</table>
</div>
{{end}}
+
+{{define "example"}}
+<div id="example_{{.Name}}" class="toggle">
+ <div class="collapsed">
+ <p class="exampleHeading toggleButton">▹ <span class="text">Example{{.Page.ExampleSuffix .Name}}</span></p>
+ </div>
+ <div class="expanded">
+ <p class="exampleHeading toggleButton">▾ <span class="text">Example{{.Page.ExampleSuffix .Name}}</span></p>
+ {{with .Doc}}<p>{{.}}</p>{{end}}
+ {{$output := .Output}}
+ {{with .Play}}
+ <div class="play">
+ <div class="input"><textarea class="code" spellcheck="false">{{.}}</textarea></div>
+ <div class="output"><pre>{{html $output}}</pre></div>
+ <div class="buttons">
+ <button class="Button Button--primary run" title="Run this code [shift-enter]">Run</button>
+ <button class="Button fmt" title="Format this code">Format</button>
+ {{if not $.Page.Web.GoogleCN}}
+ <button class="Button share" title="Share this code">Share</button>
+ {{end}}
+ </div>
+ </div>
+ {{else}}
+ <p>Code:</p>
+ <pre class="code">{{.Code}}</pre>
+ {{with .Output}}
+ <p>Output:</p>
+ <pre class="output">{{.}}</pre>
+ {{end}}
+ {{end}}
+ </div>
+</div>
+{{end}}
diff --git a/_content/lib/godoc/packageroot.html b/_content/lib/godoc/packageroot.html
index e2041b9..aaa2c53 100644
--- a/_content/lib/godoc/packageroot.html
+++ b/_content/lib/godoc/packageroot.html
@@ -48,7 +48,7 @@
</td>
{{end}}
{{else}}
- <td class="pkg-name" style="padding-left: {{multiply .Depth 20}}px;">
+ <td class="pkg-name" style="padding-left: {{mul .Depth 20}}px;">
<a href="{{.Path}}/{{$pkg.ModeQuery}}">{{.Name}}</a>
</td>
{{end}}
diff --git a/_content/lib/godoc/site.html b/_content/lib/godoc/site.html
index 2f3e496..09624be 100644
--- a/_content/lib/godoc/site.html
+++ b/_content/lib/godoc/site.html
@@ -61,10 +61,22 @@
<main id="page" class="Site-content{{if .Title}} wide{{end}}">
<div class="container">
+{{define "srcBreadcrumb"}}
+ {{$elems := split . "/"}}
+ {{$prefix := slice $elems 0 (sub (len $elems) 1)}}
+ {{if hasSuffix . "/"}}
+ {{$prefix = slice $elems 0 (sub (len $elems) 2)}}
+ {{end}}
+ {{range $i, $elem := $prefix -}}
+ <a href="/{{join (slice $prefix 0 (add $i 1)) "/"}}">{{$elem}}</a>/
+ {{- end -}}
+ <span class="text-muted">{{join (slice $elems (len $prefix) (len $elems)) "/"}} {{len $prefix}} {{len $elems}}</span>
+{{end}}
+
{{if or .Title .SrcPath}}
<h1>
{{.Title}}
- {{$.SrcBreadcrumb}}
+ {{template "srcBreadcrumb" .SrcPath}}
</h1>
{{end}}
@@ -72,9 +84,15 @@
<h2>{{.}}</h2>
{{end}}
-{{with .SrcPath}}
+{{if hasPrefix .SrcPath "src/"}}
<h2>
- Documentation: {{$.SrcPkgLink}}
+ Documentation:
+ {{$path := trimPrefix .SrcPath "src/"}}
+ {{if $path}}
+ <a href="/pkg/{{$path}}">{{$path}}</a>
+ {{else}}
+ <a href="/pkg">Index</a>
+ {{end}}
</h2>
{{end}}
@@ -82,11 +100,7 @@
Do not delete this <div>. */}}
<div id="nav"></div>
-{{if .Template}}
-{{.Invoke .Template .Data}}
-{{else}}
-{{.Data}}
-{{end}}
+{{.HTML}}
</div><!-- .container -->
</main><!-- #page -->
diff --git a/internal/web/site.go b/internal/web/site.go
index c4d9a30..4d57ab7 100644
--- a/internal/web/site.go
+++ b/internal/web/site.go
@@ -40,6 +40,22 @@
docFuncs template.FuncMap
}
+var siteFuncs = template.FuncMap{
+ "add": func(a, b int) int { return a + b },
+ "sub": func(a, b int) int { return a - b },
+ "mul": func(a, b int) int { return a * b },
+ "div": func(a, b int) int { return a / b },
+
+ "basename": path.Base,
+
+ "split": strings.Split,
+ "join": strings.Join,
+ "hasPrefix": strings.HasPrefix,
+ "hasSuffix": strings.HasSuffix,
+ "trimPrefix": strings.TrimPrefix,
+ "trimSuffix": strings.TrimSuffix,
+}
+
// NewSite returns a new Presentation from a file system.
func NewSite(fsys fs.FS) (*Site, error) {
p := &Site{
@@ -80,6 +96,18 @@
if d, ok := page.Data.(interface{ SetWebPage(*Page) }); ok {
d.SetWebPage(&page)
}
+
+ if page.Template != "" {
+ t := s.Templates.Lookup(page.Template)
+ var buf bytes.Buffer
+ if err := t.Execute(&buf, &page); err != nil {
+ log.Printf("%s.Execute: %s", t.Name(), err)
+ }
+ page.HTML = template.HTML(buf.String())
+ } else {
+ page.HTML = page.Data.(template.HTML)
+ }
+
applyTemplateToResponseWriter(w, s.Templates.Lookup("site.html"), &page)
}
@@ -106,6 +134,8 @@
Template string // template to apply to data (empty string when Data is raw template.HTML)
Data interface{} // data to be rendered into page frame
+ HTML template.HTML
+
// Filled in automatically by ServePage
GoogleCN bool // served on golang.google.cn
GoogleAnalytics string // Google Analytics tag
@@ -125,19 +155,6 @@
return page
}
-// Invoke invokes the template with the given name on
-// a copy of p with .Data set to data, returning the resulting HTML.
-func (p *Page) Invoke(name string, data interface{}) template.HTML {
- t := p.Site.Templates.Lookup(name)
- var buf bytes.Buffer
- p1 := *p
- p1.Data = data
- if err := t.Execute(&buf, &p1); err != nil {
- log.Printf("%s.Execute: %s", t.Name(), err)
- }
- return template.HTML(buf.String())
-}
-
type writeErrorSaver struct {
w io.Writer
err error
@@ -328,10 +345,11 @@
}
}
+ dirpath := strings.TrimSuffix(relpath, "/") + "/"
s.ServePage(w, r, Page{
Title: "Directory",
- SrcPath: relpath,
- TabTitle: relpath,
+ SrcPath: dirpath,
+ TabTitle: dirpath,
Template: "dirlist.html",
Data: info,
})
diff --git a/internal/web/sitefuncs.go b/internal/web/sitefuncs.go
deleted file mode 100644
index 747973b..0000000
--- a/internal/web/sitefuncs.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package web
-
-import (
- "bytes"
- "fmt"
- "html"
- "path"
- "strings"
-
- "golang.org/x/website/internal/backport/html/template"
-)
-
-var siteFuncs = template.FuncMap{
- // various helpers
- "basename": path.Base,
-
- // Number operation
- "multiply": func(a, b int) int { return a * b },
-}
-
-func srcToPkg(path string) string {
- // because of the irregular mapping under goroot
- // we need to correct certain relative paths
- path = strings.TrimPrefix(path, "/")
- path = strings.TrimPrefix(path, "src/")
- path = strings.TrimPrefix(path, "pkg/")
- return "pkg/" + path
-}
-
-// SrcPkgLink builds an <a> tag linking to the package documentation
-// for p.SrcPath.
-func (p *Page) SrcPkgLink() template.HTML {
- dir := path.Dir(srcToPkg(p.SrcPath))
- if dir == "pkg" {
- return `<a href="/pkg">Index</a>`
- }
- dir = html.EscapeString(dir)
- return template.HTML(fmt.Sprintf(`<a href="/%s">%s</a>`, dir, dir[len("pkg/"):]))
-}
-
-// SrcBreadcrumb converts each segment of p.SrcPath to a HTML <a>.
-// Each segment links to its corresponding src directories.
-func (p *Page) SrcBreadcrumb() template.HTML {
- segments := strings.Split(p.SrcPath, "/")
- var buf bytes.Buffer
- var selectedSegment string
- var selectedIndex int
-
- if strings.HasSuffix(p.SrcPath, "/") {
- // relpath is a directory ending with a "/".
- // Selected segment is the segment before the last slash.
- selectedIndex = len(segments) - 2
- selectedSegment = segments[selectedIndex] + "/"
- } else {
- selectedIndex = len(segments) - 1
- selectedSegment = segments[selectedIndex]
- }
-
- for i := range segments[:selectedIndex] {
- buf.WriteString(fmt.Sprintf(`<a href="/%s">%s</a>/`,
- html.EscapeString(strings.Join(segments[:i+1], "/")),
- html.EscapeString(segments[i]),
- ))
- }
-
- buf.WriteString(`<span class="text-muted">`)
- buf.WriteString(html.EscapeString(selectedSegment))
- buf.WriteString(`</span>`)
- return template.HTML(buf.String())
-}
diff --git a/internal/web/template_test.go b/internal/web/template_test.go
deleted file mode 100644
index 0c8371a..0000000
--- a/internal/web/template_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package web
-
-import (
- "testing"
-
- "golang.org/x/website/internal/backport/html/template"
-)
-
-func TestSrcToPkg(t *testing.T) {
- for _, tc := range []struct {
- path string
- want string
- }{
- {"/src/fmt", "pkg/fmt"},
- {"src/fmt", "pkg/fmt"},
- {"/fmt", "pkg/fmt"},
- {"fmt", "pkg/fmt"},
- {"src/pkg/fmt", "pkg/fmt"},
- {"/src/pkg/fmt", "pkg/fmt"},
- } {
- if got := srcToPkg(tc.path); got != tc.want {
- t.Errorf("srcToPkg(%v) = %v; want %v", tc.path, got, tc.want)
- }
- }
-}
-
-func TestSrcBreadcrumbFunc(t *testing.T) {
- for _, tc := range []struct {
- path string
- want template.HTML
- }{
- {"src/", `<span class="text-muted">src/</span>`},
- {"src/fmt/", `<a href="/src">src</a>/<span class="text-muted">fmt/</span>`},
- {"src/fmt/print.go", `<a href="/src">src</a>/<a href="/src/fmt">fmt</a>/<span class="text-muted">print.go</span>`},
- } {
- if got := (&Page{SrcPath: tc.path}).SrcBreadcrumb(); got != tc.want {
- t.Errorf("srcBreadcrumbFunc(%v) = %v; want %v", tc.path, got, tc.want)
- }
- }
-}
-
-func TestSrcPkgLink(t *testing.T) {
- for _, tc := range []struct {
- path string
- want template.HTML
- }{
- {"src/", `<a href="/pkg">Index</a>`},
- {"src/fmt/", `<a href="/pkg/fmt">fmt</a>`},
- {"pkg/", `<a href="/pkg">Index</a>`},
- {"pkg/LICENSE", `<a href="/pkg">Index</a>`},
- } {
- if got := (&Page{SrcPath: tc.path}).SrcPkgLink(); got != tc.want {
- t.Errorf("srcToPkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
- }
- }
-}