fix: support camelCase property names from Indiekit Eleventy preset

The Indiekit Eleventy preset uses camelcaseKeys to convert frontmatter
properties (e.g., bookmark-of → bookmarkOf), but templates expected
underscore-separated names (bookmark_of).

Changes:
- Support both camelCase and underscore property names in all templates
- Update collections to filter on both property name formats
- Include interaction URLs (bookmarks, likes, replies, reposts) in
  Bridgy syndication content for proper social media posting

Fixes bookmark URLs not appearing on posts or in syndicated content.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ricardo
2026-01-24 16:34:08 +01:00
parent 96182cb1e4
commit f7db31ac27
7 changed files with 55 additions and 31 deletions
+19 -13
View File
@@ -2,9 +2,15 @@
{# Displays rich context for replies, likes, reposts, and bookmarks #} {# Displays rich context for replies, likes, reposts, and bookmarks #}
{# Uses h-cite microformat for citing external content #} {# Uses h-cite microformat for citing external content #}
{% if in_reply_to or like_of or repost_of or bookmark_of %} {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
{% set replyTo = inReplyTo or in_reply_to %}
{% set likedUrl = likeOf or like_of %}
{% set repostedUrl = repostOf or repost_of %}
{% set bookmarkedUrl = bookmarkOf or bookmark_of %}
{% if replyTo or likedUrl or repostedUrl or bookmarkedUrl %}
<aside class="reply-context p-4 mb-6 bg-surface-100 dark:bg-surface-800 rounded-lg border-l-4 border-primary-500"> <aside class="reply-context p-4 mb-6 bg-surface-100 dark:bg-surface-800 rounded-lg border-l-4 border-primary-500">
{% if in_reply_to %} {% if replyTo %}
<div class="u-in-reply-to h-cite"> <div class="u-in-reply-to h-cite">
<p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2"> <p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
@@ -12,13 +18,13 @@
</svg> </svg>
<span>In reply to:</span> <span>In reply to:</span>
</p> </p>
<a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ in_reply_to }}"> <a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ replyTo }}">
{{ in_reply_to }} {{ replyTo }}
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% if like_of %} {% if likedUrl %}
<div class="u-like-of h-cite"> <div class="u-like-of h-cite">
<p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2"> <p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2">
<svg class="w-4 h-4 text-red-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-4 h-4 text-red-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
@@ -26,13 +32,13 @@
</svg> </svg>
<span>Liked:</span> <span>Liked:</span>
</p> </p>
<a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ like_of }}"> <a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ likedUrl }}">
{{ like_of }} {{ likedUrl }}
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% if repost_of %} {% if repostedUrl %}
<div class="u-repost-of h-cite"> <div class="u-repost-of h-cite">
<p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2"> <p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2">
<svg class="w-4 h-4 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-4 h-4 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
@@ -40,13 +46,13 @@
</svg> </svg>
<span>Reposted:</span> <span>Reposted:</span>
</p> </p>
<a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ repost_of }}"> <a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ repostedUrl }}">
{{ repost_of }} {{ repostedUrl }}
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% if bookmark_of %} {% if bookmarkedUrl %}
<div class="u-bookmark-of h-cite"> <div class="u-bookmark-of h-cite">
<p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2"> <p class="text-sm text-surface-500 dark:text-surface-400 mb-2 flex items-center gap-2">
<svg class="w-4 h-4 text-yellow-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-4 h-4 text-yellow-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
@@ -54,8 +60,8 @@
</svg> </svg>
<span>Bookmarked:</span> <span>Bookmarked:</span>
</p> </p>
<a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ bookmark_of }}"> <a class="u-url font-medium text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ bookmarkedUrl }}">
{{ bookmark_of }} {{ bookmarkedUrl }}
</a> </a>
</div> </div>
{% endif %} {% endif %}
+11 -3
View File
@@ -26,10 +26,18 @@ withBlogSidebar: true
</div> </div>
{# Bridgy syndication content - controls what gets posted to social networks #} {# Bridgy syndication content - controls what gets posted to social networks #}
{# Uses description/summary if available, otherwise first 280 chars of content #} {# For interaction types (bookmarks, likes, replies, reposts), include the target URL #}
{# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
{% set bookmarkedUrl = bookmarkOf or bookmark_of %}
{% set likedUrl = likeOf or like_of %}
{% set replyTo = inReplyTo or in_reply_to %}
{% set repostedUrl = repostOf or repost_of %}
{% set bridgySummary = description or summary or (content | ogDescription(280)) %} {% set bridgySummary = description or summary or (content | ogDescription(280)) %}
{% if bridgySummary %} {% set interactionUrl = bookmarkedUrl or likedUrl or replyTo or repostedUrl %}
<p class="p-summary e-bridgy-mastodon-content e-bridgy-bluesky-content hidden">{{ bridgySummary }}</p>
{% if bridgySummary or interactionUrl %}
<p class="p-summary e-bridgy-mastodon-content e-bridgy-bluesky-content hidden">{% if bookmarkedUrl %}🔖 {{ bookmarkedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif likedUrl %}❤️ {{ likedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif replyTo %}↩️ {{ replyTo }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif repostedUrl %}🔁 {{ repostedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% else %}{{ bridgySummary }}{% endif %}</p>
{% endif %} {% endif %}
<div class="e-content prose prose-surface dark:prose-invert max-w-none"> <div class="e-content prose prose-surface dark:prose-invert max-w-none">
+4 -2
View File
@@ -20,8 +20,10 @@ permalink: /bookmarks/
{{ post.date | dateDisplay }} {{ post.date | dateDisplay }}
</time> </time>
</div> </div>
{% if post.data.bookmark_of %} {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
<p><a class="u-bookmark-of" href="{{ post.data.bookmark_of }}">{{ post.data.bookmark_of }}</a></p> {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
{% if bookmarkedUrl %}
<p><a class="u-bookmark-of" href="{{ bookmarkedUrl }}">{{ bookmarkedUrl }}</a></p>
{% endif %} {% endif %}
<div class="e-content">{{ post.templateContent | safe }}</div> <div class="e-content">{{ post.templateContent | safe }}</div>
</li> </li>
+6 -4
View File
@@ -316,19 +316,21 @@ export default function (eleventyConfig) {
.sort((a, b) => b.date - a.date); .sort((a, b) => b.date - a.date);
}); });
// Replies collection - posts with in_reply_to property // Replies collection - posts with inReplyTo/in_reply_to property
// Supports both camelCase (Indiekit Eleventy preset) and underscore (legacy) names
eleventyConfig.addCollection("replies", function (collectionApi) { eleventyConfig.addCollection("replies", function (collectionApi) {
return collectionApi return collectionApi
.getAll() .getAll()
.filter((item) => item.data.in_reply_to) .filter((item) => item.data.inReplyTo || item.data.in_reply_to)
.sort((a, b) => b.date - a.date); .sort((a, b) => b.date - a.date);
}); });
// Reposts collection - posts with repost_of property // Reposts collection - posts with repostOf/repost_of property
// Supports both camelCase (Indiekit Eleventy preset) and underscore (legacy) names
eleventyConfig.addCollection("reposts", function (collectionApi) { eleventyConfig.addCollection("reposts", function (collectionApi) {
return collectionApi return collectionApi
.getAll() .getAll()
.filter((item) => item.data.repost_of) .filter((item) => item.data.repostOf || item.data.repost_of)
.sort((a, b) => b.date - a.date); .sort((a, b) => b.date - a.date);
}); });
+5 -3
View File
@@ -24,10 +24,12 @@ permalink: /likes/
{{ post.date | dateDisplay }} {{ post.date | dateDisplay }}
</time> </time>
</div> </div>
{% if post.data.like_of %} {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
{% set likedUrl = post.data.likeOf or post.data.like_of %}
{% if likedUrl %}
<p class="mb-2"> <p class="mb-2">
<a class="u-like-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ post.data.like_of }}"> <a class="u-like-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ likedUrl }}">
{{ post.data.like_of }} {{ likedUrl }}
</a> </a>
</p> </p>
{% endif %} {% endif %}
+5 -3
View File
@@ -29,11 +29,13 @@ permalink: /replies/
{{ post.date | dateDisplay }} {{ post.date | dateDisplay }}
</time> </time>
</div> </div>
{% if post.data.in_reply_to %} {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
{% set replyTo = post.data.inReplyTo or post.data.in_reply_to %}
{% if replyTo %}
<p class="mb-3 text-sm"> <p class="mb-3 text-sm">
<span class="text-surface-500">In reply to:</span> <span class="text-surface-500">In reply to:</span>
<a class="u-in-reply-to text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ post.data.in_reply_to }}"> <a class="u-in-reply-to text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ replyTo }}">
{{ post.data.in_reply_to }} {{ replyTo }}
</a> </a>
</p> </p>
{% endif %} {% endif %}
+5 -3
View File
@@ -29,11 +29,13 @@ permalink: /reposts/
{{ post.date | dateDisplay }} {{ post.date | dateDisplay }}
</time> </time>
</div> </div>
{% if post.data.repost_of %} {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
{% set repostedUrl = post.data.repostOf or post.data.repost_of %}
{% if repostedUrl %}
<p class="mb-3 text-sm"> <p class="mb-3 text-sm">
<span class="text-surface-500">Reposted:</span> <span class="text-surface-500">Reposted:</span>
<a class="u-repost-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ post.data.repost_of }}"> <a class="u-repost-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ repostedUrl }}">
{{ post.data.repost_of }} {{ repostedUrl }}
</a> </a>
</p> </p>
{% endif %} {% endif %}