Skip to content

Commit 1786184

Browse files
authored
Merge pull request #77 from OurSQLFoundation/fix/broken-term-and-hub-links
Fix 404s on tag chips containing "&" and homepage member-directory links
2 parents c356e6b + fdbc9dd commit 1786184

6 files changed

Lines changed: 76 additions & 5 deletions

File tree

‎layouts/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@ <h2>A living map of the MySQL ecosystem</h2>
137137
</div>
138138

139139
<div class="universe-categories">
140-
<a href="/resources/member-directory/" class="universe-cat universe-cat--cyan">
140+
<a href="/member-directory/" class="universe-cat universe-cat--cyan">
141141
<span class="universe-cat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg></span>
142142
<span class="universe-cat-title">People</span>
143143
<span class="universe-cat-desc">Contributors, speakers, authors & experts</span>
144144
</a>
145-
<a href="/resources/member-directory/" class="universe-cat universe-cat--blue">
145+
<a href="/member-directory/" class="universe-cat universe-cat--blue">
146146
<span class="universe-cat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="7" width="20" height="14" rx="2"></rect><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path></svg></span>
147147
<span class="universe-cat-title">Organizations</span>
148148
<span class="universe-cat-desc">Vendors, adopters & service providers</span>

‎layouts/partials/resources/tag-chips.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@
3434
{{ end }}
3535
{{ with $chips }}
3636
<div class="resource-tags">
37-
{{ range . }}<a href="{{ printf "/%s/" .path | relURL }}{{ .value | urlize }}/" class="resource-tag">{{ .value }}</a>{{ end }}
37+
{{ range . }}<a href="{{ partialCached "resources/term-url.html" . .path .value }}" class="resource-tag">{{ .value }}</a>{{ end }}
3838
</div>
3939
{{ end }}

‎layouts/partials/resources/term-content.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ <h2 class="resource-card-title">{{ .Title }}</h2>
7272
{{ end }}
7373
{{ with .Params.subcategories }}
7474
<div class="resource-tags">
75-
{{ range . }}<a href="{{ "/subcategories/" | relURL }}{{ . | urlize }}/" class="resource-tag">{{ . }}</a>{{ end }}
75+
{{ range . }}<a href="{{ partialCached "resources/term-url.html" (dict "path" "subcategories" "value" .) "subcategories" . }}" class="resource-tag">{{ . }}</a>{{ end }}
7676
</div>
7777
{{ end }}
7878
</div>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{{/*
2+
Returns the URL of a taxonomy term page. Input: dict "path" "value", e.g.
3+
(dict "path" "subcategories" "value" "Database Management & GUI").
4+
5+
Don't build these links with `urlize`: Hugo names the generated term
6+
directory differently from what `urlize` returns whenever the value has
7+
punctuation ("Database Management & GUI" is generated at
8+
/subcategories/database-management--gui/, `urlize` gives
9+
database-management-gui), so every such link 404s. Asking the term page for
10+
its own RelPermalink can't drift out of sync with what Hugo emits.
11+
*/}}
12+
{{ $url := "" }}
13+
{{ with site.GetPage (printf "/%s" .path) }}
14+
{{ range .Pages }}
15+
{{ if eq (lower .Title) (lower $.value) }}{{ $url = .RelPermalink }}{{ end }}
16+
{{ end }}
17+
{{ end }}
18+
{{ if not $url }}{{ $url = printf "/%s/%s/" .path (.value | urlize) | relURL }}{{ end }}
19+
{{ return $url }}

‎layouts/resources/list.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ <h2 class="resource-card-title">{{ .Title }}</h2>
306306
{{ end }}
307307
{{ with $chips }}
308308
<div class="resource-tags">
309-
{{ range first 2 . }}<a href="{{ printf "/%s/" .path | relURL }}{{ .value | urlize }}/" class="resource-tag">{{ .value }}</a>{{ end }}
309+
{{ range first 2 . }}<a href="{{ partialCached "resources/term-url.html" . .path .value }}" class="resource-tag">{{ .value }}</a>{{ end }}
310310
</div>
311311
{{ end }}
312312
</div>

‎tools/check-internal-links.py‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python3
2+
"""Fail if any internal link in the built site points at a page that doesn't exist.
3+
4+
Usage: hugo --minify && python3 tools/check-internal-links.py [public]
5+
6+
Checks every href in the generated HTML plus the <loc> URLs in the sitemap
7+
(relative and absolute oursqlfoundation.org links alike).
8+
"""
9+
import collections
10+
import os
11+
import re
12+
import sys
13+
import urllib.parse
14+
15+
ROOT = sys.argv[1] if len(sys.argv) > 1 else "public"
16+
HOSTS = ("oursqlfoundation.org",)
17+
18+
19+
def exists(path):
20+
cand = os.path.join(ROOT, urllib.parse.unquote(path).lstrip("/"))
21+
return os.path.isfile(cand) or os.path.isfile(os.path.join(cand, "index.html"))
22+
23+
24+
def normalize(href):
25+
m = re.match(r"^https?://(?:www\.)?([^/]+)(/.*)?$", href)
26+
if m:
27+
return (m.group(2) or "/") if m.group(1) in HOSTS else None
28+
return href if href.startswith("/") and not href.startswith("//") else None
29+
30+
31+
broken = collections.defaultdict(set)
32+
checked = 0
33+
for dirpath, _, files in os.walk(ROOT):
34+
for name in files:
35+
if not name.endswith((".html", ".xml")):
36+
continue
37+
path = os.path.join(dirpath, name)
38+
text = open(path, encoding="utf-8", errors="ignore").read()
39+
refs = re.findall(r'href="?([^"\s>]+)', text)
40+
if name.endswith(".xml"):
41+
refs += re.findall(r"<loc>([^<]+)</loc>", text)
42+
for raw in refs:
43+
href = normalize(raw.split("#")[0].split("?")[0])
44+
if href:
45+
checked += 1
46+
if not exists(href):
47+
broken[href].add(os.path.relpath(path, ROOT))
48+
49+
print(f"links checked: {checked} | distinct broken: {len(broken)}")
50+
for href, pages in sorted(broken.items()):
51+
print(f" {href} <- {len(pages)} page(s), e.g. {sorted(pages)[0]}")
52+
sys.exit(1 if broken else 0)

0 commit comments

Comments
 (0)