thiagowfx's avatar

¬ just serendipity 🍀 (not just serendipity)

hugo: tag-based post connections

• 247 words • 2 min

Previously.

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

OK

There’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.