hugo: tag-based post connections
• 247 words • 2 min
Problem statement: post connections showed only direct links, while posts with the same tags remained disconnected in the graph of this blog.
I added a second kind of edge. The pre-computation picks up to two posts with the most shared tags, breaks ties by date, and excludes direct links:
ci/precompute_links.py
python
def compute_tag_related_posts(
post: dict,
all_posts: list[dict],
outlinks_set: set[str],
backlinks_set: set[str],
limit: int = 2,
) -> list[str]:
"""Compute tag connections, excluding posts with direct links."""
post_tags = set(post["tags"])
if not post_tags:
return []
direct_ids = outlinks_set | backlinks_set
scored = []
for other in all_posts:
other_id = other["id"]
if other_id == post["id"] or other_id in direct_ids:
continue
shared_tags = post_tags & set(other["tags"])
if shared_tags:
scored.append((other_id, len(shared_tags), other["date"]))
scored.sort(key=lambda item: (item[1], item[2], item[0]), reverse=True)
return [item[0] for item in scored[:limit]]Direct links remain solid and prominent. Shared-tag links use smaller arrows with dashed, muted edges:
layouts/partials/style.html
css
.mini-graph .mini-graph-direct-edge {
fill: none;
stroke: var(--link-color);
stroke-width: 2.25;
stroke-opacity: 0.9;
}
.mini-graph .mini-graph-tag-edge {
fill: none;
stroke: var(--color-gray);
stroke-width: 1;
stroke-dasharray: 4 4;
stroke-opacity: 0.65;
}The original Anki post now gets one direct link and two tag connections:
json
{
"outlinks": ["2024-12-23-anki-workflow"],
"tag_related": [
"2026-04-15-anki-flashcards-with-claude-code",
"2026-04-13-anki-api-access"
]
}
shell
% python3 ci/test_precompute_links.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OKThere’s a limit of 2 shared tag post edges for the sake of not visually polluting the presentation.
I’ve been loving how this little blog is evolving into my beloved (public) digital garden.
🤖 Drafted with /bloggify. ∎