diff options
| author | Russ Cox <rsc@golang.org> | 2021-11-17 15:57:04 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2021-11-22 16:40:01 +0000 |
| commit | cecdbb6e8ed6cf33babe1e9217a00197a4845765 (patch) | |
| tree | 9cb1e3af7d30ec2fa4fb9eb5dddf9e97dec33107 | |
| parent | 961523a99713328508cc63167192db63311e474b (diff) | |
| download | go-x-website-cecdbb6e8ed6cf33babe1e9217a00197a4845765.tar.xz | |
website: merge golang.org → go.dev
As described in https://go.dev/blog/tidy-web,
redirect golang.org to go.dev.
The golang.org home page is retired -
go.dev now has all the same info and links,
and it doesn't have ten-year-old videos of me.
All the other golang.org pages are now served
directly from go.dev, styled differently but with
the same content.
A followup CL will merge the _content directories.
Change-Id: Ib7f3d951842c021280981f9b926c4943f4d9cb52
Reviewed-on: https://go-review.googlesource.com/c/website/+/364859
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
27 files changed, 457 insertions, 110 deletions
diff --git a/_content/conduct.html b/_content/conduct.html index 3d15884f..962df2e9 100644 --- a/_content/conduct.html +++ b/_content/conduct.html @@ -1,5 +1,6 @@ <!--{ - "Title": "Go Community Code of Conduct" + "Title": "Go Community Code of Conduct", + "layout": "article" }--> <style> diff --git a/_content/help.html b/_content/help.html index 2b53e44f..2b910d16 100644 --- a/_content/help.html +++ b/_content/help.html @@ -1,6 +1,7 @@ <!--{ "Title": "Help", - "Template": true + "Template": true, + "layout": "article" }--> <div id="manual-nav"></div> diff --git a/_content/project.html b/_content/project.html index 45a71692..de1a10ab 100644 --- a/_content/project.html +++ b/_content/project.html @@ -1,6 +1,7 @@ <!--{ "Title": "The Go Project", - "Template": true + "Template": true, + "layout": "article" }--> <img class="gopher" src="/doc/gopher/project.png" alt="" /> diff --git a/_content/security.html b/_content/security.html index 316cb91c..7238c8b4 100644 --- a/_content/security.html +++ b/_content/security.html @@ -1,5 +1,6 @@ <!--{ - "Title": "Go Security Policy" + "Title": "Go Security Policy", + "layout": "article" }--> <h2 id="overview">Overview</h2> diff --git a/cmd/golangorg/csp.go b/cmd/golangorg/csp.go index a6400b1e..b1c02575 100644 --- a/cmd/golangorg/csp.go +++ b/cmd/golangorg/csp.go @@ -43,7 +43,6 @@ const ( var csp = map[string][]string{ "connect-src": { "'self'", - "https://golang.org", "www.google-analytics.com", "stats.g.doubleclick.net", }, diff --git a/cmd/golangorg/server.go b/cmd/golangorg/server.go index 889e33b4..3e7feccd 100644 --- a/cmd/golangorg/server.go +++ b/cmd/golangorg/server.go @@ -11,10 +11,10 @@ import ( "context" "embed" "encoding/json" + "errors" "flag" "fmt" "go/format" - "io" "io/fs" "io/ioutil" "log" @@ -31,7 +31,6 @@ import ( "cloud.google.com/go/datastore" "golang.org/x/build/repos" - "golang.org/x/tools/playground" "golang.org/x/website" "golang.org/x/website/internal/backport/html/template" "golang.org/x/website/internal/blog" @@ -156,80 +155,87 @@ func NewHandler(contentDir, goroot string) http.Handler { gorootFS = os.DirFS(goroot) } - site, err := newSite(mux, "", golangFS, gorootFS) - if err != nil { - log.Fatalf("newSite: %v", err) - } - chinaSite, err := newSite(mux, "golang.google.cn", golangFS, gorootFS) - if err != nil { - log.Fatalf("newSite: %v", err) - } - // tip.golang.org serves content from the very latest Git commit // of the main Go repo, instead of the one the app is bundled with. + // TODO(rsc): The unionFS is a hack until we move the files in a followup CL. var tipGoroot atomicFS - if _, err := newSite(mux, "tip.golang.org", golangFS, &tipGoroot); err != nil { + if _, err := newSite(mux, "tip.golang.org", unionFS{godevFS, golangFS}, &tipGoroot); err != nil { log.Fatalf("loading tip site: %v", err) } + if *tipFlag { + go watchTip(&tipGoroot) + } // beta.golang.org is an old name for tip. mux.Handle("beta.golang.org/", redirectPrefix("https://tip.golang.org/")) + // By default, golang.org/foo redirects to go.dev/foo. + // There are some exceptions below, like for golang.org/x and golang.org/fmt. + mux.Handle("golang.org/", redirectPrefix("https://go.dev/")) + mux.Handle("blog.golang.org/", redirectPrefix("https://go.dev/blog/")) + mux.Handle("learn.go.dev/", redirectPrefix("https://go.dev/learn/")) + // m.golang.org is an old shortcut for golang.org mail. // Gmail itself can serve this redirect, but only on HTTP (not HTTPS). // Golang.org's HSTS header tells browsers to use HTTPS for all subdomains, // which broke the redirect. mux.Handle("m.golang.org/", http.RedirectHandler("https://mail.google.com/a/golang.org/", http.StatusMovedPermanently)) - if *tipFlag { - go watchTip(&tipGoroot) - } - - mux.Handle("/compile", playground.Proxy()) - mux.Handle("/fmt", http.HandlerFunc(fmtHandler)) - mux.Handle("/x/", http.HandlerFunc(xHandler)) - redirect.Register(mux) - - mux.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "User-agent: *\nDisallow: /search\n") - }) - // Register a redirect handler for tip.golang.org/dl/ to the golang.org download page. // (golang.org/dl and golang.google.cn/dl are registered separately.) - mux.Handle("tip.golang.org/dl/", http.RedirectHandler("https://golang.org/dl/", http.StatusFound)) + mux.Handle("tip.golang.org/dl/", http.RedirectHandler("https://go.dev/dl/", http.StatusFound)) - godevMux := http.NewServeMux() - godevSite, err := newSite(godevMux, "go.dev", godevFS, gorootFS) + // TODO(rsc): The unionFS is a hack until we move the files in a followup CL. + siteMux := http.NewServeMux() + godevSite, err := newSite(siteMux, "", unionFS{godevFS, golangFS}, gorootFS) if err != nil { log.Fatalf("newSite go.dev: %v", err) } - godevMux.Handle("/explore/", http.StripPrefix("/explore/", redirectPrefix("https://pkg.go.dev/"))) - if err := blog.RegisterFeeds(godevMux, "", godevSite); err != nil { + chinaSite, err := newSite(siteMux, "golang.google.cn", unionFS{godevFS, golangFS}, gorootFS) + if err != nil { + log.Fatalf("newSite golang.google.cn: %v", err) + } + siteMux.Handle("/play/", playHandler(godevSite)) + siteMux.Handle("golang.google.cn/play/", playHandler(chinaSite)) + dl.RegisterHandlers(siteMux, godevSite, "", datastoreClient, memcacheClient) + dl.RegisterHandlers(siteMux, chinaSite, "golang.google.cn", datastoreClient, memcacheClient) + mux.Handle("/", siteMux) + + mux.Handle("/explore/", http.StripPrefix("/explore/", redirectPrefix("https://pkg.go.dev/"))) + if err := blog.RegisterFeeds(mux, "", godevSite); err != nil { log.Fatalf("blog: %v", err) } - mux.Handle("go.dev/play", playHandler(godevSite)) - mux.Handle("go.dev/play/p/", playHandler(godevSite)) - mux.Handle("go.dev/", addCSP(godevMux)) - mux.Handle("blog.golang.org/", redirectPrefix("https://go.dev/blog/")) - mux.Handle("learn.go.dev/", redirectPrefix("https://go.dev/learn/")) + // Note: Only golang.org/x/, no go.dev/x/. + mux.Handle("golang.org/x/", http.HandlerFunc(xHandler)) + + redirect.Register(mux) if runningOnAppEngine { - appEngineSetup(site, chinaSite, mux) + appEngineSetup(mux) } + + // Note: Registers for golang.org, go.dev/_, and golang.google.cn. proxy.RegisterHandlers(mux) - dl.RegisterHandlers(mux, site, "golang.org", datastoreClient, memcacheClient) - dl.RegisterHandlers(mux, chinaSite, "golang.google.cn", datastoreClient, memcacheClient) var h http.Handler = mux + h = addCSP(mux) h = hostEnforcerHandler(h) h = hostPathHandler(h) return h } -func playHandler(godevSite *web.Site) http.Handler { +func playHandler(site *web.Site) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - godevSite.ServePage(w, r, web.Page{ + if r.URL.Path == "/play/p" || r.URL.Path == "/play/p/" { + http.Redirect(w, r, "/play/", http.StatusFound) + return + } + if r.Host == "golang.google.cn" && strings.HasPrefix(r.URL.Path, "/play/p/") { + site.ServeError(w, r, errors.New("Sorry, but shared playground snippets are not visible in China.")) + return + } + site.ServePage(w, r, web.Page{ "URL": r.URL.Path, "layout": "play", "title": "Go Playground", @@ -332,7 +338,7 @@ func watchTip1(tipGoroot *atomicFS) { var datastoreClient *datastore.Client var memcacheClient *memcache.Client -func appEngineSetup(site, chinaSite *web.Site, mux *http.ServeMux) { +func appEngineSetup(mux *http.ServeMux) { googleAnalytics = os.Getenv("GOLANGORG_ANALYTICS") ctx := context.Background() @@ -352,7 +358,7 @@ func appEngineSetup(site, chinaSite *web.Site, mux *http.ServeMux) { } memcacheClient = memcache.New(redisAddr) - short.RegisterHandlers(mux, "golang.org", datastoreClient, memcacheClient) + short.RegisterHandlers(mux, "", datastoreClient, memcacheClient) log.Println("AppEngine initialization complete") } @@ -469,7 +475,7 @@ func (r *linkRewriter) WriteHeader(code int) { if strings.HasPrefix(loc, "/") { r.Header().Set("Location", "/"+r.host+loc) } else if u, _ := url.Parse(loc); u != nil && validHosts[u.Host] { - r.Header().Set("Location", "/"+u.Host+"/"+u.Path+u.RawQuery) + r.Header().Set("Location", "/"+u.Host+"/"+strings.TrimPrefix(u.Path, "/")+u.RawQuery) } r.ResponseWriter.WriteHeader(code) } @@ -731,6 +737,10 @@ func (a *atomicFS) Open(name string) (fs.File, error) { func redirectPrefix(prefix string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, strings.TrimSuffix(prefix, "/")+"/"+strings.TrimPrefix(r.URL.Path, "/"), http.StatusMovedPermanently) + url := strings.TrimSuffix(prefix, "/") + "/" + strings.TrimPrefix(r.URL.Path, "/") + if r.URL.RawQuery != "" { + url += "?" + r.URL.RawQuery + } + http.Redirect(w, r, url, http.StatusMovedPermanently) }) } diff --git a/cmd/golangorg/testdata/blog.txt b/cmd/golangorg/testdata/blog.txt index 496cffed..e3cd2616 100644 --- a/cmd/golangorg/testdata/blog.txt +++ b/cmd/golangorg/testdata/blog.txt @@ -2,9 +2,16 @@ GET https://go.dev/blog/ body contains The Go Blog header Content-Type == text/html; charset=utf-8 +GET https://golang.google.cn/blog/ +body contains The Go Blog +header Content-Type == text/html; charset=utf-8 + GET https://go.dev/blog/2010/08/defer-panic-and-recover.html redirect == /blog/defer-panic-and-recover +GET https://golang.google.cn/blog/2010/08/defer-panic-and-recover.html +redirect == /blog/defer-panic-and-recover + GET https://go.dev/blog/upcoming-google-io-go-events redirect == /blog/io2010-preview @@ -23,7 +30,7 @@ GET https://go.dev/blog/gouk15 body contains <img GET https://golang.org/blog/ -redirect == /blog +redirect == https://go.dev/blog/ GET https://golang.org/blog redirect == https://go.dev/blog @@ -31,14 +38,27 @@ redirect == https://go.dev/blog GET https://go.dev/blog redirect == /blog/ +GET https://go.dev/blog/feed.atom +header Content-Type == application/atom+xml; charset=utf-8 +body contains <feed xmlns="http://www.w3.org/2005/Atom"><title>The Go Blog</title> + +GET https://go.dev/blog/.json +header Content-Type == application/json; charset=utf-8 +body contains [{" + +GET https://golang.google.cn/blog/feed.atom +header Content-Type == application/atom+xml; charset=utf-8 +body contains <feed xmlns="http://www.w3.org/2005/Atom"><title>The Go Blog</title> + +GET https://golang.google.cn/blog/.json +header Content-Type == application/json; charset=utf-8 +body contains [{" + GET https://blog.golang.org/ redirect == https://go.dev/blog/ -GET https://go.dev/blog/ -body contains The Go Blog - GET https://blog.golang.org/x -redirect == /x/ +redirect == https://go.dev/blog/x GET https://blog.golang.org/x/ redirect == https://go.dev/blog/x/ @@ -54,7 +74,3 @@ body contains Go 1.16 GET https://blog.golang.org/?googlecn=1 redirect == https://golang.google.cn/?googlecn=1 - -# Do not China-redirect go.dev links, because they will break. -GET https://go.dev/blog/?googlecn=1 -body contains The Go Blog diff --git a/cmd/golangorg/testdata/godev.txt b/cmd/golangorg/testdata/godev.txt index 42b02501..5ea8d15e 100644 --- a/cmd/golangorg/testdata/godev.txt +++ b/cmd/golangorg/testdata/godev.txt @@ -26,7 +26,23 @@ redirect == /solutions/google/sitereliability GET https://go.dev/solutions/americanexpress body contains <div class="Article-date">19 December 2019</div> -GET https://go.dev/play +GET https://go.dev/play/ body contains The Go Playground body contains About the Playground body contains Hello, 世界 + +GET https://golang.google.cn/play/ +body contains The Go Playground +body contains About the Playground +body contains Hello, 世界 + +GET https://go.dev/play/p/asdfasdf +body contains The Go Playground +body contains About the Playground + +GET https://golang.google.cn/play/p/asdfasdf +code == 500 +body contains Sorry, but shared playground snippets are not visible in China. +body !contains The Go Playground +body !contains About the Playground + diff --git a/cmd/golangorg/testdata/release.txt b/cmd/golangorg/testdata/release.txt index fc38347b..ae272a25 100644 --- a/cmd/golangorg/testdata/release.txt +++ b/cmd/golangorg/testdata/release.txt @@ -1,4 +1,4 @@ -GET https://golang.org/doc/devel/release +GET https://go.dev/doc/devel/release header content-type == text/html; charset=utf-8 trimbody contains <h2 id="go1.14">go1.14 (released 2020-02-25)</h2> diff --git a/cmd/golangorg/testdata/web.txt b/cmd/golangorg/testdata/web.txt index 002f2af4..bfc3360f 100644 --- a/cmd/golangorg/testdata/web.txt +++ b/cmd/golangorg/testdata/web.txt @@ -1,93 +1,168 @@ GET https://golang.org/ -body contains Go is an open source programming language -body contains Binary distributions available for +code == 301 +redirect == https://go.dev/ GET http://localhost:6060/ redirect == /golang.org/ -GET http://localhost:6060/golang.org/ +GET http://localhost:6060/go.dev/ body contains Go is an open source programming language -body contains Binary distributions available for -body contains href="/golang.org/doc +body contains Download packages for +body contains href="/go.dev/doc body !contains href="/doc GET https://golang.org/change/75944e2e3a63 +redirect == https://go.dev/change/75944e2e3a63 + +GET https://go.dev/change/75944e2e3a63 code == 302 redirect contains bdb10cf body contains bdb10cf body !contains UA- GET https://golang.org/cmd/compile/internal/amd64/ +redirect == https://go.dev/cmd/compile/internal/amd64/ + +GET https://go.dev/cmd/compile/internal/amd64/ redirect == https://pkg.go.dev/cmd/compile/internal/amd64 GET https://golang.org/cmd/compile/internal/amd64/?m=old +redirect == https://go.dev/cmd/compile/internal/amd64/?m=old + +GET https://go.dev/cmd/compile/internal/amd64/?m=old body contains href="/src/cmd/compile/internal/amd64/ssa.go" GET https://golang.org/conduct +redirect == https://go.dev/conduct + +GET https://go.dev/conduct body contains Project Stewards GET https://golang.org/doc/ +redirect == https://go.dev/doc/ + +GET https://go.dev/doc/ body contains an introduction to using modules in a simple project GET https://golang.org/doc/asm +redirect == https://go.dev/doc/asm + +GET https://go.dev/doc/asm body ~ Quick Guide.*Assembler GET https://golang.org/doc/debugging_with_gdb.html +redirect == https://go.dev/doc/debugging_with_gdb.html + +GET https://go.dev/doc/debugging_with_gdb.html redirect == /doc/gdb GET https://golang.org/doc/devel/release +redirect == https://go.dev/doc/devel/release + +GET https://go.dev/doc/devel/release body ~ go1\.14\.2\s+\(released 2020-04-08\)\s+includes\s+fixes to cgo, the go command, the runtime, GET https://golang.org/doc/devel/release.html +redirect == https://go.dev/doc/devel/release.html + +GET https://go.dev/doc/devel/release.html redirect == /doc/devel/release GET https://golang.org/doc/faq +redirect == https://go.dev/doc/faq + +GET https://go.dev/doc/faq body contains What is the purpose of the project GET https://golang.org/doc/gdb +redirect == https://go.dev/doc/gdb + +GET https://go.dev/doc/gdb body contains Debugging Go Code GET https://golang.org/doc/go1.16.html +redirect == https://go.dev/doc/go1.16.html + +GET https://go.dev/doc/go1.16.html redirect == /doc/go1.16 GET https://golang.org/doc/go1.16 +redirect == https://go.dev/doc/go1.16 + +GET https://go.dev/doc/go1.16 body contains Go 1.16 GET https://golang.org/doc/go_spec +redirect == https://go.dev/doc/go_spec + +GET https://go.dev/doc/go_spec redirect == /ref/spec GET https://golang.org/doc/go_spec.html +redirect == https://go.dev/doc/go_spec.html + +GET https://go.dev/doc/go_spec.html redirect == /ref/spec GET https://golang.org/doc/go_spec.md +redirect == https://go.dev/doc/go_spec.md + +GET https://go.dev/doc/go_spec.md redirect == /ref/spec GET https://golang.org/doc/go_mem.html +redirect == https://go.dev/doc/go_mem.html + +GET https://go.dev/doc/go_mem.html redirect == /ref/mem GET https://golang.org/doc/go_mem.md +redirect == https://go.dev/doc/go_mem.md + +GET https://go.dev/doc/go_mem.md redirect == /ref/mem GET https://golang.org/doc/help.html +redirect == https://go.dev/doc/help.html + +GET https://go.dev/doc/help.html redirect == /help GET https://golang.org/help/ +redirect == https://go.dev/help/ + +GET https://go.dev/help/ redirect == /help GET https://golang.org/help +redirect == https://go.dev/help + +GET https://go.dev/help body contains Get help GET https://golang.org/src/fmt/ +redirect == https://go.dev/src/fmt/ + +GET https://go.dev/src/fmt/ body contains scan_test.go GET https://golang.org/src/fmt/print.go +redirect == https://go.dev/src/fmt/print.go + +GET https://go.dev/src/fmt/print.go body contains // Println formats using body contains <!DOCTYPE html> GET https://golang.org/pkg/fmt/ +redirect == https://go.dev/pkg/fmt/ + +GET https://go.dev/pkg/fmt/ redirect == https://pkg.go.dev/fmt GET https://golang.org/pkg/fmt/?m=old +redirect == https://go.dev/pkg/fmt/?m=old + +GET https://go.dev/pkg/fmt/?m=old body contains Package fmt implements formatted I/O body contains Share this code @@ -96,109 +171,194 @@ body contains Package fmt implements formatted I/O body !contains Share this code GET https://golang.org/pkg +redirect == https://go.dev/pkg + +GET https://go.dev/pkg redirect == /pkg/ GET https://golang.org/pkg/ +redirect == https://go.dev/pkg/ + +GET https://go.dev/pkg/ redirect == https://pkg.go.dev/std GET https://tip.golang.org/pkg/ redirect == https://pkg.go.dev/std@master GET https://tip.golang.org/dl/ -redirect == https://golang.org/dl/ +redirect == https://go.dev/dl/ GET https://golang.org/pkg?m=old +redirect == https://go.dev/pkg?m=old + +GET https://go.dev/pkg?m=old redirect == /pkg/?m=old GET https://golang.org/pkg/?m=old +redirect == https://go.dev/pkg/?m=old + +GET https://go.dev/pkg/?m=old body contains Standard library body contains Package fmt implements formatted I/O body !contains internal/syscall body !contains cmd/gc GET https://golang.org/pkg/?m=old,all +redirect == https://go.dev/pkg/?m=old,all + +GET https://go.dev/pkg/?m=old,all body contains Standard library body contains Package fmt implements formatted I/O body contains internal/syscall/?m=all body !contains cmd/gc GET https://golang.org/pkg/bufio/ +redirect == https://go.dev/pkg/bufio/ + +GET https://go.dev/pkg/bufio/ redirect == https://pkg.go.dev/bufio GET https://golang.org/pkg/bufio/?GOOS=windows&GOARCH=amd64 +redirect == https://go.dev/pkg/bufio/?GOOS=windows&GOARCH=amd64 + +GET https://go.dev/pkg/bufio/?GOOS=windows&GOARCH=amd64 redirect == https://pkg.go.dev/bufio?GOOS=windows&GOARCH=amd64 GET https://tip.golang.org/pkg/bufio/ redirect == https://pkg.go.dev/bufio@master GET https://golang.org/pkg/bufio/?m=old +redirect == https://go.dev/pkg/bufio/?m=old + +GET https://go.dev/pkg/bufio/?m=old body contains href="/pkg/io/?m=old#Writer body !contains href="/pkg/io/#Writer GET https://golang.org/pkg/database/sql/ +redirect == https://go.dev/pkg/database/sql/ + +GET https://go.dev/pkg/database/sql/ redirect == https://pkg.go.dev/database/sql GET https://golang.org/pkg/database/sql/?m=old +redirect == https://go.dev/pkg/database/sql/?m=old + +GET https://go.dev/pkg/database/sql/?m=old body contains The number of connections currently in use; added in Go 1.11 body contains The number of idle connections; added in Go 1.11 GET https://golang.org/pkg/math/bits/ +redirect == https://go.dev/pkg/math/bits/ + +GET https://go.dev/pkg/math/bits/ redirect == https://pkg.go.dev/math/bits GET https://golang.org/pkg/math/bits/?m=old +redirect == https://go.dev/pkg/math/bits/?m=old + +GET https://go.dev/pkg/math/bits/?m=old body contains Added in Go 1.9 GET https://golang.org/pkg/net/ +redirect == https://go.dev/pkg/net/ + +GET https://go.dev/pkg/net/ redirect == https://pkg.go.dev/net GET https://golang.org/pkg/net/?m=old +redirect == https://go.dev/pkg/net/?m=old + +GET https://go.dev/pkg/net/?m=old body contains // IPv6 scoped addressing zone; added in Go 1.1 GET https://golang.org/pkg/net/http/?m=old +redirect == https://go.dev/pkg/net/http/?m=old + +GET https://go.dev/pkg/net/http/?m=old body contains title="Added in Go 1.11" GET https://golang.org/pkg/net/http/httptrace/ +redirect == https://go.dev/pkg/net/http/httptrace/ + +GET https://go.dev/pkg/net/http/httptrace/ redirect == https://pkg.go.dev/net/http/httptrace GET https://golang.org/pkg/net/http/httptrace/?m=old +redirect == https://go.dev/pkg/net/http/httptrace/?m=old + +GET https://go.dev/pkg/net/http/httptrace/?m=old body ~ Got1xxResponse.*// Go 1\.11 body ~ GotFirstResponseByte func\(\)\s*$ GET https://golang.org/pkg/os/?m=old +redirect == https://go.dev/pkg/os/?m=old + +GET https://go.dev/pkg/os/?m=old body contains func Open GET https://golang.org/pkg/strings/ +redirect == https://go.dev/pkg/strings/ + +GET https://go.dev/pkg/strings/ redirect == https://pkg.go.dev/strings GET https://golang.org/pkg/strings/?m=old +redirect == https://go.dev/pkg/strings/?m=old + +GET https://go.dev/pkg/strings/?m=old body contains href="/src/strings/strings.go" GET https://golang.org/project +redirect == https://go.dev/project + +GET https://go.dev/project body contains <li><a href="/doc/go1.14">Go 1.14</a> <small>(February 2020)</small></li> body contains <li><a href="/doc/go1.1">Go 1.1</a> <small>(May 2013)</small></li> GET https://golang.org/project/ +redirect == https://go.dev/project/ + +GET https://go.dev/project/ redirect == /project GET https://golang.org/project/notexist +redirect == https://go.dev/project/notexist + +GET https://go.dev/project/notexist code == 404 GET https://golang.org/ref/mem +redirect == https://go.dev/ref/mem + +GET https://go.dev/ref/mem body contains Memory Model GET https://golang.org/ref/spec +redirect == https://go.dev/ref/spec + +GET https://go.dev/ref/spec body contains Go Programming Language Specification GET https://golang.org/robots.txt -body contains Disallow: /search +redirect == https://go.dev/robots.txt + +GET https://go.dev/robots.txt +body contains User-agent: * body !contains UA- +body !contains <body> GET https://golang.org/x/net code == 200 body contains <meta name="go-import" content="golang.org/x/net git https://go.googlesource.com/net"> body !contains UA- +GET https://go.dev/x/net +code == 404 + GET https://golang.org/pkg/crypto/rsa/?m=old +redirect == https://go.dev/pkg/crypto/rsa/?m=old + +GET https://go.dev/pkg/crypto/rsa/?m=old body contains []byte("orders") body !contains []byte(&#34;orders&#34;) body contains <span class="comment"> @@ -211,26 +371,48 @@ GET https://m.golang.org/anything redirect == https://mail.google.com/a/golang.org/ GET https://golang.org/doc/effective_go +redirect == https://go.dev/doc/effective_go + +GET https://go.dev/doc/effective_go body contains KB ByteSize GET https://golang.org/doc/codewalk/codewalk/ +redirect == https://go.dev/doc/codewalk/codewalk/ + +GET https://go.dev/doc/codewalk/codewalk/ body contains Codewalk: How to Write a Codewalk body contains A codewalk is a guided tour GET https://golang.org/doc/codewalk/ +redirect == https://go.dev/doc/codewalk/ + +GET https://go.dev/doc/codewalk/ body contains Codewalks body contains <td>How to Write a Codewalk</td> GET https://golang.org/ref/mod +redirect == https://go.dev/ref/mod + +GET https://go.dev/ref/mod body contains Controls the set of version control tools GET https://golang.org/asdf +redirect == https://go.dev/asdf + +GET https://go.dev/asdf code == 404 -body ~ <span class="alert" style="font-size:120%">open (../../_content/)?asdf: (.*)</span> +body contains to, err := human() +body ~ <span class="alert" style="font-size:120%">open (..[\\/]..[\\/](go.dev[\\/])?_content[\\/])?asdf: (.*)</span> GET https://golang.org/dl/ +redirect == https://go.dev/dl/ + +GET https://go.dev/dl/ body contains href="/dl/go1.11.windows-amd64.msi" GET https://golang.org/dl/?mode=json +redirect == https://go.dev/dl/?mode=json + +GET https://go.dev/dl/?mode=json body contains .windows-amd64.msi body !contains UA- diff --git a/_content/codewalk.tmpl b/go.dev/_content/codewalk.tmpl index 511a0955..804bfe69 100644 --- a/_content/codewalk.tmpl +++ b/go.dev/_content/codewalk.tmpl @@ -5,6 +5,11 @@ --> {{define "layout"}} + +<article class="Codewalk Article"> + +<h1>{{.title}}</h1> + {{with .codewalk}} <style type='text/css'>@import "/doc/codewalk/codewalk.css";</style> <script type="text/javascript" src="/doc/codewalk/codewalk.js"></script> @@ -57,4 +62,7 @@ </div> </div> {{end}} + +</article> + {{end}} diff --git a/_content/codewalkdir.tmpl b/go.dev/_content/codewalkdir.tmpl index 5912e19d..1815d4d1 100644 --- a/_content/codewalkdir.tmpl +++ b/go.dev/_content/codewalkdir.tmpl @@ -5,6 +5,11 @@ --> {{define "layout"}} + +<article class="Codewalk Article"> + +<h1>{{.title}}</h1> + <table class="layout"> {{range .dirs}} <tr> @@ -14,4 +19,7 @@ </tr> {{end}} </table> + +</article> + {{end}} diff --git a/go.dev/_content/css/styles.css b/go.dev/_content/css/styles.css index 29a055b6..88469051 100644 --- a/go.dev/_content/css/styles.css +++ b/go.dev/_content/css/styles.css @@ -462,9 +462,6 @@ a.Footer-link--primary { max-width: 75.75rem; padding: 0 1.5rem; } -.Dir h1, .Doc h1, .Error h1, .Pkg h1, .Texthtml h1 { - padding-top: 1rem; -} h1 + h2.subtitle { margin-top: -1rem; font-size: 1.2rem !important; @@ -3999,8 +3996,9 @@ h2.Playground-about { } .expandAll { cursor: pointer; - float: left; margin: 1.25rem 0; + font-weight: normal; + font-size: 0.8em; } .toggleButton { cursor: pointer; @@ -4134,7 +4132,8 @@ th.pkg-name { /* For styling "Note" sections. */ background-color: rgb(224, 235, 245); font-size: 0.875rem; - margin: 1.25rem; + margin-top: 1.25rem; + margin-bottom: 1.25rem; max-width: 50rem; padding: 0.5rem 0.5rem 0.5rem 0.625rem; } @@ -4297,3 +4296,13 @@ a.downloadBox:hover .filename { .downloadBox .checksum { font-size: 5pt; } +#manual-nav dl, #pkg-examples dl{ + margin-left: 1.25rem; + font-size: 0.875rem; + margin-block-end: 0; + margin-block-start: 0; +} +#manual-nav dd, #pkg-examples dd { + margin: 0 0 0 1.25rem; + font-size: 0.875rem; +} diff --git a/_content/dir.tmpl b/go.dev/_content/dir.tmpl index 69ae0780..4fabcda4 100644 --- a/_content/dir.tmpl +++ b/go.dev/_content/dir.tmpl @@ -5,6 +5,11 @@ --> {{define "layout"}} + +<article class="Dir Article"> + +<h1>Directory {{breadcrumb .URL}}</h1> + <p> <table class="layout"> <tr> @@ -25,4 +30,7 @@ </table> </p> + +</article> + {{end}} diff --git a/_content/dl.tmpl b/go.dev/_content/dl.tmpl index c018d3aa..46c09b23 100644 --- a/_content/dl.tmpl +++ b/go.dev/_content/dl.tmpl @@ -1,4 +1,9 @@ {{define "layout"}} + +<article class="Downloads Article"> + +<h1>{{.title}}</h1> + {{with .dl}} <p> After downloading a binary release suitable for your system, @@ -26,7 +31,7 @@ information about Go releases. </p> {{with .Featured}} -<h3 id="featured">Featured downloads</h3> +<h2 id="featured">Featured downloads</h2> {{range .}} {{template "download" .}} {{end}} @@ -35,22 +40,22 @@ information about Go releases. <div style="clear: both;"></div> {{with .Stable}} -<h3 id="stable">Stable versions</h3> +<h2 id="stable">Stable versions</h2> {{template "download-releases" .}} {{end}} {{with .Unstable}} -<h3 id="unstable">Unstable version</h3> +<h2 id="unstable">Unstable version</h2> {{template "download-releases" .}} {{end}} {{with .Archive}} <div class="toggle" id="archive"> <div class="collapsed"> - <h3 class="toggleButton" title="Click to show versions">Archived versions ▹</h3> + <h2 class="toggleButton" title="Click to show versions">Archived versions ▸</h2> </div> <div class="expanded"> - <h3 class="toggleButton" title="Click to hide versions">Archived versions ▾</h3> + <h2 class="toggleButton" title="Click to hide versions">Archived versions ▾</h2> {{template "download-releases" .}} </div> </div> @@ -89,16 +94,19 @@ $(document).ready(function() { }); </script> {{end}} + +</article> + {{end}} {{define "download-releases"}} {{range .}} <div class="toggle{{if .Visible}}Visible{{end}}" id="{{.Version}}"> <div class="collapsed"> - <h2 class="toggleButton" title="Click to show downloads for this version">{{.Version}} ▹</h2> + <h3 class="toggleButton" title="Click to show downloads for this version">{{.Version}} ▸</h3> </div> <div class="expanded"> - <h2 class="toggleButton" title="Click to hide downloads for this version">{{.Version}} ▾</h2> + <h3 class="toggleButton" title="Click to hide downloads for this version">{{.Version}} ▾</h3> {{if .Stable}}{{else}} <p>This is an <b>unstable</b> version of Go. Use with caution.</p> <p>If you already have Go installed, you can install this version by running:</p> diff --git a/_content/texthtml.tmpl b/go.dev/_content/doc/default.tmpl index c7cd1af5..d57fc0b8 100644 --- a/_content/texthtml.tmpl +++ b/go.dev/_content/doc/default.tmpl @@ -1,3 +1,3 @@ {{define "layout"}} -{{.texthtml}} +{{doclayout .}} {{end}} diff --git a/go.dev/_content/error.tmpl b/go.dev/_content/error.tmpl index 30fe79d6..1f48d7a8 100644 --- a/go.dev/_content/error.tmpl +++ b/go.dev/_content/error.tmpl @@ -5,7 +5,15 @@ --> {{define "layout"}} + +<article class="Error Article"> + +<h1>to, err := human()</h1> + <p> <span class="alert" style="font-size:120%">{{.error}}</span> </p> + +</article> + {{end}} diff --git a/go.dev/_content/menus.yaml b/go.dev/_content/menus.yaml index bdae92ee..307c12d6 100644 --- a/go.dev/_content/menus.yaml +++ b/go.dev/_content/menus.yaml @@ -4,11 +4,11 @@ main: - name: Get Started url: /learn/ - name: Docs - url: https://golang.org/doc/ + url: /doc/ - name: Packages url: https://pkg.go.dev - name: Play - url: /play + url: /play/ - name: Blog url: /blog/ diff --git a/_content/pkg.tmpl b/go.dev/_content/pkg.tmpl index 9ffbb0ae..1c0c2259 100644 --- a/_content/pkg.tmpl +++ b/go.dev/_content/pkg.tmpl @@ -10,6 +10,11 @@ correspond to Go identifiers). --> {{define "layout"}} + +<article class="Pkg Article"> + +<h1>{{.title}}</h1> + {{$canShare := not googleCN}} {{$pkg := .pkg}} {{with $pkg.PDoc}} @@ -36,7 +41,7 @@ <!-- The package's Name is printed as title by the top-level template --> <div id="pkg-overview" class="toggleVisible"> <div class="collapsed"> - <h2 class="toggleButton" title="Click to show Overview section">Overview ▹</h2> + <h2 class="toggleButton" title="Click to show Overview section">Overview ▸</h2> </div> <div class="expanded"> <h2 class="toggleButton" title="Click to hide Overview section">Overview ▾</h2> @@ -47,7 +52,7 @@ <div id="pkg-index" class="toggleVisible"> <div class="collapsed"> - <h2 class="toggleButton" title="Click to show Index section">Index ▹</h2> + <h2 class="toggleButton" title="Click to show Index section">Index ▸</h2> </div> <div class="expanded"> <h2 class="toggleButton" title="Click to hide Index section">Index ▾</h2> @@ -82,8 +87,9 @@ {{if $pkg.Examples}} <div id="pkg-examples"> - <h3>Examples</h3> - <div class="js-expandAll expandAll collapsed">(Expand All)</div> + <h3>Examples + <span class="js-expandAll expandAll collapsed">(Expand All)</span> + </h3> <dl> {{range $pkg.Examples}} <dd><a class="exampleLink" href="#example_{{.Name}}">{{$pkg.ExampleName .Name}}</a></dd> @@ -200,7 +206,8 @@ {{if not (or (eq $pkg.Dirname "/src/cmd") $pkg.DirFlat)}} <tr> - <td colspan="2"><a href="..">..</a></td> + <td class="pkg-name"><a href="..">..</a></td> + <td class="pkg-synopsis"></td> </tr> {{end}} @@ -213,7 +220,7 @@ </td> {{end}} {{else}} - <td class="pkg-name" style="padding-left: {{mul .Depth 20}}px;"> + <td class="pkg-name" style="padding-left: {{mul (sub .Depth 1) 20}}px;"> <a href="{{.Path}}/{{$pkg.ModeQuery}}">{{.Name}}</a> </td> {{end}} @@ -225,6 +232,9 @@ </table> </div> {{end}} + +</article> + {{end}} {{define "example ex canShare"}} @@ -232,7 +242,7 @@ {{with .ex}} <div id="example_{{.Name}}" class="toggle"> <div class="collapsed"> - <p class="exampleHeading toggleButton">▹ <span class="text">Example{{.Page.ExampleSuffix .Name}}</span></p> + <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> diff --git a/_content/pkgroot.tmpl b/go.dev/_content/pkgroot.tmpl index b972cd9b..a650b281 100644 --- a/_content/pkgroot.tmpl +++ b/go.dev/_content/pkgroot.tmpl @@ -10,6 +10,11 @@ correspond to Go identifiers). --> {{define "layout"}} + +<article class="Pkg Article"> + +<h1>{{.title}}</h1> + {{$pkg := .pkg}} {{with $pkg.Dirs}} @@ -28,7 +33,7 @@ <div id="stdlib" class="toggleVisible"> <div class="collapsed"> - <h2 class="toggleButton" title="Click to show Standard library section">Standard library ▹</h2> + <h2 class="toggleButton" title="Click to show Standard library section">Standard library ▸</h2> </div> <div class="expanded"> <h2 class="toggleButton" title="Click to hide Standard library section">Standard library ▾</h2> @@ -49,7 +54,7 @@ </td> {{end}} {{else}} - <td class="pkg-name" style="padding-left: {{mul .Depth 20}}px;"> + <td class="pkg-name" style="padding-left: {{mul (sub .Depth 1) 20}}px;"> <a href="{{.Path}}/{{$pkg.ModeQuery}}">{{.Name}}</a> </td> {{end}} @@ -100,4 +105,7 @@ <li><a href="/wiki/Projects">Projects at the Go Wiki</a> - a curated list of Go projects.</li> </ul> {{end}} + +</article> + {{end}} diff --git a/go.dev/_content/ref/default.tmpl b/go.dev/_content/ref/default.tmpl new file mode 100644 index 00000000..d57fc0b8 --- /dev/null +++ b/go.dev/_content/ref/default.tmpl @@ -0,0 +1,3 @@ +{{define "layout"}} +{{doclayout .}} +{{end}} diff --git a/go.dev/_content/site.tmpl b/go.dev/_content/site.tmpl index 20a16fa8..b0d601d2 100644 --- a/go.dev/_content/site.tmpl +++ b/go.dev/_content/site.tmpl @@ -317,3 +317,45 @@ {{define "pkg path name?" -}} <a href="https://pkg.go.dev/{{.path}}?tab=overview">{{or .name .path}}</a> {{- end}} + + +{{define "breadcrumb"}} +{{$elems := strings.Split (strings.Trim . "/") "/"}} +{{$prefix := slice $elems 0 (sub (len $elems) 1)}} +{{range $i, $elem := $prefix -}} +<a href="/{{strings.Join (slice $prefix 0 (add $i 1)) "/"}}/">{{$elem}}</a>/ +{{- end -}} +<span class="text-muted">{{strings.Join (slice $elems (len $prefix) (len $elems)) "/"}}</span> +{{end}} + +{{define "doclayout"}} +{{/* used from various subdirectory default.tmpl */}} +<article class="Doc Article"> + +{{if .title}} +<h1>{{.title}}</h1> +{{else if eq .layout "error"}} +<h1>Error</h1> +{{else if eq .layout "dir"}} +<h1>Directory {{breadcrumb .URL}}</h1> +{{else if and (eq .layout "texthtml") (strings.HasSuffix .URL ".go")}} +<h1>Source file {{breadcrumb .URL}}</h1> +{{else if eq .layout "texthtml"}} +<h1>Text file {{breadcrumb .URL}}</h1> +{{end}} + +{{with .subtitle}} +<h2 class="subtitle">{{.}}</h2> +{{end}} + +{{/* The Table of Contents is automatically inserted in this <div>. + Do not delete this <div>. */}} +{{if not .hidetoc}} +<div id="nav" class="TOC"></div> +{{end}} + +{{.Content}} + +</article> + +{{end}} diff --git a/go.dev/_content/texthtml.tmpl b/go.dev/_content/texthtml.tmpl new file mode 100644 index 00000000..49783b4f --- /dev/null +++ b/go.dev/_content/texthtml.tmpl @@ -0,0 +1,14 @@ +{{define "layout"}} + +<article class="Texthtml Article"> + +{{if strings.HasSuffix .URL ".go"}} +<h1>Source file {{breadcrumb .URL}}</h1> +{{else}} +<h1>Text file {{breadcrumb .URL}}</h1> +{{end}} + +{{.texthtml}} + +</article> +{{end}} diff --git a/internal/dl/server.go b/internal/dl/server.go index d2434518..c5694f74 100644 --- a/internal/dl/server.go +++ b/internal/dl/server.go @@ -224,7 +224,7 @@ func (h server) getHandler(w http.ResponseWriter, r *http.Request) { case name == "gotip": redirectURL = "https://pkg.go.dev/golang.org/dl/gotip" case goGetRe.MatchString(name): - redirectURL = "https://golang.org/dl/#" + name + redirectURL = "/dl/#" + name default: http.NotFound(w, r) return @@ -240,7 +240,7 @@ func (h server) getHandler(w http.ResponseWriter, r *http.Request) { <meta http-equiv="refresh" content="0; url=%s"> </head> <body> -Nothing to see here; <a href="%s">move along</a>. +<a href="%s">Redirecting to documentation...</a>. </body> </html> `, html.EscapeString(redirectURL), html.EscapeString(redirectURL)) diff --git a/internal/redirect/redirect.go b/internal/redirect/redirect.go index d291863e..6d3d2f27 100644 --- a/internal/redirect/redirect.go +++ b/internal/redirect/redirect.go @@ -36,7 +36,7 @@ func Register(mux *http.ServeMux) { mux.Handle(path, Handler(redirect)) } for path, redirect := range blogRedirects { - mux.Handle("go.dev/blog"+path, Handler("/blog/"+redirect)) + mux.Handle("/blog"+path, Handler("/blog/"+redirect)) } // NB: /src/pkg (sans trailing slash) is the index of packages. mux.HandleFunc("/src/pkg/", srcPkgHandler) @@ -95,7 +95,6 @@ var cmdRedirects = map[string]string{ } var redirects = map[string]string{ - "/blog": "https://go.dev/blog", "/build": "https://build.golang.org", "/change": "https://go.googlesource.com/go", "/cl": "https://go-review.googlesource.com", @@ -104,7 +103,6 @@ var redirects = map[string]string{ "/issue/new": "https://github.com/golang/go/issues/new", "/issues": "https://github.com/golang/go/issues", "/issues/new": "https://github.com/golang/go/issues/new", - "/play": "https://play.golang.org", "/design": "https://go.googlesource.com/proposal/+/master/design", // In Go 1.2 the references page is part of /doc/. @@ -142,10 +140,8 @@ var redirects = map[string]string{ var prefixHelpers = map[string]string{ "issue": "https://github.com/golang/go/issues/", "issues": "https://github.com/golang/go/issues/", - "play": "https://play.golang.org/", "talks": "https://talks.golang.org/", "wiki": "https://github.com/golang/go/wiki/", - "blog": "https://go.dev/blog/", } func Handler(target string) http.Handler { diff --git a/internal/redirect/redirect_test.go b/internal/redirect/redirect_test.go index 7b74b571..b90893c5 100644 --- a/internal/redirect/redirect_test.go +++ b/internal/redirect/redirect_test.go @@ -21,15 +21,13 @@ func errorResult(status int) redirectResult { func TestRedirects(t *testing.T) { var tests = map[string]redirectResult{ - "/build": {301, "https://build.golang.org"}, - "/ref": {301, "/doc/#references"}, - "/doc/mem": {301, "/ref/mem"}, - "/doc/spec": {301, "/ref/spec"}, - "/tour": {301, "https://tour.golang.org"}, - "/foo": errorResult(404), - "/blog": {301, "https://go.dev/blog"}, - "/blog/": {302, "/blog"}, - "/blog/go1.16": {302, "https://go.dev/blog/go1.16"}, + "/build": {301, "https://build.golang.org"}, + "/ref": {301, "/doc/#references"}, + "/doc/mem": {301, "/ref/mem"}, + "/doc/spec": {301, "/ref/spec"}, + "/tour": {301, "https://tour.golang.org"}, + "/foo": errorResult(404), + "/blog/2011/01/json-and-go.html": {301, "/blog/json-and-go"}, "/pkg/asn1": {301, "/pkg/encoding/asn1/"}, "/pkg/template/parse": {301, "/pkg/text/template/parse/"}, diff --git a/internal/short/short.go b/internal/short/short.go index 77a7ea59..44a69a2c 100644 --- a/internal/short/short.go +++ b/internal/short/short.go @@ -26,7 +26,7 @@ import ( const ( prefix = "/s" kind = "Link" - baseURL = "https://golang.org" + prefix + baseURL = "https://go.dev" + prefix ) // Link represents a short link. @@ -54,7 +54,7 @@ func RegisterHandlers(mux *http.ServeMux, host string, dc *datastore.Client, mc } // linkHandler services requests to short URLs. -// http://golang.org/s/key[/remaining/path] +// https://go.dev/s/key[/remaining/path] // It consults memcache and datastore for the Link for key. // It then sends a redirects or an error message. // If the remaining path part is not empty, the redirects |
