diff --git a/src/content/posts/gitops-with-flux-cd.md b/src/content/posts/gitops-with-flux-cd.md index 9c5b74e..32ba7a3 100644 --- a/src/content/posts/gitops-with-flux-cd.md +++ b/src/content/posts/gitops-with-flux-cd.md @@ -11,6 +11,9 @@ tags: - ci-cd - automation readTime: 10 min read +related_posts: + - k3s-cluster + - gitea-self-hosted-git --- # GitOps with Flux CD diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index ffc17fa..db64706 100644 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -63,7 +63,9 @@ const graphData = { edges: [] }; -// Create edges between posts and their tags +// Create edges between posts and their tags, and between related posts +const processedPostPairs = new Set(); // Keep track of processed pairs to avoid duplicate edges + sortedPosts .filter(post => !post.data.draft) .forEach(post => { @@ -78,22 +80,59 @@ sortedPosts strength: 1 }); }); - - // Check if post references other posts (optional) - // This requires a related_posts field in frontmatter - if (post.data.related_posts && Array.isArray(post.data.related_posts)) { - post.data.related_posts.forEach(relatedSlug => { - // Make sure related post exists - if (sortedPosts.some(p => p.slug === relatedSlug)) { - graphData.edges.push({ - source: post.slug, - target: relatedSlug, - type: 'post-post', - strength: 2 - }); - } - }); + + // --- Combined Related Posts Logic --- + let explicitRelatedSlugs = new Set(post.data.related_posts || []); + let relatedPostsForGraph = []; + + // 1. Add explicitly related posts + explicitRelatedSlugs.forEach(relatedSlug => { + const relatedPost = sortedPosts.find(p => p.slug === relatedSlug && !p.data.draft); + if (relatedPost) { + relatedPostsForGraph.push(relatedPost); + } + }); + + // 2. Add implicitly related posts by tag similarity (if needed, up to a limit, e.g., 3 total) + const MAX_RELATED = 3; // Max related posts to show connections for + const MIN_SHARED_TAGS = 2; // Minimum shared tags for implicit relation + + if (relatedPostsForGraph.length < MAX_RELATED && postTags.length > 0) { + sortedPosts + .filter(otherPost => + !otherPost.data.draft && + otherPost.slug !== post.slug && // Not the same post + !explicitRelatedSlugs.has(otherPost.slug) && // Not already explicitly related + !relatedPostsForGraph.some(rp => rp.slug === otherPost.slug) // Not already added + ) + .forEach(otherPost => { + if (relatedPostsForGraph.length >= MAX_RELATED) return; // Stop if we have enough + + const otherTags = otherPost.data.tags || []; + const sharedTags = postTags.filter(tag => otherTags.includes(tag)); + + if (sharedTags.length >= MIN_SHARED_TAGS) { + relatedPostsForGraph.push(otherPost); + } + }); } + + // 3. Create edges for all found related posts (explicit + implicit) + relatedPostsForGraph.forEach(relatedPost => { + const pairKey1 = `${post.slug}-${relatedPost.slug}`; + const pairKey2 = `${relatedPost.slug}-${post.slug}`; + + // Avoid duplicate edges (A->B and B->A) + if (!processedPostPairs.has(pairKey1) && !processedPostPairs.has(pairKey2)) { + graphData.edges.push({ + source: post.slug, + target: relatedPost.slug, + type: 'post-post', // Use consistent type + strength: explicitRelatedSlugs.has(relatedPost.slug) ? 3 : 1.5 // Stronger link if explicit + }); + processedPostPairs.add(pairKey1); // Mark pair as processed + } + }); }); // Terminal commands for tech effect