aboutsummaryrefslogtreecommitdiff
path: root/go.dev
diff options
context:
space:
mode:
authorRuss Cox <rsc@google.com>2021-04-28 22:57:05 -0400
committerRuss Cox <rsc@google.com>2021-05-24 23:12:14 -0400
commit2e6578a8f2ecf69e636aef96b8a107bcfeef730c (patch)
tree141f0d16c547c702c67177e7b71888cdc15efa44 /go.dev
parentdfbbeaf13f306eee5f9e1987827992197382a18b (diff)
downloadgo-x-website-2e6578a8f2ecf69e636aef96b8a107bcfeef730c.tar.xz
[x/go.dev] all: replace shortcodes with template invocations
Templates already provide a way to call other templates. Use it in place of the Hugo shortcode mechanism, which adds unnecessary complexity and is not well integrated into HTML sanitizing. Change-Id: I1fc578bc8f4d9c410127f8423434c0c8162d900e X-GoDev-Commit: 623170c6f36da204eccea6e82ec400d0a8bcf7d0
Diffstat (limited to 'go.dev')
-rw-r--r--go.dev/cmd/internal/site/md.go53
-rw-r--r--go.dev/cmd/internal/site/page.go2
-rw-r--r--go.dev/cmd/internal/site/shortcode.go163
-rw-r--r--go.dev/content/about.md5
-rw-r--r--go.dev/content/post.md139
-rw-r--r--go.dev/content/solutions/americanexpress/index.md22
-rw-r--r--go.dev/content/solutions/clis/index.md35
-rw-r--r--go.dev/content/solutions/cloud/index.md30
-rw-r--r--go.dev/content/solutions/devops/index.md11
-rw-r--r--go.dev/content/solutions/google/_index.md30
-rw-r--r--go.dev/content/solutions/google/chrome.md11
-rw-r--r--go.dev/content/solutions/google/coredata.md22
-rw-r--r--go.dev/content/solutions/google/firebase.md11
-rw-r--r--go.dev/content/solutions/google/sitereliability.md29
-rw-r--r--go.dev/content/solutions/mercadolibre/index.md42
-rw-r--r--go.dev/content/solutions/paypal/index.md21
-rw-r--r--go.dev/content/solutions/webdev/index.md14
-rw-r--r--go.dev/layouts/shortcodes/backgroundQuote.html29
-rw-r--r--go.dev/layouts/shortcodes/gopher.html114
-rw-r--r--go.dev/layouts/shortcodes/headerWithLink.html10
-rw-r--r--go.dev/layouts/shortcodes/largeMedia.html13
-rw-r--r--go.dev/layouts/shortcodes/linkList.html3
-rw-r--r--go.dev/layouts/shortcodes/mediaList.html3
-rw-r--r--go.dev/layouts/shortcodes/mediaListBox.html9
-rw-r--r--go.dev/layouts/shortcodes/mediaListItem.html5
-rw-r--r--go.dev/layouts/shortcodes/mediaTable.html16
-rw-r--r--go.dev/layouts/shortcodes/mediaTableItem.html11
-rw-r--r--go.dev/layouts/shortcodes/pkg.html10
-rw-r--r--go.dev/layouts/shortcodes/pullquote.html37
-rw-r--r--go.dev/layouts/shortcodes/quote.html23
-rw-r--r--go.dev/layouts/shortcodes/rawhtml.html2
-rw-r--r--go.dev/layouts/shortcodes/starItem.html13
-rw-r--r--go.dev/templates/backgroundquote.tmpl26
-rw-r--r--go.dev/templates/books.tmpl (renamed from go.dev/layouts/shortcodes/books.html)6
-rw-r--r--go.dev/templates/gopher.tmpl116
-rw-r--r--go.dev/templates/libraries.tmpl (renamed from go.dev/layouts/shortcodes/goLibraries.html)6
-rw-r--r--go.dev/templates/pkg.tmpl3
-rw-r--r--go.dev/templates/projects.tmpl (renamed from go.dev/layouts/shortcodes/featuredProjects.html)22
-rw-r--r--go.dev/templates/pullquote.tmpl34
-rw-r--r--go.dev/templates/quote.tmpl21
-rw-r--r--go.dev/templates/toolsblurbs.tmpl (renamed from go.dev/layouts/shortcodes/toolsBlurbs.html)17
-rw-r--r--go.dev/testdata/golden/solutions/clis/index.html21
-rw-r--r--go.dev/testdata/golden/solutions/cloud/index.html3
-rw-r--r--go.dev/testdata/golden/solutions/devops/index.html3
-rw-r--r--go.dev/testdata/golden/solutions/paypal/index.html4
-rw-r--r--go.dev/testdata/golden/solutions/webdev/index.html6
46 files changed, 420 insertions, 806 deletions
diff --git a/go.dev/cmd/internal/site/md.go b/go.dev/cmd/internal/site/md.go
index bd0db59f..bed4fe52 100644
--- a/go.dev/cmd/internal/site/md.go
+++ b/go.dev/cmd/internal/site/md.go
@@ -5,11 +5,12 @@
package site
import (
- "fmt"
+ "bytes"
"strings"
"github.com/russross/blackfriday"
"golang.org/x/go.dev/cmd/internal/html/template"
+ "golang.org/x/go.dev/cmd/internal/tmplfunc"
)
// markdownToHTML converts markdown to HTML using the renderer and settings that Hugo uses.
@@ -38,42 +39,18 @@ func markdownToHTML(markdown string) template.HTML {
return template.HTML(blackfriday.MarkdownOptions([]byte(markdown), renderer, options))
}
-// markdownWithShortCodesToHTML converts markdown to HTML,
-// first expanding Hugo shortcodes in the markdown input.
-// Shortcodes templates are given access to p as .Page.
-func markdownWithShortCodesToHTML(markdown string, p *Page) (template.HTML, error) {
- // We replace each shortcode invocation in the markdown with
- // a keyword HUGOREPLACECODE0001 etc and then run the result
- // through markdown conversion, and then we substitute the actual
- // shortcode ouptuts for the keywords.
- var md string // current markdown chunk
- var replaces []string // replacements to apply to all at end
-
- for i, elem := range p.parseCodes(markdown) {
- switch elem := elem.(type) {
- default:
- return "", fmt.Errorf("unexpected elem %T", elem)
- case string:
- md += elem
-
- case *ShortCode:
- code := elem
- html, err := code.run()
- if err != nil {
- return "", err
- }
- // Adjust shortcode output to match Hugo's line breaks.
- // This is weird but will go away when we retire shortcodes.
- if code.Inner != "" {
- html = "\n\n" + html
- } else if code.Kind == "%" {
- html = template.HTML(strings.TrimLeft(string(html), " \n"))
- }
- key := fmt.Sprintf("HUGOREPLACECODE%04d", i)
- md += key
- replaces = append(replaces, key, string(html), "<p>"+key+"</p>", string(html))
- }
+// markdownTemplateToHTML converts a markdown template to HTML,
+// first applying the template execution engine and then interpreting
+// the result as markdown to be converted to HTML.
+// This is the same logic used by the Go web site.
+func markdownTemplateToHTML(markdown string, p *Page) (template.HTML, error) {
+ t := p.Site.clone().New(p.file)
+ if err := tmplfunc.Parse(t, string(p.data)); err != nil {
+ return "", err
+ }
+ var buf bytes.Buffer
+ if err := t.Execute(&buf, p); err != nil {
+ return "", err
}
- html := markdownToHTML(md)
- return template.HTML(strings.NewReplacer(replaces...).Replace(string(html))), nil
+ return markdownToHTML(buf.String()), nil
}
diff --git a/go.dev/cmd/internal/site/page.go b/go.dev/cmd/internal/site/page.go
index 8320a810..e8e759af 100644
--- a/go.dev/cmd/internal/site/page.go
+++ b/go.dev/cmd/internal/site/page.go
@@ -139,7 +139,7 @@ func (site *Site) loadPage(file string) (*Page, error) {
// renderHTML renders the HTML for the page, leaving it in p.html.
func (p *Page) renderHTML() error {
var err error
- p.Content, err = markdownWithShortCodesToHTML(string(p.data), p)
+ p.Content, err = markdownTemplateToHTML(string(p.data), p)
if err != nil {
return err
}
diff --git a/go.dev/cmd/internal/site/shortcode.go b/go.dev/cmd/internal/site/shortcode.go
deleted file mode 100644
index 97c7a07a..00000000
--- a/go.dev/cmd/internal/site/shortcode.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2021 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 site
-
-import (
- "fmt"
- "log"
- "strconv"
- "strings"
- "unicode/utf8"
-
- "golang.org/x/go.dev/cmd/internal/html/template"
-)
-
-// A ShortCode is a parsed Hugo shortcode like {{% foo %}} or {{< foo >}}.
-// It is Hugo's wrapping of a template call and will be replaced by actual template calls.
-type ShortCode struct {
- Kind string
- Name string
- Args []string
- Keys map[string]string
- Inner template.HTML
- Page *Page
-}
-
-func (c *ShortCode) run() (template.HTML, error) {
- return c.Page.Site.runTemplate("layouts/shortcodes/"+c.Name+".html", c)
-}
-
-func (c *ShortCode) String() string {
- if c == nil {
- return ""
- }
- return fmt.Sprintf("<code %s %v %v %q>", c.Name, c.Args, c.Keys, c.Inner)
-}
-
-func (c *ShortCode) Get(x interface{}) string {
- switch x := x.(type) {
- case int:
- if 0 <= x && x < len(c.Args) {
- return c.Args[x]
- }
- return ""
- case string:
- return c.Keys[x]
- }
- panic(fmt.Sprintf("bad Get %v", x))
-}
-
-func (c *ShortCode) IsNamedParams() bool {
- return len(c.Keys) != 0
-}
-
-// parseCodes parses the shortcode invocations in the Hugo markdown file.
-// It returns a slice containing only two types of elements: string and *ShortCode.
-// The even indexes are strings and the odd indexes are *ShortCode.
-// There are an odd number of elements (the slice begins and ends with a string).
-func (p *Page) parseCodes(markdown string) []interface{} {
- t1, c1, t2, kind1 := findCode(markdown)
- t2, c2, t3, kind2 := findCode(t2)
- var ret []interface{}
- for c1 != nil {
- c1.Kind = kind1
- c1.Page = p
- if c2 != nil && c2.Name == "/"+c1.Name {
- c1.Inner = template.HTML(t2)
- t2, c2, t3, kind2 = findCode(t3)
- continue
- }
- ret = append(ret, t1)
- ret = append(ret, c1)
- t1, c1, kind1 = t2, c2, kind2
- t2, c2, t3, kind2 = findCode(t3)
- }
- ret = append(ret, t1)
- return ret
-}
-
-func findCode(text string) (before string, code *ShortCode, after string, kind string) {
- end := "%}}"
- kind = "%"
- i := strings.Index(text, "{{%")
- j := strings.Index(text, "{{<")
- if i < 0 || j >= 0 && j < i {
- i = j
- kind = "<"
- end = ">}}"
- }
- if i < 0 {
- return text, nil, "", ""
- }
- j = strings.Index(text[i+3:], end)
- if j < 0 {
- return text, nil, "", ""
- }
- before, codeText, after := text[:i], text[i+3:i+3+j], text[i+3+j+3:]
- codeText = strings.TrimSpace(codeText)
- name, args, _ := cutAny(codeText, " \t\r\n")
- if name == "" {
- log.Fatalf("empty code")
- }
- args = strings.TrimSpace(args)
- code = &ShortCode{Name: name, Keys: make(map[string]string)}
- for args != "" {
- k, v := "", args
- if strings.HasPrefix(args, `"`) {
- goto Value
- }
- {
- i := strings.Index(args, "=")
- if i < 0 {
- goto Value
- }
- for j := 0; j < i; j++ {
- if args[j] == ' ' || args[j] == '\t' {
- goto Value
- }
- }
- k, v = args[:i], args[i+1:]
- }
- Value:
- v = strings.TrimSpace(v)
- if strings.HasPrefix(v, `"`) {
- j := 1
- for ; ; j++ {
- if j >= len(v) {
- log.Fatalf("unterminated quoted string: %s", args)
- }
- if v[j] == '"' {
- v, args = v[:j+1], v[j+1:]
- break
- }
- if v[j] == '\\' {
- j++
- }
- }
- u, err := strconv.Unquote(v)
- if err != nil {
- log.Fatalf("malformed k=v: %s=%s", k, v)
- }
- v = u
- } else {
- v, args, _ = cutAny(v, " \t\r\n")
- }
- if k == "" {
- code.Args = append(code.Args, v)
- } else {
- code.Keys[k] = v
- }
- args = strings.TrimSpace(args)
- }
- return
-}
-
-func cutAny(s, any string) (before, after string, ok bool) {
- if i := strings.IndexAny(s, any); i >= 0 {
- _, size := utf8.DecodeRuneInString(s[i:])
- return s[:i], s[i+size:], true
- }
- return s, "", false
-}
diff --git a/go.dev/content/about.md b/go.dev/content/about.md
index f52eaab5..90300125 100644
--- a/go.dev/content/about.md
+++ b/go.dev/content/about.md
@@ -6,7 +6,10 @@ draft: false
[Go.dev](https://go.dev) is a companion website to [golang.org](https://golang.org). [Golang.org](https://golang.org) is the home of the open source project and distribution, while [go.dev](https://go.dev) is the hub for Go users providing centralized and curated resources from across the Go ecosystem.
-{{% gopher gopher=pink align=right %}}
+{{gopher `
+ color: pink
+ align: right
+`}}
Go.dev provides:
1. Centralized information for Go packages and modules published on index.golang.org.
diff --git a/go.dev/content/post.md b/go.dev/content/post.md
deleted file mode 100644
index 57ce3b38..00000000
--- a/go.dev/content/post.md
+++ /dev/null
@@ -1,139 +0,0 @@
----
-title: 'Lorem Postum'
-date: 2019-06-25T17:51:23-04:00
-authors: ['Andrew Bonventre', 'Steve Francia']
-draft: true
----
-
-## Inminet facies saevit montis
-
-Lorem markdownum horum surgere es quaeris et iuvenci cadunt hausitque armiferae
-[senex](http://sub.com/). Cecidisse inpediunt Romam, voluisse curru **saepe pro
-sola** poposcerat bracchia. Sanguine _discutiunt manu_, mihi armos? Dilata levia
-ab mira auxiliaria pennas Eumenidum lentoque inertem tantum stipite pompa.
-
-{{%pullquote author="Google dev manager"%}}
-Lorem markdownum horum surgere es quaeris et iuvenci cadunt hausitque armiferae
-[senex](http://sub.com/). Cecidisse inpediunt Romam, voluisse curru **saepe pro
-sola** poposcerat bracchia. Sanguine _discutiunt manu_, mihi armos? Dilata levia
-ab mira auxiliaria pennas Eumenidum lentoque inertem tantum stipite pompa.
-{{%/pullquote%}}
-
-## Rex feritatis tamen seminaque aquas liceret nepos
-
-Pervenit ramos; quaterque panda, terra pedum blandita parte. Et vidisse illis
-loci crimen moratur **nomine**! Pelasgos discurrunt conata. Manu Hippomenes
-pecudis dixisse, hac, iunctam dixerat vita penetralia tempus praedivite Libycas.
-Feroci sacris Pitanen guttura despexitque candida fervebant curasque dies
-inhibere rapta.
-
-- Fulmina doctam deduxisse illo
-- Corpora o Pallade magno regia ignarus optime
-- Venenis et esse perimet
-- Mihi nocte
-- Gelidoque sit crevit
-
-## Quamquam nympha esse senex prior nec
-
-Longos et o reliquit [alterius](http://caelaratin.net/dixitexspes) canis
-praecordia nimiis, fiducia _non corpore_. Correptaque et venata illi! Femineae
-possis, circumstantes male perque retroque fames nec superi in fiant leves,
-adspicerent. Hasta spectabat est **vultum in** inficere subsidit hunc. Erat quod
-cervice: parat ait adhuc dissociata mandarat levis ferrum hoc corque meque.
-
-## Imaginis lora
-
-Et arte, versabat ne pater sibila; natus visa graves perque rustica! Caeli
-forma, Tres, clarum? Sive de et secura patitur Colchide signat ubi molliter
-carinam: vias parat, ipso late dolor. Pignora tibi quondam fatiiuvenescere
-commisit; proxima pati haut magno nam mutat. Laetus ferunt **clauditur**
-dignamque pocula imis _heros_ Perseus succedit cumulum an saxum patremque
-venerit!
-
- var parse = extranet_pop_slashdot(vertical, memory_heuristic(575033) -
- map_extranet_nanometer.ssid_cd_commerce(prebinding_icq, png_virtual,
- tag_mount));
- var leopard_shortcut = 3 + onlineAlphaBiometrics;
- kilobitLogicSsid = ad;
- if (storage - 1 > 3 + 3) {
- scroll(half_file * row, installerRefreshFriendly);
- } else {
- compile_big += exbibyte * white_bus_webmail;
- }
-
-_Avem linguam fecundus_ voce, mea haud paratior et telorum trahitur, causas iura
-dilectae **nisi feres** canes formam? Domos ac mediaque os Stygias!
-
-{{%largeMedia
- title="_Avem linguam fecundus_ voce, mea haud"
- img-src="/images/google-logo.png"
- img-alt="Google."%}}
- Lorem markdownum horum surgere es quaeris et iuvenci cadunt hausitque armiferae
- [senex](http://sub.com/).
-{{%/largeMedia%}}
-{{%largeMedia
- title="_Avem linguam fecundus_ voce, mea haud"
- img-src="/images/gophers/biplane.svg"
- img-alt="Gopher piloting a biplane."%}}
- Lorem markdownum horum surgere es quaeris et iuvenci cadunt hausitque armiferae
- [senex](http://sub.com/).
-{{%/largeMedia%}}
-
-{{%mediaList%}}
- {{%mediaListItem title="Lorem ipsum dolor"
- img-src="/images/google-logo.png"
- img-alt="Google."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- {{%/mediaListItem%}}
- {{%mediaListItem title="Lorem ipsum dolor"
- img-src="/images/gophers/biplane.svg"
- img-alt="Gopher piloting a biplane."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- {{%/mediaListItem%}}
- {{%mediaListItem title="Lorem ipsum dolor"
- img-src="/images/google-logo.png"
- img-alt="Google."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- {{%/mediaListItem%}}
- {{%mediaListItem title="Lorem ipsum dolor"
- img-src="/images/gophers/biplane.svg"
- img-alt="Gopher piloting a biplane."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
- {{%/mediaListItem%}}
-{{%/mediaList%}}
-
-{{%mediaList%}}
- {{%mediaListBox title="Lorem ipsum"
- img-src="/images/google-logo.png"
- img-alt="Google."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- {{%/mediaListBox%}}
- {{%mediaListBox title="Lorem ipsum"
- img-src="/images/gophers/biplane.svg"
- img-alt="Gopher piloting a biplane."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- {{%/mediaListBox%}}
- {{%mediaListBox title="Lorem ipsum"
- img-src="/images/learn/codecademy.png"
- img-alt="Google."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- {{%/mediaListBox%}}
- {{%mediaListBox title="Lorem ipsum"
- img-src="/images/gophers/biplane.svg"
- img-alt="Gopher piloting a biplane."%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- {{%/mediaListBox%}}
-{{%/mediaList%}}
-
-{{%starItem title="Lorem ipsum dolor sit amet, consectetur"%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
- aliqua. Ut enim ad minim veniam,
-{{%/starItem%}}
-{{%starItem title="Lorem ipsum dolor sit amet, consectetur"%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
- aliqua. Ut enim ad minim veniam,
-{{%/starItem%}}
-{{%starItem title="Lorem ipsum dolor sit amet, consectetur"%}}
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
- aliqua. Ut enim ad minim veniam,
-{{%/starItem%}}
diff --git a/go.dev/content/solutions/americanexpress/index.md b/go.dev/content/solutions/americanexpress/index.md
index 3f3d106a..b2e44c22 100644
--- a/go.dev/content/solutions/americanexpress/index.md
+++ b/go.dev/content/solutions/americanexpress/index.md
@@ -9,11 +9,15 @@ series: Case Studies
quote: Go provides American Express with the speed and scalability it needs for both its payment and rewards networks.
---
-{{% pullquote author="Glen Balliet" title="Engineering Director of loyalty platforms" company="American Express" %}}
-What makes Go different from other programming languages is cognitive load. You can do more with less code, which makes it easier to reason about and understand the code that you do end up writing.
+{{pullquote `
+ author: Glen Balliet
+ title: Engineering Director of loyalty platforms
+ company: American Express
+ quote: |
+ What makes Go different from other programming languages is cognitive load. You can do more with less code, which makes it easier to reason about and understand the code that you do end up writing.
-The majority of Go code ends up looking quite similar, so, even if you’re working with a completely new codebase, you can get up and running pretty quickly.
-{{% /pullquote %}}
+ The majority of Go code ends up looking quite similar, so, even if you’re working with a completely new codebase, you can get up and running pretty quickly.
+`}}
## Go Improves Microservices and Speeds Productivity
@@ -55,9 +59,13 @@ Today, scores of developers are programming with Go at American Express, with mo
"Tooling has always been a critical area of need for our legacy code base," says Cane. "We have found that Go has excellent tooling, plus built-in testing, benchmarking, and profiling frameworks. It is easy to write efficient and resilient applications."
-{{% backgroundQuote author="Benjamin Cane" title="Vice President and Principal Engineer" company="American Express" %}}
-After working on Go, most of our developers don't want to go back to other languages.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Benjamin Cane
+ title: Vice President and Principal Engineer
+ company: American Express
+ quote: |
+ After working on Go, most of our developers don't want to go back to other languages.
+`}}
American Express is just beginning to see the benefits of Go. For example, Go was designed from the ground up with concurrency in mind – using lightweight “goroutines” rather than heavier-weight operating system threads – making it practical to create hundreds of thousands of goroutines in the same address space. Using goroutines, American Express has seen improved performance numbers in its real-time transaction processing.
diff --git a/go.dev/content/solutions/clis/index.md b/go.dev/content/solutions/clis/index.md
index 041540cb..e91c9476 100644
--- a/go.dev/content/solutions/clis/index.md
+++ b/go.dev/content/solutions/clis/index.md
@@ -136,35 +136,38 @@ Specifically, **programs written in Go run on any system without requiring any e
### Use Go for building elegant CLIs
-{{< backgroundQuote author="Steve Domino" title="senior engineer and architect at Strala" link="https://medium.com/@skdomino/writing-better-clis-one-snake-at-a-time-d22e50e60056" >}}
-I was tasked with building our CLI tool and found two really great projects, Cobra and Viper, which make building CLI’s easy. Individually they are very powerful, very flexible and very good at what they do. But together they will help you show your next CLI who is boss!
-{{< /backgroundQuote >}}
+{{backgroundquote `
+ author: Steve Domino
+ title: senior engineer and architect at Strala
+ link: https://medium.com/@skdomino/writing-better-clis-one-snake-at-a-time-d22e50e60056
+ quote: |
+ I was tasked with building our CLI tool and found two really great projects, Cobra and Viper, which make building CLI’s easy. Individually they are very powerful, very flexible and very good at what they do. But together they will help you show your next CLI who is boss!
+`}}
-{{< backgroundQuote author="Francesc Campoy" title="VP of product at DGraph Labs and producer of Just For Func videos" link="https://www.youtube.com/watch?v=WvWPGVKLvR4" >}}
-Cobra is a great product to write small tools or even large ones. It’s more of a framework than a library, because when you call the binary that would create a skeleton, then you would be adding code in between.”
-{{< /backgroundQuote >}}
+{{backgroundquote `
+ author: Francesc Campoy
+ title: VP of product at DGraph Labs and producer of Just For Func videos
+ link: https://www.youtube.com/watch?v=WvWPGVKLvR4
+ quote: |
+ Cobra is a great product to write small tools or even large ones. It’s more of a framework than a library, because when you call the binary that would create a skeleton, then you would be adding code in between.”
+`}}
When developing CLIs in Go, two tools are widely used: Cobra & Viper.
- {{< pkg "github.com/spf13/cobra" Cobra >}} is both a library for creating powerful modern CLI applications and a program to generate applications and CLI applications in Go. Cobra powers most of the popular Go applications including CoreOS, Delve, Docker, Dropbox, Git Lfs, Hugo, Kubernetes, and [many more](https://pkg.go.dev/github.com/spf13/cobra?tab=importedby). With integrated command help, autocomplete and documentation “[it] makes documenting each command really simple,” says [Alex Ellis](https://blog.alexellis.io/5-keys-to-a-killer-go-cli/), founder of OpenFaaS.
+{{pkg "github.com/spf13/cobra" "Cobra"}} is both a library for creating powerful modern CLI applications and a program to generate applications and CLI applications in Go. Cobra powers most of the popular Go applications including CoreOS, Delve, Docker, Dropbox, Git Lfs, Hugo, Kubernetes, and [many more](https://pkg.go.dev/github.com/spf13/cobra?tab=importedby). With integrated command help, autocomplete and documentation “[it] makes documenting each command really simple,” says [Alex Ellis](https://blog.alexellis.io/5-keys-to-a-killer-go-cli/), founder of OpenFaaS.
- {{< pkg "github.com/spf13/viper" Viper >}} is a complete configuration solution for Go applications, designed to work within an app to handle configuration needs and formats. Cobra and Viper are designed to work together.
+{{pkg "github.com/spf13/viper" "Viper"}} is a complete configuration solution for Go applications, designed to work within an app to handle configuration needs and formats. Cobra and Viper are designed to work together.
Viper [supports nested structures](https://scene-si.org/2017/04/20/managing-configuration-with-viper/) in the configuration, allowing CLI developers to manage the configuration for multiple parts of a large application. Viper also provides all of the tooling need to easily build twelve factor apps.
"If you don’t want to pollute your command line, or if you’re working with sensitive data which you don’t want to show up in the history, it’s a good idea to work with environment variables. To do this, you can use Viper," [suggests Geudens](https://ordina-jworks.github.io/development/2018/10/20/make-your-own-cli-with-golang-and-cobra.html).
-{{< rawhtml >}}<div class="FeaturedUsers">{{< /rawhtml >}}
-
-## Featured users {#featured-users .sectionHeading}
-{{< featuredProjects >}}
-
-{{< rawhtml >}}</div>{{< /rawhtml >}}
+{{projects $}}
## Get Started {#get-started .sectionHeading}
### Go books for creating CLIs
-{{< books >}}
-{{< goLibraries >}} \ No newline at end of file
+{{books $}}
+{{libraries $}}
diff --git a/go.dev/content/solutions/cloud/index.md b/go.dev/content/solutions/cloud/index.md
index 328a19b6..8ff57a25 100644
--- a/go.dev/content/solutions/cloud/index.md
+++ b/go.dev/content/solutions/cloud/index.md
@@ -192,18 +192,18 @@ toolsBlurbs:
## Overview {#overview .sectionHeading}
-{{< rawhtml >}}
- <div class="UseCase-halfColumn">
+<div class="UseCase-halfColumn">
<h3>Go helps enterprises build and scale cloud computing systems</h3>
-
<p>As applications and processing move to the cloud, concurrency becomes a very big issue. Cloud computing systems, by their very nature, share and scale resources. Coordinating access to shared resources is an issue that impacts every application processing in the cloud, and requires programming languages “explicitly geared to develop highly reliable concurrent applications.”</p>
-
</div>
-{{< /rawhtml >}}
-{{< quote author="Ruchi Malik" title="developer at Choozle" link="https://builtin.com/software-engineering-perspectives/golang-advantages" >}}
-Go makes it very easy to scale as a company. This is very important because, as our engineering team grows, each service can be managed by a different unit.
-{{< /quote >}}
+{{quote `
+ author: Ruchi Malik
+ title: developer at Choozle
+ link: https://builtin.com/software-engineering-perspectives/golang-advantages
+ quote: |
+ Go makes it very easy to scale as a company. This is very important because, as our engineering team grows, each service can be managed by a different unit.
+`}}
## Key Benefits {#key-benefits .sectionHeading}
@@ -229,19 +229,13 @@ The major Cloud providers ([GCP](https://cloud.google.com/go/home), [AWS](https:
### Go tools for Cloud Computing
-{{< toolsBlurbs >}}
-
-{{< rawhtml >}}<div class="FeaturedUsers">{{< /rawhtml >}}
-
-## Featured users {#featured-users .sectionHeading}
-{{< featuredProjects >}}
-
-{{< rawhtml >}}</div>{{< /rawhtml >}}
+{{toolsblurbs $}}
+{{projects $}}
## Get Started {#get-started .sectionHeading}
### Go books for cloud computing
-{{< books >}}
-{{< goLibraries >}} \ No newline at end of file
+{{books $}}
+{{libraries $}}
diff --git a/go.dev/content/solutions/devops/index.md b/go.dev/content/solutions/devops/index.md
index 31641f49..584661b5 100644
--- a/go.dev/content/solutions/devops/index.md
+++ b/go.dev/content/solutions/devops/index.md
@@ -159,16 +159,11 @@ Every site reliability engineer has written “one-time use” scripts that turn
### Scale and maintain larger applications with Go’s low memory footprint and doc generator
Go’s garbage collector means DevOps/SRE teams don’t have to worry about memory management. And Go’s automatic documentation generator (godoc) makes code self-documenting–lowering maintenance overhead and establishing best practices from the get-go.
-{{< rawhtml >}}<div class="FeaturedUsers">{{< /rawhtml >}}
-
-## Featured users {#featured-users .sectionHeading}
-{{< featuredProjects >}}
-
-{{< rawhtml >}}</div>{{< /rawhtml >}}
+{{projects $}}
## Get Started {#get-started .sectionHeading}
### Go books on DevOps & SRE
-{{< books >}}
-{{< goLibraries >}} \ No newline at end of file
+{{books $}}
+{{libraries $}}
diff --git a/go.dev/content/solutions/google/_index.md b/go.dev/content/solutions/google/_index.md
index 6e3ae17a..654750e0 100644
--- a/go.dev/content/solutions/google/_index.md
+++ b/go.dev/content/solutions/google/_index.md
@@ -21,22 +21,24 @@ quote: Go was created at Google in 2007, and since then, engineering teams
---
-{{% pullquote author="Rob Pike" %}}
-Go started in September 2007 when Robert Griesemer, Ken Thompson, and I began
-discussing a new language to address the engineering challenges we and our
-colleagues at Google were facing in our daily work.
+{{pullquote `
+ author: Rob Pike
+ quote: |
+ Go started in September 2007 when Robert Griesemer, Ken Thompson, and I began
+ discussing a new language to address the engineering challenges we and our
+ colleagues at Google were facing in our daily work.
-When we first released Go to the public in November 2009, we didn’t know if the
-language would be widely adopted or if it might influence future languages.
-Looking back from 2020, Go has succeeded in both ways: it is widely used both
-inside and outside Google, and its approaches to network concurrency and
-software engineering have had a noticeable effect on other languages and their
-tools.
+ When we first released Go to the public in November 2009, we didn’t know if the
+ language would be widely adopted or if it might influence future languages.
+ Looking back from 2020, Go has succeeded in both ways: it is widely used both
+ inside and outside Google, and its approaches to network concurrency and
+ software engineering have had a noticeable effect on other languages and their
+ tools.
-Go has turned out to have a much broader reach than we had ever expected. Its
-growth in the industry has been phenomenal, and it has powered many projects at
-Google.
-{{% /pullquote %}}
+ Go has turned out to have a much broader reach than we had ever expected. Its
+ growth in the industry has been phenomenal, and it has powered many projects at
+ Google.
+`}}
The following stories are a small sample of the many ways that Go is used at Google.
diff --git a/go.dev/content/solutions/google/chrome.md b/go.dev/content/solutions/google/chrome.md
index bf6b258e..8a634378 100644
--- a/go.dev/content/solutions/google/chrome.md
+++ b/go.dev/content/solutions/google/chrome.md
@@ -35,10 +35,13 @@ already on the device. Were the Chrome Optimization Guide service to suddenly
disappear, users might notice a dramatic change in the speed of their page loads
and the amount of data consumed while browsing the web.
-{{% backgroundQuote author="Sophie Chang" title="Software Engineer" %}}
-Given that Go was a success for us, we plan to continue to use
-it where appropriate
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Sophie Chang
+ title: Software Engineer
+ quote: |
+ Given that Go was a success for us, we plan to continue to use
+ it where appropriate
+`}}
When the Chrome engineering team started building the service, only a few
members had comfort with Go. Most of the team was more familiar with C++, but
diff --git a/go.dev/content/solutions/google/coredata.md b/go.dev/content/solutions/google/coredata.md
index 73c5647c..8182f2fc 100644
--- a/go.dev/content/solutions/google/coredata.md
+++ b/go.dev/content/solutions/google/coredata.md
@@ -30,10 +30,13 @@ stack from a single monolithic binary written in C++ to multiple components in a
microservices architecture. We decided to rewrite many indexing services in Go,
which we now use to power the majority of our architecture.
-{{% backgroundQuote author="Minjae Hwang" title="Software Engineer" %}}
-Go’s built-in concurrency is a natural fit because engineers on the team are
-encouraged to use concurrency and parallel algorithms.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Minjae Hwang
+ title: Software Engineer
+ quote: |
+ Go’s built-in concurrency is a natural fit because engineers on the team are
+ encouraged to use concurrency and parallel algorithms.
+`}}
When choosing a language, our team found that several of Go’s features made it
particularly suitable. For instance, Go’s built-in concurrency is a natural fit
@@ -62,10 +65,13 @@ good job of static type checking and that certain Go fundamentals, such as the
godoc command, have helped the team build a more disciplined culture around
writing documentation.
-{{% backgroundQuote author="Prasanna Meda" title="Software Engineer" %}}
-...Google’s web indexing was re-architected within a year. More impressively,
-most developers on the team were rewriting in Go while also learning it.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Prasanna Meda
+ title: Software Engineer
+ quote: |
+ ...Google’s web indexing was re-architected within a year. More impressively,
+ most developers on the team were rewriting in Go while also learning it.
+`}}
Working on a product used so heavily around the world is no small task and our
team’s decision to use Go wasn’t a simple one, but doing so helped us move
diff --git a/go.dev/content/solutions/google/firebase.md b/go.dev/content/solutions/google/firebase.md
index d3a899eb..fd7e543d 100644
--- a/go.dev/content/solutions/google/firebase.md
+++ b/go.dev/content/solutions/google/firebase.md
@@ -55,10 +55,13 @@ learn when each route is best, how to determine when a problem is a concurrency
problem, how to debug–but that comes out of the fact that you actually can write
these patterns in Go code.”
-{{% backgroundQuote author="Robert Rossney" title="Software Engineer" %}}
-Generally speaking, there’s not a time on the team where we’re feeling
-frustrated with Go, it just kind of gets out of the way and lets you do work.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Robert Rossney
+ title: Software Engineer
+ quote: |
+ Generally speaking, there’s not a time on the team where we’re feeling
+ frustrated with Go, it just kind of gets out of the way and lets you do work.
+`}}
Hundreds of thousands of customers host their websites with Firebase Hosting,
which means Go code is used to serve billions of requests per day. “Our customer
diff --git a/go.dev/content/solutions/google/sitereliability.md b/go.dev/content/solutions/google/sitereliability.md
index a8506c02..7b03abcd 100644
--- a/go.dev/content/solutions/google/sitereliability.md
+++ b/go.dev/content/solutions/google/sitereliability.md
@@ -30,10 +30,11 @@ behind all of Google’s public services with an ever-watchful eye on their
availability, latency, performance, and capacity.”
- [Site Reliability Engineering (SRE)](https://sre.google/).
-{{% backgroundQuote %}}
-Go promised a sweet spot between performance and readability that neither of
-the other languages [Python and C++] were able to offer.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ quote: |
+ Go promised a sweet spot between performance and readability that neither of
+ the other languages [Python and C++] were able to offer.
+`}}
In 2013-2014, Google’s SRE team realized that our approach to production
management was not cutting it anymore in many ways. We had advanced far beyond
@@ -54,10 +55,11 @@ themselves at the core. We were happy with Go—its simplicity grew on us, the
performance was there, and concurrency primitives would have been hard to
replace.
-{{% backgroundQuote %}}
-Now the majority of Google production is managed and maintained by our systems
-written in Go.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ quote: |
+ Now the majority of Google production is managed and maintained by our systems
+ written in Go.
+`}}
At no point was there ever a mandate or requirement to use Go, but we had no
desire to return to Python or C++. Go grew organically in Annealing and
@@ -71,11 +73,12 @@ ability to enforce in the code that some complex structure should not be
mutated. But for each one of those cases, there have undoubtedly been tens or
hundred of cases where the simplicity helped.
-{{% backgroundQuote %}}
-Go’s simplicity means that the code is easy to follow, whether it is to spot
-bugs during review or when trying to determine exactly what happened during a
-service disruption.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ quote: |
+ Go’s simplicity means that the code is easy to follow, whether it is to spot
+ bugs during review or when trying to determine exactly what happened during a
+ service disruption.
+`}}
For example, Annealing impacts a wide variety of teams and services meaning
that we relied heavily on contributions across the company. The simplicity of
diff --git a/go.dev/content/solutions/mercadolibre/index.md b/go.dev/content/solutions/mercadolibre/index.md
index ad843d5e..9a68dc12 100644
--- a/go.dev/content/solutions/mercadolibre/index.md
+++ b/go.dev/content/solutions/mercadolibre/index.md
@@ -9,9 +9,13 @@ series: Case Studies
quote: Go provides clean, efficient code that readily scales as MercadoLibre’s online commerce grows, and increases developer productivity by allowing their engineers to serve their ever-increasing audience while writing less code.
---
-{{% pullquote author="Eric Kohan" title="Software Engineering Manager" company="MercadoLibre" %}}
-I think that **the tour of Go is by far the best introduction to a language that I’ve seen**, It’s really simple and it gives you a fair overview of probably 80 percent of the language. When we want to get developers to learn Go, and to get to production fast, we tell them to start with the tour of Go.
-{{% /pullquote %}}
+{{pullquote `
+ author: Eric Kohan
+ title: Software Engineering Manager
+ company: MercadoLibre
+ quote: |
+ I think that **the tour of Go is by far the best introduction to a language that I’ve seen**, It’s really simple and it gives you a fair overview of probably 80 percent of the language. When we want to get developers to learn Go, and to get to production fast, we tell them to start with the tour of Go.
+`}}
## Go helps integrated ecosystem attract developers and scale eCommerce
@@ -57,10 +61,14 @@ Converting that legacy architecture to Go as a new, very thin framework for buil
layers and yielded great performance benefits. For example, one large Go service is now able to **run 70,000 requests
per machine with just 20 MB of RAM.**
-{{% backgroundQuote author="Eric Kohan" title="Software Engineering Manager" company="MercadoLibre" %}}
-Go was just marvelous for us. It’s very powerful
-and very easy to learn, and with backend infrastructure, has been great for us in terms of scalability.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Eric Kohan
+ title: Software Engineering Manager
+ company: MercadoLibre
+ quote: |
+ Go was just marvelous for us. It’s very powerful
+ and very easy to learn, and with backend infrastructure, has been great for us in terms of scalability.
+`}}
Using **Go allowed MercadoLibre to cut the number of servers** they use for this service to one-eighth the original
number (from 32 servers down to four), plus each server can operate with less power (originally four CPU cores, now down
@@ -97,9 +105,13 @@ companies using Go in Argentina, and is perhaps the largest in Latin America usi
Headquartered in Buenos Aires, with many start-ups and emerging technology companies nearby, MercadoLibre's adoption of
Go has shaped the market for developers across the Pampas.
-{{% backgroundQuote author="Eric Kohan" title="Software Engineering Manager" company="MercadoLibre" %}}
-We really see eye-to-eye with the larger philosophy of the language. We love Go's simplicity, and we find that having its very explicit error handling has been a gain for developers because it results in safer, more stable code in production.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Eric Kohan
+ title: Software Engineering Manager
+ company: MercadoLibre
+ quote: |
+ We really see eye-to-eye with the larger philosophy of the language. We love Go's simplicity, and we find that having its very explicit error handling has been a gain for developers because it results in safer, more stable code in production.
+`}}
Buenos Aires is today a very competitive market for programmers, offering computer programmers many employment options,
and the high demand for technology in the region drives great salaries, great benefits, and the ability to be selective
@@ -118,9 +130,13 @@ Go](https://golang.org/doc/effective_go.html) to educate new programmers, and sh
written in Go to speed understanding and proficiency. MercadoLibre developers get the resources they need to embrace the
language, then leverage their own skills and enthusiasm to start programming.
-{{% backgroundQuote author="Federico Martin Roasio" title="Technical Project Lead" company="MercadoLibre" %}}
-Go has been great for writing business logic, and we are the team that writes those APIs.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Federico Martin Roasio
+ title: Technical Project Lead
+ company: MercadoLibre
+ quote: |
+ Go has been great for writing business logic, and we are the team that writes those APIs.
+`}}
MercadoLibre leverages Go’s expressive and clean syntax to make it easier for developers to write programs that run
efficiently on modern cloud platforms. And while speed in development yields cost efficiency for the company, developers
diff --git a/go.dev/content/solutions/paypal/index.md b/go.dev/content/solutions/paypal/index.md
index 7a003041..7cdf9621 100644
--- a/go.dev/content/solutions/paypal/index.md
+++ b/go.dev/content/solutions/paypal/index.md
@@ -9,9 +9,13 @@ series: Case Studies
quote: Go’s value in producing clean, efficient code that readily scales as software deployment scales made the language a strong fit to support PayPal’s goals.
---
-{{% pullquote author="Bala Natarajan" title="<span class=\"NoWrapSpan\">Sr. Director of Engineering,</span>&nbsp;<span class=\"NoWrapSpan\">Developer Experience</span>" company="PayPal" %}}
-Since our NoSQL and DB proxy used quite a bit of system details in a multi-threaded mode, the code got complex managing the different conditions, given that Go provides channels and routines to deal with complexity, we were able to structure the code to meet our requirements.
-{{% /pullquote %}}
+{{pullquote `
+ author: Bala Natarajan
+ title: <span class="NoWrapSpan">Sr. Director of Engineering,</span>&nbsp;<span class="NoWrapSpan">Developer Experience</span>
+ company: PayPal
+ quote: |
+ Since our NoSQL and DB proxy used quite a bit of system details in a multi-threaded mode, the code got complex managing the different conditions, given that Go provides channels and routines to deal with complexity, we were able to structure the code to meet our requirements.
+`}}
## New code infrastructure built on Go
@@ -32,7 +36,6 @@ With Go, PayPal enables its developers to spend more time looking at code and th
After the success of this newly re-written NoSQL system, more platform and content teams within PayPal began adopting Go. Natarajan’s current team is responsible for PayPal’s build, test, and release pipelines—all built in Go. The company has a large build and test farm which is completely managed using Go infrastructure to support builds-as-a-service (and tests-as-a-service) for developers across the company.
-{{< rawhtml >}}
<img
loading="lazy"
width="607"
@@ -40,7 +43,6 @@ After the success of this newly re-written NoSQL system, more platform and conte
class=""
alt="Go gopher factory"
src="/images/gophers/factory.png">
-{{< /rawhtml >}}
## Modernizing PayPal systems with Go
@@ -50,9 +52,12 @@ Security and supportability are key matters at PayPal, and the company’s opera
As PayPal continues to modernize their software-defined networking (SDN) infrastructure with Go, they are seeing performance benefits in addition to more maintainable code. For example, Go now powers routers, load balances, and an increasing number of production systems.
-{{% backgroundQuote author="Bala Natarajan" title="Sr. Director of Engineering" %}}
-In our tightly managed environments where we run Go code, we have seen a CPU reduction of approximately ten percent with cleaner and maintainable code.
-{{% /backgroundQuote %}}
+{{backgroundquote `
+ author: Bala Natarajan
+ title: Sr. Director of Engineering
+ quote: |
+ In our tightly managed environments where we run Go code, we have seen a CPU reduction of approximately ten percent with cleaner and maintainable code.
+`}}
## Go increases developer productivity
diff --git a/go.dev/content/solutions/webdev/index.md b/go.dev/content/solutions/webdev/index.md
index 8787dc95..eaf0b54d 100644
--- a/go.dev/content/solutions/webdev/index.md
+++ b/go.dev/content/solutions/webdev/index.md
@@ -191,24 +191,20 @@ Tigran Bayburtsyan, Co-Founder and CTO at Hexact Inc., summarizes five key reaso
- **Great IDE support and debugging** — “After rewriting all projects to Go, we got 64 percent less code than we had earlier.”
-{{< rawhtml >}}<div class="FeaturedUsers">{{< /rawhtml >}}
-
-## Featured users {#featured-users .sectionHeading}
-{{< featuredProjects >}}
-
-{{< rawhtml >}}</div>{{< /rawhtml >}}
+{{projects $}}
## Get Started {#get-started .sectionHeading}
### Go books on web development
-{{< books >}}
-{{< goLibraries >}}
+
+{{books $}}
+{{libraries $}}
### Courses
* [Learn to Create Web Applications using Go](https://www.usegolang.com), a paid online course
### Projects
-* {{< pkg "github.com/gopherjs/gopherjs" gopherjs >}}, a compiler from Go to JavaScript allowing developers to write front-end code in Go which will run in all browsers.
+* {{pkg "github.com/gopherjs/gopherjs" "gopherjs"}}, a compiler from Go to JavaScript allowing developers to write front-end code in Go which will run in all browsers.
* [Hugo](https://gohugo.io/), The world’s fastest framework for building websites
* [Mattermost](https://mattermost.com/), a flexible, open source messaging platform
that enables secure team collaboration
diff --git a/go.dev/layouts/shortcodes/backgroundQuote.html b/go.dev/layouts/shortcodes/backgroundQuote.html
deleted file mode 100644
index b826d819..00000000
--- a/go.dev/layouts/shortcodes/backgroundQuote.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{{with .Get "link"}}
-<a href="{{.}}" target="_blank" rel="noopener">{{end -}}
- <div class="BackgroundQuote">
- <p class="BackgroundQuote-body">
- “{{.Inner | markdownify}}”
- </p>
- {{$author := .Get 0 -}}
- {{$title := .Get 1 -}}
- {{$company := .Get 2 -}}
- {{if .IsNamedParams -}}
- {{$author = .Get "author" -}}
- {{$title = .Get "title" -}}
- {{$company = .Get "company" -}}
- {{end -}}
- {{if $author -}}
- <div class="BackgroundQuote-author">
- <span>&mdash; {{$author -}}</span>
- {{if $title -}},&nbsp;
- <span class="BackgroundQuote-title">{{$title | safeHTML}}</span>
- {{end -}}
- {{if $company -}}
- <span class="BackgroundQuote-title">&nbsp;at {{$company -}}</span>
- {{end -}}
- </div>
- {{end -}}
- </div>
- {{with .Get "link"}}
-</a>
-{{end -}}
diff --git a/go.dev/layouts/shortcodes/gopher.html b/go.dev/layouts/shortcodes/gopher.html
deleted file mode 100644
index f0cd021e..00000000
--- a/go.dev/layouts/shortcodes/gopher.html
+++ /dev/null
@@ -1,114 +0,0 @@
-{{ $src := "/images/gophers/wrench.svg"}}
-{{ $alt := "Go gophers with wrench"}}
-{{ $size := "Large"}}
-{{ $align := "Left"}}
-{{ $gopher := .Get "gopher"}}
-{{ $sizeIn := .Get "size"}}
-
-{{if eq (.Get "align") "right" "Right"}}
- {{$align = "Right"}}
-{{end}}
-
-{{if eq $sizeIn "XLarge" "xl" "xlarge"}}
- {{$size = "XLarge"}}
-{{end}}
-
-{{if eq $gopher "plane"}}
- {{$src = "/images/gophers/biplane.svg"}}
- {{$alt = "Go gopher in a plane"}}
-{{end}}
-{{if eq $gopher "blue"}}
- {{$src = "/images/gophers/blue.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "front" "sticker1"}}
- {{$src = "/images/gophers/front.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "graduate"}}
- {{$src = "/images/gophers/graduate.svg"}}
- {{$alt = "Go gopher graduating"}}
-{{end}}
-{{if eq $gopher "graduate-colorized"}}
- {{$src = "/images/gophers/graduate-colorized.svg"}}
- {{$alt = "Go gopher graduating"}}
-{{end}}
-{{if eq $gopher "green"}}
- {{$src = "/images/gophers/green.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "grey" "gray"}}
- {{$src = "/images/gophers/grey.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "happy" "sticker2"}}
- {{$src = "/images/gophers/happy.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "headlamp"}}
- {{$src = "/images/gophers/headlamp.svg"}}
- {{$alt = "Go gopher with headlamp"}}
-{{end}}
-{{if eq $gopher "headlamp-colorized"}}
- {{$src = "/images/gophers/headlamp-colorized.svg"}}
- {{$alt = "Go gopher with headlamp"}}
-{{end}}
-{{if eq $gopher "ladder"}}
- {{$src = "/images/gophers/ladder.svg"}}
- {{$alt = "Go gopher with ladder"}}
-{{end}}
-{{if eq $gopher "machine"}}
- {{$src = "/images/gophers/machine.svg"}}
- {{$alt = "Go gophers with a machine"}}
-{{end}}
-{{if eq $gopher "machine-colorized"}}
- {{$src = "/images/gophers/machine-colorized.svg"}}
- {{$alt = "Go gopher with a machine"}}
-{{end}}
-{{if eq $gopher "megaphone"}}
- {{$src = "/images/gophers/megaphone.svg"}}
- {{$alt = "Go gopher with a megaphone"}}
-{{end}}
-{{if eq $gopher "peach"}}
- {{$src = "/images/gophers/peach.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "pilot-bust"}}
- {{$src = "/images/gophers/pilot-bust.svg"}}
- {{$alt = "Go gopher pilot"}}
-{{end}}
-{{if eq $gopher "pink"}}
- {{$src = "/images/gophers/pink.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "running"}}
- {{$src = "/images/gophers/running.svg"}}
- {{$alt = "Go gopher running"}}
-{{end}}
-{{if eq $gopher "slate"}}
- {{$src = "/images/gophers/slate.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "wrench"}}
- {{$src = "/images/gophers/wrench.svg"}}
- {{$alt = "gopher with a wrench"}}
-{{end}}
-{{if eq $gopher "yellow"}}
- {{$src = "/images/gophers/yellow.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "violet"}}
- {{$src = "/images/gophers/violet.svg"}}
- {{$alt = "Go gopher"}}
-{{end}}
-{{if eq $gopher "factory"}}
- {{$src = "/images/gophers/factory.png"}}
- {{$alt = "Go gopher factory"}}
-{{end}}
-
-
-<img
- loading="lazy"
- class="{{$size}}Media-image {{$align}}"
- alt="{{$alt}}"
- src="{{$src}}"> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/headerWithLink.html b/go.dev/layouts/shortcodes/headerWithLink.html
deleted file mode 100644
index 8fe3550a..00000000
--- a/go.dev/layouts/shortcodes/headerWithLink.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<div class="headerWithLink">
- <h{{with .Get "level"}}{{.}}{{else}}2{{end}}>{{ .Get "header"}}</h2>
- <p class="headerLink">
- {{- if .Get "search" -}}
- <a href="https://pkg.go.dev/search?q={{ .Get "search" | htmlEscape }}">{{with .Get "text"}}{{.}}{{else}}View More &gt;{{end}}</a>
- {{- else -}}
- <a href="{{ .Get "link"}}">{{with .Get "text"}}{{.}}{{else}}View More &gt;{{end}}</a>
- {{- end -}}
- </p>
-</div> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/largeMedia.html b/go.dev/layouts/shortcodes/largeMedia.html
deleted file mode 100644
index 669f3cb7..00000000
--- a/go.dev/layouts/shortcodes/largeMedia.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<div class="LargeMedia">
- <img class="LargeMedia-image" alt="{{.Get "img-alt"}}" src="{{.Get "img-src"}}">
- <div class="LargeMedia-body">
- {{with .Get "title"}}
- <h3 class="LargeMedia-title">
- {{- . | markdownify -}}
- </h3>
- {{end}}
- <p class="LargeMedia-text">
- {{.Inner | markdownify -}}
- </p>
- </div>
-</div>
diff --git a/go.dev/layouts/shortcodes/linkList.html b/go.dev/layouts/shortcodes/linkList.html
deleted file mode 100644
index 1ded9fb3..00000000
--- a/go.dev/layouts/shortcodes/linkList.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<ul>
- {{.Inner}}
-</ul> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/mediaList.html b/go.dev/layouts/shortcodes/mediaList.html
deleted file mode 100644
index 1d11acb9..00000000
--- a/go.dev/layouts/shortcodes/mediaList.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<ul class="MediaList">
- {{.Inner}}
-</ul>
diff --git a/go.dev/layouts/shortcodes/mediaListBox.html b/go.dev/layouts/shortcodes/mediaListBox.html
deleted file mode 100644
index e2979a01..00000000
--- a/go.dev/layouts/shortcodes/mediaListBox.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<li class="MediaList-itemBox">
- <div class="MediaList-itemBoxHeader{{if eq (.Get "align") "top"}}-top{{end}}">
- {{with .Get "img-link"}}<a href="{{.}}" target="_blank" rel="noopener">{{end -}}
- <img class="MediaList-itemBoxImage" src="{{.Get "img-src"}}" alt="{{.Get "img-alt"}}">
- {{- with .Get "img-link"}}</a>{{end}}
- <p class="MediaList-itemBoxTitle">{{.Get "title"}}</p>
- </div>
- <p class="MediaList-itemBoxBody{{if eq (.Get "align") "top"}}-top{{end}}">{{.Inner | markdownify -}}</p>
-</li>
diff --git a/go.dev/layouts/shortcodes/mediaListItem.html b/go.dev/layouts/shortcodes/mediaListItem.html
deleted file mode 100644
index 054df1d7..00000000
--- a/go.dev/layouts/shortcodes/mediaListItem.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<li class="MediaList-item">
- <img class="MediaList-itemImage" src="{{.Get "img-src"}}" alt="{{.Get "img-alt"}}">
- <h3 class="MediaList-itemTitle">{{.Get "title"}}</h3>
- <p class="MediaList-itemBody">{{.Inner | markdownify -}}</p>
-</li>
diff --git a/go.dev/layouts/shortcodes/mediaTable.html b/go.dev/layouts/shortcodes/mediaTable.html
deleted file mode 100644
index 95877015..00000000
--- a/go.dev/layouts/shortcodes/mediaTable.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- <ul class="MediaList">
- {{.Inner}}
-</ul> -->
-
-<table>
- <thead>
- <tr>
- <th colspan="2">Customer</th>
- <th colspan="2">Breif introduction</th>
- <th colspan="2">Projects using go</th>
- </tr>
- </thead>
- <tbody>
- {{.Inner}}
- </tbody>
-</table> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/mediaTableItem.html b/go.dev/layouts/shortcodes/mediaTableItem.html
deleted file mode 100644
index 3b9ca828..00000000
--- a/go.dev/layouts/shortcodes/mediaTableItem.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<tr>
- <td>
- {{with .Get "img-link"}}
- <a href="{{.}}" target="_blank" rel="noopener">
- {{end -}}
- <img class="MediaList-itemBoxImage" src="{{.Get "img-src"}}" alt="{{.Get "img-alt"}}">
- {{- with .Get "img-link"}}</a>{{end}}
- </td>
- <td><p class="MediaList-itemBoxTitle">{{.Get "title"}}</p></td>
- <td><p class="MediaList-itemBoxBody{{if eq (.Get "align") "top"}}-top{{end}}">{{.Inner | markdownify -}}</p></td>
-</tr> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/pkg.html b/go.dev/layouts/shortcodes/pkg.html
deleted file mode 100644
index 333b6d02..00000000
--- a/go.dev/layouts/shortcodes/pkg.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- $link := .Get 0 -}}
-{{- $link = replace $link "https://" ""}}
-{{- $link = replace $link "http://" ""}}
-{{- $label := or (.Get 1) (.Get 0) -}}
-{{- if not (.Get 1) -}}
- {{- $name := path.Base $label -}}
- {{- $owner := path.Base (path.Dir $label) -}}
- {{- $label = path.Join $owner $name -}}
-{{end}}
-<a href="https://pkg.go.dev/{{$link}}?tab=overview">{{$label}}</a> \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/pullquote.html b/go.dev/layouts/shortcodes/pullquote.html
deleted file mode 100644
index 81ccab54..00000000
--- a/go.dev/layouts/shortcodes/pullquote.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<div class="PullQuote">
- <div class="PullQuote-quoteHeader">
- <img class="PullQuote-image" src="/images/quote.svg" alt="Quotation mark.">
- </div>
- <p class="PullQuote-body">
- {{.Inner | markdownify}}
- </p>
- {{$author := .Get 0 -}}
- {{$title := .Get 1 -}}
- {{$company := .Get 2 -}}
- {{if .IsNamedParams -}}
- {{$author = .Get "author" -}}
- {{$title = .Get "title" -}}
- {{$company = .Get "company" -}}
- {{end -}}
- {{if $author -}}
- <div class="PullQuote-author">
- {{with .Get "link"}}
- <a
- class="PullQuote-link"
- href="{{.}}"
- target="_blank"
- rel="noopener">
- {{end -}}
- <span>
- &mdash; {{$author -}}
- </span>
- {{if $title -}},&nbsp;
- <span class="PullQuote-title">{{$title | safeHTML}}</span>
- {{end -}}
- {{if $company -}}
- <span class="PullQuote-title">&nbsp;at {{$company -}}</span>
- {{end -}}
- {{with .Get "link"}}</a>{{end -}}
- </div>
- {{end -}}
-</div>
diff --git a/go.dev/layouts/shortcodes/quote.html b/go.dev/layouts/shortcodes/quote.html
deleted file mode 100644
index 221ea3dc..00000000
--- a/go.dev/layouts/shortcodes/quote.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<div class="QuoteBlock">
- <p class="QuoteBlock-body">
- {{.Inner | markdownify}}
- </p>
- {{$author := .Get 0 -}}
- {{$title := .Get 1 -}}
- {{if .IsNamedParams -}}
- {{$author = .Get "author" -}}
- {{$title = .Get "title" -}}
- {{end -}}
- {{if $author -}}
- <div class="QuoteBlock-author">
- {{with .Get "link"}}
- <a class="QuoteBlock-link" href="{{.}}" target="_blank" rel="noopener">
- {{end -}}
- &mdash; {{$author -}}
- {{if $title -}}
- ,&nbsp;<span>{{$title -}}</span>
- {{end -}}
- {{with .Get "link"}}</a>{{end -}}
- </div>
- {{end -}}
-</div>
diff --git a/go.dev/layouts/shortcodes/rawhtml.html b/go.dev/layouts/shortcodes/rawhtml.html
deleted file mode 100644
index 520ec178..00000000
--- a/go.dev/layouts/shortcodes/rawhtml.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!-- raw html -->
-{{.Inner}} \ No newline at end of file
diff --git a/go.dev/layouts/shortcodes/starItem.html b/go.dev/layouts/shortcodes/starItem.html
deleted file mode 100644
index 4da8dd6e..00000000
--- a/go.dev/layouts/shortcodes/starItem.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<div class="StarItem">
- <div class="StarItem-icon" role="presentation">
- <i class="material-icons StarItem-image">star</i>
- </div>
- <div class="StarItem-body">
- <h2 class="StarItem-title">
- {{- .Get "title" | markdownify -}}
- </h2>
- <p class="StarItem-text">
- {{.Inner | markdownify -}}
- </p>
- </div>
-</div>
diff --git a/go.dev/templates/backgroundquote.tmpl b/go.dev/templates/backgroundquote.tmpl
new file mode 100644
index 00000000..5d347eb7
--- /dev/null
+++ b/go.dev/templates/backgroundquote.tmpl
@@ -0,0 +1,26 @@
+{{define "backgroundquote info" -}}
+{{- with (yaml .info)}}
+<div class="BackgroundQuote">
+{{- with .link}}
+<a href="{{.}}" target="_blank" rel="noopener">
+{{- end}}
+ <p class="BackgroundQuote-body">
+ “{{.quote | markdownify}}”
+ </p>
+ {{- if .author}}
+ <div class="BackgroundQuote-author">
+ <span>&mdash; {{.author}}</span>
+ {{if .title}},&nbsp;
+ <span class="BackgroundQuote-title">{{.title | safeHTML}}</span>
+ {{- end}}
+ {{- if .company}}
+ <span class="BackgroundQuote-title">&nbsp;at {{.company}}</span>
+ {{- end}}
+ </div>
+ {{- end}}
+{{- if .link}}
+</a>
+{{- end}}
+</div>
+{{- end}}
+{{end}}
diff --git a/go.dev/layouts/shortcodes/books.html b/go.dev/templates/books.tmpl
index f4b4e6de..14eac390 100644
--- a/go.dev/layouts/shortcodes/books.html
+++ b/go.dev/templates/books.tmpl
@@ -1,4 +1,5 @@
-{{$books := .Page.Param "books"}}
+{{define "books"}}
+{{$books := .Param "books"}}
<ul class="Learn-tileList">
{{range $books}}
@@ -15,4 +16,5 @@
</a>
</li>
{{end}}
-</ul> \ No newline at end of file
+</ul>
+{{end}}
diff --git a/go.dev/templates/gopher.tmpl b/go.dev/templates/gopher.tmpl
new file mode 100644
index 00000000..5fcd14a5
--- /dev/null
+++ b/go.dev/templates/gopher.tmpl
@@ -0,0 +1,116 @@
+{{define "gopher info" -}}
+{{- with (yaml .info)}}
+{{- $src := "/images/gophers/wrench.svg"}}
+{{- $alt := "Go gophers with wrench"}}
+{{- $size := "Large"}}
+{{- $align := "Left"}}
+{{- $gopher := .color}}
+{{- $sizeIn := (or .size "")}}
+
+{{- if eq (.align) "right" "Right"}}
+ {{- $align = "Right"}}
+{{- end}}
+
+{{- if eq $sizeIn "XLarge" "xl" "xlarge"}}
+ {{- $size = "XLarge"}}
+{{- end}}
+
+{{- if eq $gopher "plane"}}
+ {{- $src = "/images/gophers/biplane.svg"}}
+ {{- $alt = "Go gopher in a plane"}}
+{{- end}}
+{{- if eq $gopher "blue"}}
+ {{- $src = "/images/gophers/blue.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "front" "sticker1"}}
+ {{- $src = "/images/gophers/front.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "graduate"}}
+ {{- $src = "/images/gophers/graduate.svg"}}
+ {{- $alt = "Go gopher graduating"}}
+{{- end}}
+{{- if eq $gopher "graduate-colorized"}}
+ {{- $src = "/images/gophers/graduate-colorized.svg"}}
+ {{- $alt = "Go gopher graduating"}}
+{{- end}}
+{{- if eq $gopher "green"}}
+ {{- $src = "/images/gophers/green.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "grey" "gray"}}
+ {{- $src = "/images/gophers/grey.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "happy" "sticker2"}}
+ {{- $src = "/images/gophers/happy.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "headlamp"}}
+ {{- $src = "/images/gophers/headlamp.svg"}}
+ {{- $alt = "Go gopher with headlamp"}}
+{{- end}}
+{{- if eq $gopher "headlamp-colorized"}}
+ {{- $src = "/images/gophers/headlamp-colorized.svg"}}
+ {{- $alt = "Go gopher with headlamp"}}
+{{- end}}
+{{- if eq $gopher "ladder"}}
+ {{- $src = "/images/gophers/ladder.svg"}}
+ {{- $alt = "Go gopher with ladder"}}
+{{- end}}
+{{- if eq $gopher "machine"}}
+ {{- $src = "/images/gophers/machine.svg"}}
+ {{- $alt = "Go gophers with a machine"}}
+{{- end}}
+{{- if eq $gopher "machine-colorized"}}
+ {{- $src = "/images/gophers/machine-colorized.svg"}}
+ {{- $alt = "Go gopher with a machine"}}
+{{- end}}
+{{- if eq $gopher "megaphone"}}
+ {{- $src = "/images/gophers/megaphone.svg"}}
+ {{- $alt = "Go gopher with a megaphone"}}
+{{- end}}
+{{- if eq $gopher "peach"}}
+ {{- $src = "/images/gophers/peach.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "pilot-bust"}}
+ {{- $src = "/images/gophers/pilot-bust.svg"}}
+ {{- $alt = "Go gopher pilot"}}
+{{- end}}
+{{- if eq $gopher "pink"}}
+ {{- $src = "/images/gophers/pink.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "running"}}
+ {{- $src = "/images/gophers/running.svg"}}
+ {{- $alt = "Go gopher running"}}
+{{- end}}
+{{- if eq $gopher "slate"}}
+ {{- $src = "/images/gophers/slate.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "wrench"}}
+ {{- $src = "/images/gophers/wrench.svg"}}
+ {{- $alt = "gopher with a wrench"}}
+{{- end}}
+{{- if eq $gopher "yellow"}}
+ {{- $src = "/images/gophers/yellow.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "violet"}}
+ {{- $src = "/images/gophers/violet.svg"}}
+ {{- $alt = "Go gopher"}}
+{{- end}}
+{{- if eq $gopher "factory"}}
+ {{- $src = "/images/gophers/factory.png"}}
+ {{- $alt = "Go gopher factory"}}
+{{- end}}
+<img
+ loading="lazy"
+ class="{{$size}}Media-image {{$align}}"
+ alt="{{$alt}}"
+ src="{{$src}}">
+{{- end}}
+{{- end}}
diff --git a/go.dev/layouts/shortcodes/goLibraries.html b/go.dev/templates/libraries.tmpl
index a0062a3d..f13b10bd 100644
--- a/go.dev/layouts/shortcodes/goLibraries.html
+++ b/go.dev/templates/libraries.tmpl
@@ -1,4 +1,5 @@
-{{$goLibraries := .Page.Param "goLibraries"}}
+{{define "libraries"}}
+{{$goLibraries := .Param "goLibraries"}}
{{range $goLibraries}}
<div class="WhoUsesCaseStudy-librariesWrapper">
@@ -15,4 +16,5 @@
</ul>
<a class="WhoUsesCaseStudy-librariesViewMoreLink" href="{{.viewMoreUrl}}">View More</a>
</div>
-{{end}} \ No newline at end of file
+{{end}}
+{{end}}
diff --git a/go.dev/templates/pkg.tmpl b/go.dev/templates/pkg.tmpl
new file mode 100644
index 00000000..19d76302
--- /dev/null
+++ b/go.dev/templates/pkg.tmpl
@@ -0,0 +1,3 @@
+{{define "pkg path name?" -}}
+<a href="https://pkg.go.dev/{{.path}}?tab=overview">{{or .name .path}}</a>
+{{- end}}
diff --git a/go.dev/layouts/shortcodes/featuredProjects.html b/go.dev/templates/projects.tmpl
index 9d0be58c..2f9d07e1 100644
--- a/go.dev/layouts/shortcodes/featuredProjects.html
+++ b/go.dev/templates/projects.tmpl
@@ -1,4 +1,9 @@
-{{$featuredProjects := .Page.Param "featuredProjects"}}
+{{define "projects"}}
+{{$featuredProjects := .Param "featuredProjects"}}
+
+<div class="FeaturedUsers">
+
+<h2 id="featured-users" class="sectionHeading">Featured users</h2>
<table>
<thead>
@@ -8,12 +13,12 @@
<th>Projects using go</th>
</tr>
</thead>
-
<tbody>
- {{range $index, $project := $featuredProjects}}
+ {{- range $index, $project := $featuredProjects}}
<tr
class="js-featuredUsersRow FeaturedUsers-row"
- {{ if (gt $index 2) }} hidden {{end}}
+ {{- if (gt $index 2) }}
+ hidden {{end}}
>
<td class="FeaturedUsers--hiddenMobile">
<img src="/images/logos/{{.logoSrc}}" alt="{{.company}}" />
@@ -26,13 +31,13 @@
</td>
<td>
<ul>
- {{range .ctas}}
+ {{- range .ctas}}
<li><a href="{{.url}}">{{.text}}</a></li>
- {{end}}
+ {{- end}}
</ul>
</td>
</tr>
- {{end}}
+ {{- end}}
</tbody>
</table>
@@ -41,3 +46,6 @@
type="button">
More projects
</button>
+
+</div>
+{{end}}
diff --git a/go.dev/templates/pullquote.tmpl b/go.dev/templates/pullquote.tmpl
new file mode 100644
index 00000000..3cf8443f
--- /dev/null
+++ b/go.dev/templates/pullquote.tmpl
@@ -0,0 +1,34 @@
+{{define "pullquote info" -}}
+{{- with (yaml .info)}}
+<div class="PullQuote">
+ <div class="PullQuote-quoteHeader">
+ <img class="PullQuote-image" src="/images/quote.svg" alt="Quotation mark.">
+ </div>
+ <p class="PullQuote-body">
+ {{.quote | markdownify}}
+ </p>
+ {{- if .author}}
+ <div class="PullQuote-author">
+ {{- with .link}}
+ <a
+ class="PullQuote-link"
+ href="{{.}}"
+ target="_blank"
+ rel="noopener">
+ {{- end}}
+ <span>
+ &mdash; {{.author -}}
+ </span>
+ {{if .title}},&nbsp;
+ <span class="PullQuote-title">{{.title | safeHTML}}</span>
+ {{- end}}
+ {{- if .company}}
+ <span class="PullQuote-title">&nbsp;at {{.company -}}</span>
+ {{- end}}
+ {{- with .link}}</a>{{end}}
+ </div>
+ {{- end}}
+</div>
+{{- end}}
+{{end}}
+
diff --git a/go.dev/templates/quote.tmpl b/go.dev/templates/quote.tmpl
new file mode 100644
index 00000000..523e34ee
--- /dev/null
+++ b/go.dev/templates/quote.tmpl
@@ -0,0 +1,21 @@
+{{define "quote info" -}}
+{{- with (yaml .info)}}
+<div class="QuoteBlock">
+ <p class="QuoteBlock-body">
+ {{.quote | markdownify}}
+ </p>
+ {{- if .author}}
+ <div class="QuoteBlock-author">
+ {{- with .link}}
+ <a class="QuoteBlock-link" href="{{.}}" target="_blank" rel="noopener">
+ {{- end}}
+ &mdash; {{.author}}
+ {{- if .title}},&nbsp;<span>{{.title}}</span>{{end}}
+ {{- with .link}}
+ </a>
+ {{- end -}}
+ </div>
+ {{- end}}
+</div>
+{{- end}}
+{{end}}
diff --git a/go.dev/layouts/shortcodes/toolsBlurbs.html b/go.dev/templates/toolsblurbs.tmpl
index 0346548b..443c6080 100644
--- a/go.dev/layouts/shortcodes/toolsBlurbs.html
+++ b/go.dev/templates/toolsblurbs.tmpl
@@ -1,17 +1,20 @@
-{{$toolsBlurbs := .Page.Param "toolsBlurbs"}}
+{{define "toolsblurbs"}}
+{{$toolsBlurbs := .Param "toolsBlurbs"}}
<div class="ToolsBlurbs">
- {{range $toolsBlurbs}}
+ {{- range $toolsBlurbs}}
<div class="ToolsBlurbs-blurb">
<a class="ToolsBlurbs-blurbHeader" href="{{.url}}">
<img class="ToolsBlurbs-blurbIcon" src="{{.iconSrc}}" alt="{{.title}}">
<span>{{.title}}</span>
</a>
- {{range .paragraphs}}
+ {{- range .paragraphs}}
<p class="ToolsBlurbs-blurbBody">
- {{ . }}
+ {{.}}
</p>
- {{end}}
+ {{- end}}
</div>
- {{end}}
-</div> \ No newline at end of file
+ {{- end}}
+</div>
+
+{{end}}
diff --git a/go.dev/testdata/golden/solutions/clis/index.html b/go.dev/testdata/golden/solutions/clis/index.html
index cda49c85..a7ee6ed0 100644
--- a/go.dev/testdata/golden/solutions/clis/index.html
+++ b/go.dev/testdata/golden/solutions/clis/index.html
@@ -213,7 +213,8 @@
<h3 id="use-go-for-building-elegant-clis">Use Go for building elegant CLIs</h3>
-<a href="https://medium.com/@skdomino/writing-better-clis-one-snake-at-a-time-d22e50e60056" target="_blank" rel="noopener"><div class="BackgroundQuote">
+<div class="BackgroundQuote">
+<a href="https://medium.com/@skdomino/writing-better-clis-one-snake-at-a-time-d22e50e60056" target="_blank" rel="noopener">
<p class="BackgroundQuote-body">
“I was tasked with building our CLI tool and found two really great projects, Cobra and Viper, which make building CLI’s easy. Individually they are very powerful, very flexible and very good at what they do. But together they will help you show your next CLI who is boss!”
</p>
@@ -221,14 +222,14 @@
<span>&mdash; Steve Domino</span>
,&nbsp;
<span class="BackgroundQuote-title">senior engineer and architect at Strala</span>
- </div>
</div>
-
</a>
+</div>
-<a href="https://www.youtube.com/watch?v=WvWPGVKLvR4" target="_blank" rel="noopener"><div class="BackgroundQuote">
+<div class="BackgroundQuote">
+<a href="https://www.youtube.com/watch?v=WvWPGVKLvR4" target="_blank" rel="noopener">
<p class="BackgroundQuote-body">
“Cobra is a great product to write small tools or even large ones. It’s more of a framework than a library, because when you call the binary that would create a skeleton, then you would be adding code in between.””
</p>
@@ -237,18 +238,15 @@
,&nbsp;
<span class="BackgroundQuote-title">VP of product at DGraph Labs and producer of Just For Func videos</span>
</div>
- </div>
-
</a>
+</div>
<p>When developing CLIs in Go, two tools are widely used: Cobra &amp; Viper.</p>
-<p>
-<a href="https://pkg.go.dev/github.com/spf13/cobra?tab=overview">Cobra</a> is both a library for creating powerful modern CLI applications and a program to generate applications and CLI applications in Go. Cobra powers most of the popular Go applications including CoreOS, Delve, Docker, Dropbox, Git Lfs, Hugo, Kubernetes, and <a href="https://pkg.go.dev/github.com/spf13/cobra?tab=importedby" rel="noreferrer" target="_blank">many more</a>. With integrated command help, autocomplete and documentation “[it] makes documenting each command really simple,” says <a href="https://blog.alexellis.io/5-keys-to-a-killer-go-cli/" rel="noreferrer" target="_blank">Alex Ellis</a>, founder of OpenFaaS.</p>
+<p><a href="https://pkg.go.dev/github.com/spf13/cobra?tab=overview">Cobra</a> is both a library for creating powerful modern CLI applications and a program to generate applications and CLI applications in Go. Cobra powers most of the popular Go applications including CoreOS, Delve, Docker, Dropbox, Git Lfs, Hugo, Kubernetes, and <a href="https://pkg.go.dev/github.com/spf13/cobra?tab=importedby" rel="noreferrer" target="_blank">many more</a>. With integrated command help, autocomplete and documentation “[it] makes documenting each command really simple,” says <a href="https://blog.alexellis.io/5-keys-to-a-killer-go-cli/" rel="noreferrer" target="_blank">Alex Ellis</a>, founder of OpenFaaS.</p>
-<p>
-<a href="https://pkg.go.dev/github.com/spf13/viper?tab=overview">Viper</a> is a complete configuration solution for Go applications, designed to work within an app to handle configuration needs and formats. Cobra and Viper are designed to work together.</p>
+<p><a href="https://pkg.go.dev/github.com/spf13/viper?tab=overview">Viper</a> is a complete configuration solution for Go applications, designed to work within an app to handle configuration needs and formats. Cobra and Viper are designed to work together.</p>
<p>Viper <a href="https://scene-si.org/2017/04/20/managing-configuration-with-viper/" rel="noreferrer" target="_blank">supports nested structures</a> in the configuration, allowing CLI developers to manage the configuration for multiple parts of a large application. Viper also provides all of the tooling need to easily build twelve factor apps.</p>
@@ -467,8 +465,6 @@
<h3 id="go-books-for-creating-clis">Go books for creating CLIs</h3>
-<p>
-
<ul class="Learn-tileList">
<li class="Learn-tile">
@@ -581,7 +577,6 @@
</ul>
<a class="WhoUsesCaseStudy-librariesViewMoreLink" href="https://pkg.go.dev/search?q=command%20line%20OR%20CLI">View More</a>
</div>
-</p>
</div>
</div>
diff --git a/go.dev/testdata/golden/solutions/cloud/index.html b/go.dev/testdata/golden/solutions/cloud/index.html
index 871adfb3..8930bad8 100644
--- a/go.dev/testdata/golden/solutions/cloud/index.html
+++ b/go.dev/testdata/golden/solutions/cloud/index.html
@@ -471,8 +471,6 @@
<h3 id="go-books-for-cloud-computing">Go books for cloud computing</h3>
-<p>
-
<ul class="Learn-tileList">
<li class="Learn-tile">
@@ -695,7 +693,6 @@
</ul>
<a class="WhoUsesCaseStudy-librariesViewMoreLink" href="">View More</a>
</div>
-</p>
</div>
</div>
diff --git a/go.dev/testdata/golden/solutions/devops/index.html b/go.dev/testdata/golden/solutions/devops/index.html
index 45377af5..b4aac4f3 100644
--- a/go.dev/testdata/golden/solutions/devops/index.html
+++ b/go.dev/testdata/golden/solutions/devops/index.html
@@ -464,8 +464,6 @@ common needs like HTTP, file I/O, time, regular expressions, exec, and JSON/CSV
<h3 id="go-books-on-devops-sre">Go books on DevOps &amp; SRE</h3>
-<p>
-
<ul class="Learn-tileList">
<li class="Learn-tile">
@@ -593,7 +591,6 @@ common needs like HTTP, file I/O, time, regular expressions, exec, and JSON/CSV
</ul>
<a class="WhoUsesCaseStudy-librariesViewMoreLink" href="">View More</a>
</div>
-</p>
</div>
</div>
diff --git a/go.dev/testdata/golden/solutions/paypal/index.html b/go.dev/testdata/golden/solutions/paypal/index.html
index df3e0755..de7c4efc 100644
--- a/go.dev/testdata/golden/solutions/paypal/index.html
+++ b/go.dev/testdata/golden/solutions/paypal/index.html
@@ -214,13 +214,13 @@
- <img
+<p><img
loading="lazy"
width="607"
height="289"
class=""
alt="Go gopher factory"
- src="/images/gophers/factory.png">
+ src="/images/gophers/factory.png"></p>
<h2 id="modernizing-paypal-systems-with-go">Modernizing PayPal systems with Go</h2>
diff --git a/go.dev/testdata/golden/solutions/webdev/index.html b/go.dev/testdata/golden/solutions/webdev/index.html
index db5999ae..74d58123 100644
--- a/go.dev/testdata/golden/solutions/webdev/index.html
+++ b/go.dev/testdata/golden/solutions/webdev/index.html
@@ -413,8 +413,6 @@
<h3 id="go-books-on-web-development">Go books on web development</h3>
-<p>
-
<ul class="Learn-tileList">
<li class="Learn-tile">
@@ -650,7 +648,6 @@
</ul>
<a class="WhoUsesCaseStudy-librariesViewMoreLink" href="">View More</a>
</div>
-</p>
<h3 id="courses">Courses</h3>
@@ -661,8 +658,7 @@
<h3 id="projects">Projects</h3>
<ul>
-<li>
-<a href="https://pkg.go.dev/github.com/gopherjs/gopherjs?tab=overview">gopherjs</a>, a compiler from Go to JavaScript allowing developers to write front-end code in Go which will run in all browsers.</li>
+<li><a href="https://pkg.go.dev/github.com/gopherjs/gopherjs?tab=overview">gopherjs</a>, a compiler from Go to JavaScript allowing developers to write front-end code in Go which will run in all browsers.</li>
<li><a href="https://gohugo.io/" rel="noreferrer" target="_blank">Hugo</a>, The world’s fastest framework for building websites</li>
<li><a href="https://mattermost.com/" rel="noreferrer" target="_blank">Mattermost</a>, a flexible, open source messaging platform
that enables secure team collaboration</li>