80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package build
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"html/template"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.coffeylabs.org/coffey-labs/hotdog-cms/internal/site"
|
|
)
|
|
|
|
// Search engines: verification meta tags, and what IndexNow needs. Every
|
|
// build writes a manifest of its pages and a hash of each, so publishing can
|
|
// tell search engines exactly which pages changed (internal/publish).
|
|
|
|
// PagesManifest is the file listing a build's pages: "address<TAB>hash".
|
|
const PagesManifest = ".hotdog-cms-pages"
|
|
|
|
// IndexNowFile is the build's note of its IndexNow key and address.
|
|
const IndexNowFile = ".hotdog-cms-indexnow"
|
|
|
|
// IndexNowInfo is what IndexNowFile holds.
|
|
type IndexNowInfo struct {
|
|
Key string `json:"key"`
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
func verificationTags(cfg *site.Config) template.HTML {
|
|
var b strings.Builder
|
|
for _, kv := range [][2]string{{"google-site-verification", cfg.Verify.Google}, {"msvalidate.01", cfg.Verify.Bing}, {"yandex-verification", cfg.Verify.Yandex}} {
|
|
if kv[1] != "" {
|
|
b.WriteString(`<meta name="` + kv[0] + `" content="` + template.HTMLEscapeString(kv[1]) + `">`)
|
|
}
|
|
}
|
|
return template.HTML(b.String())
|
|
}
|
|
|
|
// writeSearchFiles writes the pages manifest, and the IndexNow key file and
|
|
// note when the site has a key.
|
|
func writeSearchFiles(out string, cfg *site.Config) error {
|
|
var lines []string
|
|
err := filepath.WalkDir(out, func(p string, d fs.DirEntry, err error) error {
|
|
if err != nil || d.IsDir() || !strings.HasSuffix(p, ".html") {
|
|
return err
|
|
}
|
|
data, err := os.ReadFile(p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if strings.Contains(string(data[:min(len(data), 512)]), `http-equiv="refresh"`) {
|
|
return nil // a redirect, not a page
|
|
}
|
|
rel, _ := filepath.Rel(out, p)
|
|
u := "/" + strings.TrimSuffix(filepath.ToSlash(rel), "index.html")
|
|
sum := sha256.Sum256(data)
|
|
lines = append(lines, u+"\t"+hex.EncodeToString(sum[:12]))
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sort.Strings(lines)
|
|
if err := os.WriteFile(filepath.Join(out, PagesManifest), []byte(strings.Join(lines, "\n")+"\n"), 0o644); err != nil {
|
|
return err
|
|
}
|
|
if k := cfg.IndexNow.Key; k != "" {
|
|
if err := os.WriteFile(filepath.Join(out, k+".txt"), []byte(k), 0o644); err != nil {
|
|
return err
|
|
}
|
|
note, _ := json.Marshal(IndexNowInfo{Key: k, URL: cfg.URL})
|
|
return os.WriteFile(filepath.Join(out, IndexNowFile), note, 0o644)
|
|
}
|
|
return nil
|
|
}
|