From b64e9e1bc9269e78d4bfafe7c8d3a06066026d64 Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Wed, 15 Oct 2025 16:33:22 +0300 Subject: [PATCH] appview/pages: seo improvements, sitemap, schemae and more Change-Id: xzpvnptzsmkyvnrspootptpsutyrxxyv Signed-off-by: Anirudh Oppiliappan --- appview/pages/repoinfo/repoinfo.go | 46 ++++++++++++++++ .../pages/templates/fragments/breadcrumb.html | 22 ++++++++ .../pages/templates/fragments/dolly/logo.html | 46 ++++++++++++++++ .../pages/templates/fragments/dolly/logo.svg | 44 +++++++++++++++ .../templates/goodfirstissues/index.html | 29 +++++++++- appview/pages/templates/layouts/base.html | 28 +++++++++- .../pages/templates/layouts/profilebase.html | 21 +++++++- appview/pages/templates/repo/index.html | 36 +++++++++++++ .../templates/repo/issues/fragments/og.html | 19 ------- .../templates/repo/pulls/fragments/og.html | 32 +++++------ appview/pages/templates/timeline/home.html | 52 ++++++++++++++++-- appview/state/router.go | 1 + appview/state/state.go | 53 +++++++++++++++++++ 13 files changed, 386 insertions(+), 43 deletions(-) create mode 100644 appview/pages/templates/fragments/breadcrumb.html create mode 100644 appview/pages/templates/fragments/dolly/logo.svg delete mode 100644 appview/pages/templates/repo/issues/fragments/og.html diff --git a/appview/pages/repoinfo/repoinfo.go b/appview/pages/repoinfo/repoinfo.go index f5b505bb..20121d65 100644 --- a/appview/pages/repoinfo/repoinfo.go +++ b/appview/pages/repoinfo/repoinfo.go @@ -1,6 +1,7 @@ package repoinfo import ( + "encoding/json" "fmt" "path" "slices" @@ -117,3 +118,48 @@ func (r RolesInRepo) IsCollaborator() bool { func (r RolesInRepo) IsPushAllowed() bool { return slices.Contains(r.Roles, "repo:push") } + +// PrimaryLanguage returns the first (most used) language from a list, or empty string if none +func PrimaryLanguage(languages []interface{}) string { + if len(languages) == 0 { + return "" + } + + // Languages are already sorted by percentage in descending order + // Just get the first one + if firstLang, ok := languages[0].(map[string]interface{}); ok { + if name, ok := firstLang["Name"].(string); ok { + return name + } + } + + return "" +} + +// StructuredData generates Schema.org JSON-LD structured data for the repository +func (r RepoInfo) StructuredData(primaryLanguage string) string { + data := map[string]interface{}{ + "@context": "https://schema.org", + "@type": "SoftwareSourceCode", + "name": r.Name, + "description": r.Description, + "codeRepository": "https://tangled.org/" + r.FullName(), + "url": "https://tangled.org/" + r.FullName(), + "author": map[string]interface{}{ + "@type": "Person", + "name": r.owner(), + "url": "https://tangled.org/" + r.owner(), + }, + } + + // Add programming language if available + if primaryLanguage != "" { + data["programmingLanguage"] = primaryLanguage + } + + jsonBytes, err := json.Marshal(data) + if err != nil { + return "{}" + } + return string(jsonBytes) +} diff --git a/appview/pages/templates/fragments/breadcrumb.html b/appview/pages/templates/fragments/breadcrumb.html new file mode 100644 index 00000000..68297379 --- /dev/null +++ b/appview/pages/templates/fragments/breadcrumb.html @@ -0,0 +1,22 @@ +{{ define "fragments/breadcrumb" }} + {{ $items := . }} + {{ if gt (len $items) 0 }} + + {{ end }} +{{ end }} \ No newline at end of file diff --git a/appview/pages/templates/fragments/dolly/logo.html b/appview/pages/templates/fragments/dolly/logo.html index ee651e4e..ac90bd85 100644 --- a/appview/pages/templates/fragments/dolly/logo.html +++ b/appview/pages/templates/fragments/dolly/logo.html @@ -81,4 +81,50 @@ +%%%%%%% Changes from base to side #2 + + Dolly + + + + + + + + {{ end }} diff --git a/appview/pages/templates/fragments/dolly/logo.svg b/appview/pages/templates/fragments/dolly/logo.svg new file mode 100644 index 00000000..a3f1891d --- /dev/null +++ b/appview/pages/templates/fragments/dolly/logo.svg @@ -0,0 +1,44 @@ + + Dolly + + + + + + + + diff --git a/appview/pages/templates/goodfirstissues/index.html b/appview/pages/templates/goodfirstissues/index.html index b4fa8dd1..255b6b84 100644 --- a/appview/pages/templates/goodfirstissues/index.html +++ b/appview/pages/templates/goodfirstissues/index.html @@ -1,12 +1,37 @@ {{ define "title" }}good first issues{{ end }} {{ define "extrameta" }} + + + - + - + + + + + + + + {{ end }} +{{ define "canonical" }}https://tangled.org/goodfirstissues{{ end }} + {{ define "content" }}
diff --git a/appview/pages/templates/layouts/base.html b/appview/pages/templates/layouts/base.html index f357201d..be098908 100644 --- a/appview/pages/templates/layouts/base.html +++ b/appview/pages/templates/layouts/base.html @@ -4,8 +4,13 @@ - + + + + + + @@ -15,6 +20,9 @@ + + {{ block "rss" . }}{{ end }} + @@ -22,7 +30,23 @@ - {{ block "title" . }}{{ end }} · tangled + {{ block "title" . }}{{ end }} + + + {{ block "structuredData" . }} + + {{ end }} + {{ block "extrameta" . }}{{ end }} diff --git a/appview/pages/templates/layouts/profilebase.html b/appview/pages/templates/layouts/profilebase.html index 0747a39f..3a646a7d 100644 --- a/appview/pages/templates/layouts/profilebase.html +++ b/appview/pages/templates/layouts/profilebase.html @@ -10,11 +10,30 @@ - + + + + +{{ end }} + +{{ define "canonical" }}https://tangled.org/{{ or .Card.UserHandle .Card.UserDid }}{{ end }} + +{{ define "rss" }} + {{ end }} {{ define "content" }} diff --git a/appview/pages/templates/repo/index.html b/appview/pages/templates/repo/index.html index 1144e8d1..605bfa7e 100644 --- a/appview/pages/templates/repo/index.html +++ b/appview/pages/templates/repo/index.html @@ -5,6 +5,42 @@ {{ template "repo/fragments/meta" . }} {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} + + + + + + {{ template "fragments/breadcrumb" (list + (list "Home" "https://tangled.org") + (list .RepoInfo.OwnerWithAt (printf "https://tangled.org/%s" .RepoInfo.OwnerWithAt)) + (list .RepoInfo.Name (printf "https://tangled.org/%s" .RepoInfo.FullName)) + ) }} +{{ end }} + +{{ define "canonical" }}https://tangled.org/{{ .RepoInfo.FullName }}{{ end }} + +{{ define "rss" }} + {{ end }} {{ define "repoContent" }} diff --git a/appview/pages/templates/repo/issues/fragments/og.html b/appview/pages/templates/repo/issues/fragments/og.html deleted file mode 100644 index 3e1794a7..00000000 --- a/appview/pages/templates/repo/issues/fragments/og.html +++ /dev/null @@ -1,19 +0,0 @@ -{{ define "repo/issues/fragments/og" }} - {{ $title := printf "%s #%d" .Issue.Title .Issue.IssueId }} - {{ $description := or .Issue.Body .RepoInfo.Description }} - {{ $url := printf "https://tangled.org/%s/issues/%d" .RepoInfo.FullName .Issue.IssueId }} - {{ $imageUrl := printf "https://tangled.org/%s/issues/%d/opengraph" .RepoInfo.FullName .Issue.IssueId }} - - - - - - - - - - - - - -{{ end }} diff --git a/appview/pages/templates/repo/pulls/fragments/og.html b/appview/pages/templates/repo/pulls/fragments/og.html index 58f25035..ad8a00e8 100644 --- a/appview/pages/templates/repo/pulls/fragments/og.html +++ b/appview/pages/templates/repo/pulls/fragments/og.html @@ -1,19 +1,19 @@ -{{ define "repo/pulls/fragments/og" }} - {{ $title := printf "%s #%d" .Pull.Title .Pull.PullId }} - {{ $description := or .Pull.Body .RepoInfo.Description }} - {{ $url := printf "https://tangled.org/%s/pulls/%d" .RepoInfo.FullName .Pull.PullId }} - {{ $imageUrl := printf "https://tangled.org/%s/pulls/%d/opengraph" .RepoInfo.FullName .Pull.PullId }} + {{ define "pulls/fragments/og" }} + {{ $title := printf "%s #%d" .Pull.Title .Pull.PullId }} + {{ $description := or .Pull.Body .RepoInfo.Description }} + {{ $url := printf "https://tangled.org/%s/pulls/%d" .RepoInfo.FullName .Pull.PullId }} + {{ $imageUrl := printf "https://tangled.org/%s/pulls/%d/opengraph" .RepoInfo.FullName .Pull.PullId }} - - - - - - - + + + + + + + - - - - + + + + {{ end }} diff --git a/appview/pages/templates/timeline/home.html b/appview/pages/templates/timeline/home.html index febf520e..6e098d82 100644 --- a/appview/pages/templates/timeline/home.html +++ b/appview/pages/templates/timeline/home.html @@ -1,12 +1,58 @@ {{ define "title" }}tangled · tightly-knit social coding{{ end }} {{ define "extrameta" }} - - + {{ $desc := "Collaborate on code with decentralized git hosting, modern contribution and review workflows, and lightweight CI/CD pipelines." }} + {{ $title = "tangled · tightly-knit social coding" }} + + + + - + + + + + + + + + + + + + {{ end }} +{{ define "canonical" }}https://tangled.org{{ end }} + {{ define "content" }}
diff --git a/appview/state/router.go b/appview/state/router.go index 968ed403..9b792e11 100644 --- a/appview/state/router.go +++ b/appview/state/router.go @@ -36,6 +36,7 @@ func (s *State) Router() http.Handler { router.Get("/favicon.ico", s.Favicon) router.Get("/pwa-manifest.json", s.PWAManifest) router.Get("/robots.txt", s.RobotsTxt) + router.Get("/sitemap.xml", s.Sitemap) userRouter := s.UserRouter(&middleware) standardRouter := s.StandardRouter(&middleware) diff --git a/appview/state/state.go b/appview/state/state.go index aeef9f78..adc673d9 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -220,10 +220,63 @@ func (s *State) RobotsTxt(w http.ResponseWriter, r *http.Request) { robotsTxt := `User-agent: * Allow: / +Disallow: /settings +Disallow: /notifications +Disallow: /login +Disallow: /logout +Disallow: /signup +Disallow: /oauth +Disallow: */settings$ +Disallow: */settings/* + +Crawl-delay: 1 + +Sitemap: https://tangled.org/sitemap.xml ` w.Write([]byte(robotsTxt)) } +func (s *State) Sitemap(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/xml; charset=utf-8") + w.Header().Set("Cache-Control", "public, max-age=3600") + + // basic sitemap with static pages + sitemap := ` + + + https://tangled.org + daily + 1.0 + + + https://tangled.org/timeline + hourly + 0.9 + + + https://tangled.org/goodfirstissues + daily + 0.8 + + + https://tangled.org/terms + monthly + 0.3 + + + https://tangled.org/privacy + monthly + 0.3 + + + https://tangled.org/brand + monthly + 0.5 + +` + w.Write([]byte(sitemap)) +} + // https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest const manifestJson = `{ "name": "tangled", -- 2.43.0