socle

calling-card: pasted links unfurl into something

commit c45b00c46887fa5e59800f704744bb5f10113509 · parent 9f3639044e · browse this tree
Ximianth, 2026-10-30 14:41:52 UTC

meta description + OpenGraph tags on the entrance and repo homes:
the entrance introduces itself as the sitename's code host, a repo card
carries its configured description, and og:url states the canonical address
when a baseurl is configured.  Deeper pages are destinations, not cards.
Text only: og:image wants rasterization, and that is not worth a dependency.
diff --git a/chrome.go b/chrome.go
index 47f1d5e..5e2b67c 100644
--- a/chrome.go
+++ b/chrome.go
@@ -20,7 +20,12 @@ import (
 type pageData struct {
 	Title    string
 	SiteName string
-	Crumbs   []display.Crumb
+	// Desc, when set, emits the calling-card metas (description + OpenGraph):
+	// what a pasted link unfurls into.  Only the entrance and repo homes carry one;
+	// deeper pages are destinations, not cards.
+	Desc   string
+	Canon  string // the canonical URL for og:url, when a baseurl is configured
+	Crumbs []display.Crumb
 	Arc      []arcButton
 	ArcDrop  int  // the deepest button drop, so the arc region reserves room for it (transforms take no layout space)
 	Dawn     bool // true: the full dawn arc (repo home); false: the compact corner arc
@@ -76,7 +81,13 @@ var soclePageTmpl = template.Must(template.New("socle").Parse(`<!doctype html>
 <title>{{.Title}}</title>
 <link rel="stylesheet" href="/-/style.css">
 <link rel="icon" type="image/svg+xml" href="/-/sketch/favicon.svg">
-</head>
+{{if .Desc}}<meta name="description" content="{{.Desc}}">
+<meta property="og:type" content="website">
+<meta property="og:site_name" content="{{.SiteName}}">
+<meta property="og:title" content="{{.Title}}">
+<meta property="og:description" content="{{.Desc}}">
+{{if .Canon}}<meta property="og:url" content="{{.Canon}}">
+{{end}}{{end}}</head>
 <body>
 <div class="flank left"></div><div class="flank right"></div>
 <div class="sheet">
diff --git a/pages.go b/pages.go
index 139b168..580b4b8 100644
--- a/pages.go
+++ b/pages.go
@@ -127,10 +127,15 @@ func (s *server) serveIndex(w http.ResponseWriter, r *http.Request, snap *snapsh
 		}
 		rows = append(rows, row)
 	}
-	s.render(w, snap, indexTmpl, rows, pageData{
+	pd := pageData{
 		Title:  snap.face.siteName,
+		Desc:   "the " + snap.face.siteName + " code host: git repositories to browse and clone",
 		Crumbs: []display.Crumb{{Name: snap.face.siteName}},
-	})
+	}
+	if snap.baseURL != "" {
+		pd.Canon = snap.baseURL + "/"
+	}
+	s.render(w, snap, indexTmpl, rows, pd)
 }
 
 // ---- repo home ----
@@ -265,8 +270,15 @@ func (s *server) serveHome(w http.ResponseWriter, r *http.Request, snap *snapsho
 	}
 	pd := pageData{
 		Title:  rp.name,
+		Desc:   rp.description,
 		Crumbs: repoCrumbs(snap.face.siteName, rp.name),
 	}
+	if pd.Desc == "" {
+		pd.Desc = "a git repository on display at " + snap.face.siteName
+	}
+	if snap.baseURL != "" {
+		pd.Canon = snap.baseURL + "/" + rp.name + "/"
+	}
 	// No clone button on the arc: the clone line sits right below it in the vitals card,
 	// and a button that scrolls to something already in view is a non-move.
 	if !d.Empty {
diff --git a/serve_test.go b/serve_test.go
index 4f8f2d8..f0fde18 100644
--- a/serve_test.go
+++ b/serve_test.go
@@ -312,6 +312,10 @@ func TestGoGetMeta(t *testing.T) {
 			t.Errorf("GET %s: body lacks the go-source tag\nwant: %s", target, wantSource)
 		}
 	}
+	// With a baseurl, the calling-card metas carry the canonical og:url.
+	if rec := do(s, "/fixturama/", nil, nil); !strings.Contains(rec.Body.String(), `<meta property="og:url" content="https://code.example/fixturama/">`) {
+		t.Errorf("repo home lacks the canonical og:url meta")
+	}
 	// The configured address also becomes the displayed clone URL.
 	if body := do(s, "/fixturama/", nil, nil).Body.String(); !strings.Contains(body, "git clone https://code.example/fixturama") {
 		t.Errorf("home page clone line does not use the configured baseurl")
diff --git a/testdata/pages.md b/testdata/pages.md
index b83feb6..90fea16 100644
--- a/testdata/pages.md
+++ b/testdata/pages.md
@@ -31,6 +31,11 @@ Content-Type: text/html; charset=utf-8
 <title>test</title>
 <link rel="stylesheet" href="/-/style.css">
 <link rel="icon" type="image/svg+xml" href="/-/sketch/favicon.svg">
+<meta name="description" content="the test code host: git repositories to browse and clone">
+<meta property="og:type" content="website">
+<meta property="og:site_name" content="test">
+<meta property="og:title" content="test">
+<meta property="og:description" content="the test code host: git repositories to browse and clone">
 </head>
 <body>
 <div class="flank left"></div><div class="flank right"></div>
@@ -81,6 +86,11 @@ Content-Type: text/html; charset=utf-8
 <title>fixturama</title>
 <link rel="stylesheet" href="/-/style.css">
 <link rel="icon" type="image/svg+xml" href="/-/sketch/favicon.svg">
+<meta name="description" content="the fixture">
+<meta property="og:type" content="website">
+<meta property="og:site_name" content="test">
+<meta property="og:title" content="fixturama">
+<meta property="og:description" content="the fixture">
 </head>
 <body>
 <div class="flank left"></div><div class="flank right"></div>