Skip to content

Commit

Permalink
internal/frontend: display godoc links
Browse files Browse the repository at this point in the history
Display the links from the godoc "Links" section in the right sidebar.

For golang/go#42968

Change-Id: Ibf21a74133e10ed4c7b5a310e85999f590938c6a
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/274958
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
  • Loading branch information
jba committed Dec 3, 2020
1 parent 01700ac commit f800db3
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 149 deletions.
10 changes: 0 additions & 10 deletions content/static/html/doc/links.tmpl

This file was deleted.

4 changes: 4 additions & 0 deletions content/static/html/helpers/_unit_meta.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@
<div class="UnitMeta-repo">{{.Body}}</div>
<a href="{{.Href}}" title="{{.Href}}" target="_blank" rel="noopener">{{.Href}}</a>
{{end}}
{{range .Details.DocLinks}}
<div class="UnitMeta-repo">{{.Body}}</div>
<a href="{{.Href}}" title="{{.Href}}" target="_blank" rel="noopener">{{.Href}}</a>
{{end}}
</div>
{{end}}
7 changes: 6 additions & 1 deletion internal/frontend/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,16 @@ func TestServer(t *testing.T) {
name: "links",
urlPath: "/github.com/links/pkg",
wantStatusCode: http.StatusOK,
// There is one div before the actual links appear, hence
// the numbers are off by one.
want: in(".UnitMeta",
in("div:nth-of-type(3)", hasText("title1")),
in("a:nth-of-type(2)", href("http://url1"), hasText("http://url1")),
in("div:nth-of-type(4)", hasText("title2")),
in("a:nth-of-type(3)", href("about:invalid#zGoSafez"), hasText("javascript://pwned"))),
in("a:nth-of-type(3)", href("about:invalid#zGoSafez"), hasText("javascript://pwned")),
in("div:nth-of-type(5)", hasText("pkg.go.dev")),
in("a:nth-of-type(4)", href("https://pkg.go.dev"), hasText("https://pkg.go.dev")),
),
})
},
experiments: []string{internal.ExperimentReadmeOutline, internal.ExperimentGoldmark},
Expand Down
21 changes: 15 additions & 6 deletions internal/frontend/unit_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ type MainDetails struct {
// and are displayed on the right sidebar.
ReadmeLinks []link

// DocLinks are from the "Links" section of the Go package documentation,
// and are displayed on the right sidebar.
DocLinks []link

// ImportedByCount is the number of packages that import this path.
// When the count is > limit it will read as 'limit+'. This field
// is not supported when using a datasource proxy.
Expand Down Expand Up @@ -123,8 +127,9 @@ func fetchMainDetails(ctx context.Context, ds internal.DataSource, um *internal.
return nil, err
}
var (
parts = &dochtml.Parts{}
files []*File
docParts = &dochtml.Parts{}
docLinks []link
files []*File
)
if unit.Documentation != nil {
end := middleware.ElapsedStat(ctx, "DecodePackage")
Expand All @@ -139,11 +144,14 @@ func fetchMainDetails(ctx context.Context, ds internal.DataSource, um *internal.
}
return nil, err
}
parts, err = getHTML(ctx, unit, docPkg)
docParts, err = getHTML(ctx, unit, docPkg)
// If err is ErrTooLarge, then docBody will have an appropriate message.
if err != nil && !errors.Is(err, dochtml.ErrTooLarge) {
return nil, err
}
for _, l := range docParts.Links {
docLinks = append(docLinks, link{Href: l.Href, Body: l.Text})
}
end = middleware.ElapsedStat(ctx, "sourceFiles")
files = sourceFiles(unit, docPkg)
end()
Expand All @@ -157,12 +165,13 @@ func fetchMainDetails(ctx context.Context, ds internal.DataSource, um *internal.
Readme: readme.HTML,
ReadmeOutline: readme.Outline,
ReadmeLinks: readme.Links,
DocOutline: parts.Outline,
DocBody: parts.Body,
DocLinks: docLinks,
DocOutline: docParts.Outline,
DocBody: docParts.Body,
SourceFiles: files,
RepositoryURL: um.SourceInfo.RepoURL(),
SourceURL: um.SourceInfo.DirectoryURL(internal.Suffix(um.Path, um.ModulePath)),
MobileOutline: parts.MobileOutline,
MobileOutline: docParts.MobileOutline,
NumImports: unit.NumImports,
ImportedByCount: importedByCount,
IsPackage: unit.IsPackage(),
Expand Down
16 changes: 7 additions & 9 deletions internal/godoc/dochtml/dochtml.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ type templateData struct {
*doc.Package
Examples *examples
NoteHeaders map[string]noteHeader
Links func() []render.Link
}

// Render renders package documentation HTML for the
Expand All @@ -84,7 +83,7 @@ func Render(ctx context.Context, fset *token.FileSet, p *doc.Package, opt Render
opt.Limit = 10 * megabyte
}

funcs, data := renderInfo(ctx, fset, p, opt)
funcs, data, _ := renderInfo(ctx, fset, p, opt)
p = data.Package
if p.Doc == "" &&
len(p.Examples) == 0 &&
Expand All @@ -103,7 +102,7 @@ type Parts struct {
Body safehtml.HTML // main body of doc
Outline safehtml.HTML // outline for large screens
MobileOutline safehtml.HTML // outline for mobile
Links safehtml.HTML // "Links" section of package doc
Links []render.Link // "Links" section of package doc
}

// Render renders package documentation HTML for the
Expand All @@ -119,7 +118,7 @@ func RenderParts(ctx context.Context, fset *token.FileSet, p *doc.Package, opt R
opt.Limit = 10 * megabyte
}

funcs, data := renderInfo(ctx, fset, p, opt)
funcs, data, links := renderInfo(ctx, fset, p, opt)
p = data.Package
if p.Doc == "" &&
len(p.Examples) == 0 &&
Expand Down Expand Up @@ -156,9 +155,9 @@ func RenderParts(ctx context.Context, fset *token.FileSet, p *doc.Package, opt R
Body: exec("body.tmpl"),
Outline: outline,
MobileOutline: exec("sidenav-mobile.tmpl"),
// Links must be rendered after body, because the call to
// links must be called after body, because the call to
// render_doc_extract_links in body.tmpl creates the links.
Links: exec("links.tmpl"),
Links: links(),
}
if err != nil {
return nil, err
Expand All @@ -167,7 +166,7 @@ func RenderParts(ctx context.Context, fset *token.FileSet, p *doc.Package, opt R
}

// renderInfo returns the functions and data needed to render the doc.
func renderInfo(ctx context.Context, fset *token.FileSet, p *doc.Package, opt RenderOptions) (map[string]interface{}, templateData) {
func renderInfo(ctx context.Context, fset *token.FileSet, p *doc.Package, opt RenderOptions) (map[string]interface{}, templateData, func() []render.Link) {
// Make a copy to avoid modifying caller's *doc.Package.
p2 := *p
p = &p2
Expand Down Expand Up @@ -226,9 +225,8 @@ func renderInfo(ctx context.Context, fset *token.FileSet, p *doc.Package, opt Re
Package: p,
Examples: collectExamples(p),
NoteHeaders: buildNoteHeaders(p.Notes),
Links: r.Links,
}
return funcs, data
return funcs, data, r.Links
}

// executeToHTMLWithLimit executes tmpl on data and returns the result as a safehtml.HTML.
Expand Down
16 changes: 7 additions & 9 deletions internal/godoc/dochtml/dochtml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/safehtml/template"
"golang.org/x/net/html"
"golang.org/x/pkgsite/internal/godoc/dochtml/internal/render"
"golang.org/x/pkgsite/internal/godoc/internal/doc"
"golang.org/x/pkgsite/internal/testing/htmlcheck"
)
Expand Down Expand Up @@ -107,11 +108,6 @@ func TestRenderParts(t *testing.T) {
if err != nil {
t.Fatal(err)
}
links, err := html.Parse(strings.NewReader(parts.Links.String()))
if err != nil {
t.Fatal(err)
}

// Check that there are no duplicate id attributes.
t.Run("duplicate ids", func(t *testing.T) {
testDuplicateIDs(t, bodyDoc)
Expand Down Expand Up @@ -146,10 +142,12 @@ func TestRenderParts(t *testing.T) {
t.Errorf("note check: %v", err)
}

checker = htmlcheck.In(".Documentation-links",
htmlcheck.In("li", htmlcheck.In("a", htmlcheck.HasHref("https://go.googlesource.com/pkgsite"), htmlcheck.HasExactText("pkgsite repo"))))
if err := checker(links); err != nil {
t.Errorf("note check: %v", err)
wantLinks := []render.Link{
{Href: "https://go.googlesource.com/pkgsite", Text: "pkgsite repo"},
{Href: "https://play-with-go.dev", Text: "Play with Go"},
}
if diff := cmp.Diff(wantLinks, parts.Links); diff != "" {
t.Errorf("links mismatch (-want, +got):\n%s", diff)
}
}

Expand Down
1 change: 0 additions & 1 deletion internal/godoc/dochtml/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ func LoadTemplates(dir template.TrustedSource) {
join(dir, tc("sidenav.tmpl")),
join(dir, tc("sidenav-mobile.tmpl")),
join(dir, tc("body.tmpl")),
join(dir, tc("links.tmpl")),
example))
})
}
Expand Down
5 changes: 5 additions & 0 deletions internal/godoc/testdata/p/p.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

// Package p is for testing godoc.Render. There are a lot
// of other things to say, but that's the gist of it.
//
//
// Links
//
// - pkg.go.dev, https://pkg.go.dev
package p

import (
Expand Down
Loading

0 comments on commit f800db3

Please sign in to comment.