internal/blog: populate author names in feeds

Go blog posts have metadata like:

by:
- Author Name
- Maybe Another Author

Those YAML lists were decoded into a slice of empty interfaces, each
holding a string, and all that was being ignored. Update it to parse
the []any type of p["by"] and to return an error if there aren't any
authors. There are only 2 existing blog posts that cause such errors,
but they're very old and can be ignored (or updated if needed).

There's probably more that can be done, like having one <author> XML
item per 'by' item in the YAML/JSON metadata of blog posts, but this
is a reasonable step forward.

For golang/go#68869.

Change-Id: I7b97a09b006bacf4835442a749cb0e467c7dbb47
Reviewed-on: https://go-review.googlesource.com/c/website/+/605537
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Hongxiang Jiang <hxjiang@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
Dmitri Shuralyov 2024-08-14 20:10:29 -04:00 коммит произвёл Gopher Robot
Родитель 702685aefd
Коммит d43f0ec556
2 изменённых файлов: 28 добавлений и 10 удалений

1
cmd/golangorg/testdata/blog.txt поставляемый
Просмотреть файл

@ -41,6 +41,7 @@ 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>
body !contains <author><name></name></author>
GET https://go.dev/blog/.json
header Content-Type == application/json; charset=utf-8

Просмотреть файл

@ -7,6 +7,7 @@ package blog
import (
"encoding/json"
"encoding/xml"
"fmt"
"html"
"io"
"net/http"
@ -49,7 +50,10 @@ func atomFeed(site *web.Site) ([]byte, error) {
url, _ := p["URL"].(string)
date, _ := p["date"].(time.Time)
summary, _ := p["summary"].(string)
by, _ := p["by"].([]string)
authors, err := authors(p)
if err != nil {
return nil, fmt.Errorf("there's a problem in the 'by' metadata of the blog post file %v: %v", p["File"], err)
}
content, err := site.RenderContent(p, "blogfeed.tmpl")
if err != nil {
return nil, err
@ -73,7 +77,7 @@ func atomFeed(site *web.Site) ([]byte, error) {
Body: string(content),
},
Author: &atom.Person{
Name: authors(by),
Name: authors,
},
}
feed.Entry = append(feed.Entry, e)
@ -105,7 +109,10 @@ func jsonFeed(site *web.Site) ([]byte, error) {
url, _ := p["URL"].(string)
date, _ := p["date"].(time.Time)
summary, _ := p["summary"].(string)
by, _ := p["by"].([]string)
authors, err := authors(p)
if err != nil {
return nil, fmt.Errorf("there's a problem in the 'by' metadata of the blog post file %v: %v", p["File"], err)
}
content, err := site.RenderContent(p, "blogfeed.tmpl")
if err != nil {
return nil, err
@ -116,7 +123,7 @@ func jsonFeed(site *web.Site) ([]byte, error) {
Time: date,
Summary: summary,
Content: string(content),
Author: authors(by),
Author: authors,
}
feed = append(feed, item)
}
@ -147,16 +154,26 @@ func feedPages(site *web.Site) ([]web.Page, error) {
return pages, nil
}
func authors(by []string) string {
func authors(p web.Page) (string, error) {
byAny, _ := p["by"].([]any)
if len(byAny) == 0 {
return "", fmt.Errorf("no author specified")
}
var by []string
for _, b := range byAny {
s, ok := b.(string)
if !ok {
return "", fmt.Errorf("author entry %q type is %[1]T, want string", b)
}
by = append(by, s)
}
switch len(by) {
case 0:
return ""
case 1:
return by[0]
return by[0], nil
case 2:
return by[0] + " and " + by[1]
return by[0] + " and " + by[1], nil
default:
return strings.Join(by[:len(by)-1], ", ") + ", and " + by[len(by)-1]
return strings.Join(by[:len(by)-1], ", ") + ", and " + by[len(by)-1], nil
}
}