feat: differentiate post types in blog feed with icons and labels
Likes, bookmarks, reposts, replies, and photos now render with distinct type icons, colored labels, target URLs, and proper microformat classes (u-like-of, u-bookmark-of, etc.) instead of all appearing as generic notes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,225 @@ permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber
|
|||||||
<ul class="post-list">
|
<ul class="post-list">
|
||||||
{% for post in paginatedPosts %}
|
{% for post in paginatedPosts %}
|
||||||
<li class="h-entry post-card">
|
<li class="h-entry post-card">
|
||||||
{# Article with title #}
|
{# Detect post type from frontmatter properties #}
|
||||||
{% if post.data.title %}
|
{% set likedUrl = post.data.likeOf or post.data.like_of %}
|
||||||
|
{% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
|
||||||
|
{% set repostedUrl = post.data.repostOf or post.data.repost_of %}
|
||||||
|
{% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
|
||||||
|
{% set hasPhotos = post.data.photo and post.data.photo.length %}
|
||||||
|
|
||||||
|
{% if likedUrl %}
|
||||||
|
{# ── Like card ── #}
|
||||||
|
<div class="post-header flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<svg class="w-5 h-5 text-red-500" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="post-meta">
|
||||||
|
<span class="font-medium text-red-600 dark:text-red-400">Liked</span>
|
||||||
|
<time class="dt-published" datetime="{{ post.date | isoDate }}">
|
||||||
|
{{ post.date | dateDisplay }}
|
||||||
|
</time>
|
||||||
|
{% if post.data.category %}
|
||||||
|
<span class="post-categories">
|
||||||
|
{% if post.data.category is string %}
|
||||||
|
<span class="p-category">{{ post.data.category }}</span>
|
||||||
|
{% else %}
|
||||||
|
{% for cat in post.data.category %}
|
||||||
|
<span class="p-category">{{ cat }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<p class="mt-2">
|
||||||
|
<a class="u-like-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ likedUrl }}">
|
||||||
|
{{ likedUrl }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{% if post.templateContent %}
|
||||||
|
<div class="e-content prose dark:prose-invert prose-sm mt-3 max-w-none">
|
||||||
|
{{ post.templateContent | safe }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a class="u-url text-sm text-primary-600 dark:text-primary-400 hover:underline mt-3 inline-block" href="{{ post.url }}">Permalink</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif bookmarkedUrl %}
|
||||||
|
{# ── Bookmark card ── #}
|
||||||
|
<div class="post-header flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<svg class="w-5 h-5 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="post-meta">
|
||||||
|
<span class="font-medium text-amber-600 dark:text-amber-400">Bookmarked</span>
|
||||||
|
<time class="dt-published" datetime="{{ post.date | isoDate }}">
|
||||||
|
{{ post.date | dateDisplay }}
|
||||||
|
</time>
|
||||||
|
{% if post.data.category %}
|
||||||
|
<span class="post-categories">
|
||||||
|
{% if post.data.category is string %}
|
||||||
|
<span class="p-category">{{ post.data.category }}</span>
|
||||||
|
{% else %}
|
||||||
|
{% for cat in post.data.category %}
|
||||||
|
<span class="p-category">{{ cat }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if post.data.title %}
|
||||||
|
<h2 class="p-name text-lg font-semibold text-surface-900 dark:text-surface-100 mt-2">
|
||||||
|
<a class="hover:text-primary-600 dark:hover:text-primary-400" href="{{ post.url }}">{{ post.data.title }}</a>
|
||||||
|
</h2>
|
||||||
|
{% endif %}
|
||||||
|
<p class="mt-2 text-sm">
|
||||||
|
<a class="u-bookmark-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ bookmarkedUrl }}">
|
||||||
|
{{ bookmarkedUrl }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{% if post.templateContent %}
|
||||||
|
<div class="e-content prose dark:prose-invert prose-sm mt-3 max-w-none">
|
||||||
|
{{ post.templateContent | safe }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a class="u-url text-sm text-primary-600 dark:text-primary-400 hover:underline mt-3 inline-block" href="{{ post.url }}">Permalink</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif repostedUrl %}
|
||||||
|
{# ── Repost card ── #}
|
||||||
|
<div class="post-header flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="post-meta">
|
||||||
|
<span class="font-medium text-green-600 dark:text-green-400">Reposted</span>
|
||||||
|
<time class="dt-published" datetime="{{ post.date | isoDate }}">
|
||||||
|
{{ post.date | dateDisplay }}
|
||||||
|
</time>
|
||||||
|
{% if post.data.category %}
|
||||||
|
<span class="post-categories">
|
||||||
|
{% if post.data.category is string %}
|
||||||
|
<span class="p-category">{{ post.data.category }}</span>
|
||||||
|
{% else %}
|
||||||
|
{% for cat in post.data.category %}
|
||||||
|
<span class="p-category">{{ cat }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 text-sm">
|
||||||
|
<a class="u-repost-of text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ repostedUrl }}">
|
||||||
|
{{ repostedUrl }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{% if post.templateContent %}
|
||||||
|
<div class="e-content prose dark:prose-invert prose-sm mt-3 max-w-none">
|
||||||
|
{{ post.templateContent | safe }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a class="u-url text-sm text-primary-600 dark:text-primary-400 hover:underline mt-3 inline-block" href="{{ post.url }}">Permalink</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif replyToUrl %}
|
||||||
|
{# ── Reply card ── #}
|
||||||
|
<div class="post-header flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<svg class="w-5 h-5 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="post-meta">
|
||||||
|
<span class="font-medium text-primary-600 dark:text-primary-400">In reply to</span>
|
||||||
|
<time class="dt-published" datetime="{{ post.date | isoDate }}">
|
||||||
|
{{ post.date | dateDisplay }}
|
||||||
|
</time>
|
||||||
|
{% if post.data.category %}
|
||||||
|
<span class="post-categories">
|
||||||
|
{% if post.data.category is string %}
|
||||||
|
<span class="p-category">{{ post.data.category }}</span>
|
||||||
|
{% else %}
|
||||||
|
{% for cat in post.data.category %}
|
||||||
|
<span class="p-category">{{ cat }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 text-sm">
|
||||||
|
<a class="u-in-reply-to text-primary-600 dark:text-primary-400 hover:underline break-all" href="{{ replyToUrl }}">
|
||||||
|
{{ replyToUrl }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<div class="e-content prose dark:prose-invert prose-sm mt-3 max-w-none">
|
||||||
|
{{ post.templateContent | safe }}
|
||||||
|
</div>
|
||||||
|
<a class="u-url text-sm text-primary-600 dark:text-primary-400 hover:underline mt-3 inline-block" href="{{ post.url }}">Permalink</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif hasPhotos %}
|
||||||
|
{# ── Photo card ── #}
|
||||||
|
<div class="post-header flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<svg class="w-5 h-5 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="post-meta">
|
||||||
|
<span class="font-medium text-purple-600 dark:text-purple-400">Photo</span>
|
||||||
|
<time class="dt-published" datetime="{{ post.date | isoDate }}">
|
||||||
|
{{ post.date | dateDisplay }}
|
||||||
|
</time>
|
||||||
|
{% if post.data.category %}
|
||||||
|
<span class="post-categories">
|
||||||
|
{% if post.data.category is string %}
|
||||||
|
<span class="p-category">{{ post.data.category }}</span>
|
||||||
|
{% else %}
|
||||||
|
{% for cat in post.data.category %}
|
||||||
|
<span class="p-category">{{ cat }}</span>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="photo-gallery mt-3">
|
||||||
|
{% for img in post.data.photo %}
|
||||||
|
{% set photoUrl = img.url %}
|
||||||
|
{% if photoUrl and photoUrl[0] != '/' and 'http' not in photoUrl %}
|
||||||
|
{% set photoUrl = '/' + photoUrl %}
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ post.url }}" class="photo-link">
|
||||||
|
<img src="{{ photoUrl }}" alt="{{ img.alt | default('Photo') }}" class="u-photo" loading="lazy" eleventy:ignore>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% if post.templateContent %}
|
||||||
|
<div class="e-content photo-caption prose dark:prose-invert prose-sm mt-3 max-w-none">
|
||||||
|
{{ post.templateContent | safe }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a class="u-url text-sm text-primary-600 dark:text-primary-400 hover:underline mt-3 inline-block" href="{{ post.url }}">Permalink</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif post.data.title %}
|
||||||
|
{# ── Article card (unchanged) ── #}
|
||||||
<div class="post-header">
|
<div class="post-header">
|
||||||
<h2 class="text-xl font-semibold mb-1">
|
<h2 class="text-xl font-semibold mb-1">
|
||||||
<a class="p-name u-url text-surface-900 dark:text-surface-100 hover:text-primary-600 dark:hover:text-primary-400" href="{{ post.url }}">
|
<a class="p-name u-url text-surface-900 dark:text-surface-100 hover:text-primary-600 dark:hover:text-primary-400" href="{{ post.url }}">
|
||||||
@@ -51,8 +268,8 @@ permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber
|
|||||||
Read more →
|
Read more →
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{# Note without title #}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{# ── Note card (unchanged) ── #}
|
||||||
<div class="post-header">
|
<div class="post-header">
|
||||||
<a class="u-url" href="{{ post.url }}">
|
<a class="u-url" href="{{ post.url }}">
|
||||||
<time class="dt-published text-sm text-primary-600 dark:text-primary-400 font-medium" datetime="{{ post.date | isoDate }}">
|
<time class="dt-published text-sm text-primary-600 dark:text-primary-400 font-medium" datetime="{{ post.date | isoDate }}">
|
||||||
|
|||||||
Reference in New Issue
Block a user