feat: See Also includes in-text links to other blog posts
Adds seeAlsoLinks filter that extracts all internal blog.giersig.eu links from the raw markdown source and merges them with the explicit `related` frontmatter field, deduplicated. The section now surfaces automatically whenever an article links to another post inline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -128,12 +128,13 @@ withBlogSidebar: true
|
||||
</details>
|
||||
{% endif %}
|
||||
|
||||
{# See Also — related posts from frontmatter (resolved wikilinks → URLs) #}
|
||||
{% if related and related.length > 0 %}
|
||||
{# See Also — explicit related: frontmatter + in-text links to other blog posts #}
|
||||
{% set _seeAlso = page.inputPath | seeAlsoLinks(related) %}
|
||||
{% if _seeAlso.length > 0 %}
|
||||
<section class="post-related mt-6 pt-5 border-t border-surface-200 dark:border-surface-700">
|
||||
<h2 class="text-xs font-semibold text-surface-500 dark:text-surface-400 uppercase tracking-widest mb-3">See Also</h2>
|
||||
<ul class="space-y-1.5 list-none p-0 m-0">
|
||||
{% for relUrl in related %}
|
||||
{% for relUrl in _seeAlso %}
|
||||
{% set _relPost = collections.posts | postByUrl(relUrl) %}
|
||||
<li>
|
||||
<a href="{{ relUrl }}" class="text-sm text-accent-700 dark:text-accent-300 hover:underline">
|
||||
|
||||
@@ -1119,6 +1119,26 @@ export default function (eleventyConfig) {
|
||||
return (posts || []).find((p) => p.url === path || p.url === `${path}/`);
|
||||
});
|
||||
|
||||
// Collect all internal blog links from a post's raw markdown and merge with
|
||||
// the explicit `related` frontmatter URLs. Returns a deduplicated list.
|
||||
eleventyConfig.addFilter("seeAlsoLinks", function (inputPath, relatedUrls) {
|
||||
const seen = new Set();
|
||||
const result = [];
|
||||
const add = (url) => {
|
||||
const key = String(url).replace(/\/$/, "");
|
||||
if (!seen.has(key)) { seen.add(key); result.push(String(url)); }
|
||||
};
|
||||
for (const url of (relatedUrls || [])) add(url);
|
||||
try {
|
||||
const content = readFileSync(inputPath, "utf-8");
|
||||
const escaped = siteUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const re = new RegExp(`\\]\\((${escaped}/[^)\\s]+)\\)`, "g");
|
||||
let m;
|
||||
while ((m = re.exec(content)) !== null) add(m[1]);
|
||||
} catch { /* ignore */ }
|
||||
return result;
|
||||
});
|
||||
|
||||
// Strip garden/* tags from a category list so they don't render as
|
||||
// plain category pills alongside the garden badge.
|
||||
eleventyConfig.addFilter("withoutGardenTags", (categories) => {
|
||||
|
||||
Reference in New Issue
Block a user