feat(listings): hide unlisted posts from blog and notes
This commit is contained in:
8
blog.njk
8
blog.njk
@@ -3,7 +3,7 @@ layout: layouts/base.njk
|
||||
title: Blog
|
||||
withSidebar: true
|
||||
pagination:
|
||||
data: collections.posts
|
||||
data: collections.listedPosts
|
||||
size: 20
|
||||
alias: paginatedPosts
|
||||
permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
|
||||
@@ -11,19 +11,19 @@ permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber
|
||||
<div class="h-feed">
|
||||
<div class="flex flex-wrap items-center gap-4 mb-2">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-surface-900 dark:text-surface-100">Blog</h1>
|
||||
{% set sparklineSvg = collections.posts | postingFrequency %}
|
||||
{% set sparklineSvg = collections.listedPosts | postingFrequency %}
|
||||
{% if sparklineSvg %}
|
||||
<div class="flex-1 min-w-0 text-amber-600 dark:text-amber-400">{{ sparklineSvg | safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="text-surface-600 dark:text-surface-400 mb-6 sm:mb-8">
|
||||
All posts including articles and notes.
|
||||
<span class="text-sm">({{ collections.posts.length }} total)</span>
|
||||
<span class="text-sm">({{ collections.listedPosts.length }} total)</span>
|
||||
</p>
|
||||
|
||||
{% if paginatedPosts.length > 0 %}
|
||||
<nav class="flex flex-wrap gap-2 mb-6" aria-label="Filter by post type">
|
||||
<a href="/blog/" class="px-3 py-1.5 text-sm font-medium rounded-full bg-accent-600 text-white dark:bg-accent-700">All Posts <span class="opacity-75">({{ collections.posts.length }})</span></a>
|
||||
<a href="/blog/" class="px-3 py-1.5 text-sm font-medium rounded-full bg-accent-600 text-white dark:bg-accent-700">All Posts <span class="opacity-75">({{ collections.listedPosts.length }})</span></a>
|
||||
{% for pt in enabledPostTypes %}
|
||||
{% set collName = pt.label | lower %}
|
||||
<a href="{{ pt.path }}" class="px-3 py-1.5 text-sm font-medium rounded-full bg-surface-100 dark:bg-surface-800 text-surface-600 dark:text-surface-300 hover:bg-surface-200 dark:hover:bg-surface-700 border border-surface-200 dark:border-surface-700 transition-colors">{{ pt.label }}{% if collections[collName] %} <span class="text-surface-600 dark:text-surface-400">({{ collections[collName].length }})</span>{% endif %}</a>
|
||||
|
||||
@@ -876,19 +876,22 @@ export default function (eleventyConfig) {
|
||||
};
|
||||
});
|
||||
|
||||
// Exclude unlisted posts from UI slices like homepage/sidebar recent-post lists.
|
||||
eleventyConfig.addFilter("excludeUnlistedPosts", (posts) => {
|
||||
if (!Array.isArray(posts)) return [];
|
||||
return posts.filter((post) => {
|
||||
const data = post?.data || {};
|
||||
// Helper: exclude drafts from collections
|
||||
const isPublished = (item) => !item.data.draft;
|
||||
|
||||
// Helper: exclude unlisted visibility from public listing surfaces
|
||||
const isListed = (item) => {
|
||||
const data = item?.data || {};
|
||||
const rawVisibility = data.visibility ?? data.properties?.visibility;
|
||||
const visibility = Array.isArray(rawVisibility) ? rawVisibility[0] : rawVisibility;
|
||||
return String(visibility ?? "").toLowerCase() !== "unlisted";
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Helper: exclude drafts from collections
|
||||
const isPublished = (item) => !item.data.draft;
|
||||
// Exclude unlisted posts from UI slices like homepage/sidebar recent-post lists.
|
||||
eleventyConfig.addFilter("excludeUnlistedPosts", (posts) => {
|
||||
if (!Array.isArray(posts)) return [];
|
||||
return posts.filter(isListed);
|
||||
});
|
||||
|
||||
// Collections for different post types
|
||||
// Note: content path is content/ due to symlink structure
|
||||
@@ -900,6 +903,13 @@ export default function (eleventyConfig) {
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("listedPosts", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/**/*.md")
|
||||
.filter((item) => isPublished(item) && isListed(item))
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("notes", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/notes/**/*.md")
|
||||
@@ -907,6 +917,13 @@ export default function (eleventyConfig) {
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("listedNotes", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/notes/**/*.md")
|
||||
.filter((item) => isPublished(item) && isListed(item))
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("articles", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/articles/**/*.md")
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: layouts/base.njk
|
||||
title: Notes
|
||||
withSidebar: true
|
||||
pagination:
|
||||
data: collections.notes
|
||||
data: collections.listedNotes
|
||||
size: 20
|
||||
alias: paginatedNotes
|
||||
generatePageOnEmptyData: true
|
||||
@@ -12,14 +12,14 @@ permalink: "notes/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumbe
|
||||
<div class="h-feed">
|
||||
<div class="flex flex-wrap items-center gap-4 mb-2">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-surface-900 dark:text-surface-100">Notes</h1>
|
||||
{% set sparklineSvg = collections.notes | postingFrequency %}
|
||||
{% set sparklineSvg = collections.listedNotes | postingFrequency %}
|
||||
{% if sparklineSvg %}
|
||||
<div class="flex-1 min-w-0 text-teal-600 dark:text-teal-400">{{ sparklineSvg | safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="text-surface-600 dark:text-surface-400 mb-6 sm:mb-8">
|
||||
Short thoughts, updates, and quick posts.
|
||||
<span class="text-sm">({{ collections.notes.length }} total)</span>
|
||||
<span class="text-sm">({{ collections.listedNotes.length }} total)</span>
|
||||
</p>
|
||||
|
||||
{% if paginatedNotes.length > 0 %}
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: layouts/base.njk
|
||||
title: Blog
|
||||
withSidebar: true
|
||||
pagination:
|
||||
data: collections.posts
|
||||
data: collections.listedPosts
|
||||
size: 20
|
||||
alias: paginatedPosts
|
||||
permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
|
||||
@@ -11,14 +11,14 @@ permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber
|
||||
<div class="h-feed">
|
||||
<div class="flex flex-wrap items-center gap-4 mb-2">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-surface-900 dark:text-surface-100">Blog</h1>
|
||||
{% set sparklineSvg = collections.posts | postingFrequency %}
|
||||
{% set sparklineSvg = collections.listedPosts | postingFrequency %}
|
||||
{% if sparklineSvg %}
|
||||
<span class="text-amber-600 dark:text-amber-400">{{ sparklineSvg | safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="text-surface-600 dark:text-surface-400 mb-6 sm:mb-8">
|
||||
All posts including articles and notes.
|
||||
<span class="text-sm">({{ collections.posts.length }} total)</span>
|
||||
<span class="text-sm">({{ collections.listedPosts.length }} total)</span>
|
||||
</p>
|
||||
|
||||
{% if paginatedPosts.length > 0 %}
|
||||
|
||||
@@ -818,19 +818,22 @@ export default function (eleventyConfig) {
|
||||
};
|
||||
});
|
||||
|
||||
// Exclude unlisted posts from UI slices like homepage/sidebar recent-post lists.
|
||||
eleventyConfig.addFilter("excludeUnlistedPosts", (posts) => {
|
||||
if (!Array.isArray(posts)) return [];
|
||||
return posts.filter((post) => {
|
||||
const data = post?.data || {};
|
||||
// Helper: exclude drafts from collections
|
||||
const isPublished = (item) => !item.data.draft;
|
||||
|
||||
// Helper: exclude unlisted visibility from public listing surfaces
|
||||
const isListed = (item) => {
|
||||
const data = item?.data || {};
|
||||
const rawVisibility = data.visibility ?? data.properties?.visibility;
|
||||
const visibility = Array.isArray(rawVisibility) ? rawVisibility[0] : rawVisibility;
|
||||
return String(visibility ?? "").toLowerCase() !== "unlisted";
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Helper: exclude drafts from collections
|
||||
const isPublished = (item) => !item.data.draft;
|
||||
// Exclude unlisted posts from UI slices like homepage/sidebar recent-post lists.
|
||||
eleventyConfig.addFilter("excludeUnlistedPosts", (posts) => {
|
||||
if (!Array.isArray(posts)) return [];
|
||||
return posts.filter(isListed);
|
||||
});
|
||||
|
||||
// Collections for different post types
|
||||
// Note: content path is content/ due to symlink structure
|
||||
@@ -842,6 +845,13 @@ export default function (eleventyConfig) {
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("listedPosts", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/**/*.md")
|
||||
.filter((item) => isPublished(item) && isListed(item))
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("notes", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/notes/**/*.md")
|
||||
@@ -849,6 +859,13 @@ export default function (eleventyConfig) {
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("listedNotes", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/notes/**/*.md")
|
||||
.filter((item) => isPublished(item) && isListed(item))
|
||||
.sort((a, b) => b.date - a.date);
|
||||
});
|
||||
|
||||
eleventyConfig.addCollection("articles", function (collectionApi) {
|
||||
return collectionApi
|
||||
.getFilteredByGlob("content/articles/**/*.md")
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: layouts/base.njk
|
||||
title: Notes
|
||||
withSidebar: true
|
||||
pagination:
|
||||
data: collections.notes
|
||||
data: collections.listedNotes
|
||||
size: 20
|
||||
alias: paginatedNotes
|
||||
generatePageOnEmptyData: true
|
||||
@@ -12,14 +12,14 @@ permalink: "notes/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumbe
|
||||
<div class="h-feed">
|
||||
<div class="flex flex-wrap items-center gap-4 mb-2">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-surface-900 dark:text-surface-100">Notes</h1>
|
||||
{% set sparklineSvg = collections.notes | postingFrequency %}
|
||||
{% set sparklineSvg = collections.listedNotes | postingFrequency %}
|
||||
{% if sparklineSvg %}
|
||||
<span class="text-amber-600 dark:text-amber-400">{{ sparklineSvg | safe }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="text-surface-600 dark:text-surface-400 mb-6 sm:mb-8">
|
||||
Short thoughts, updates, and quick posts.
|
||||
<span class="text-sm">({{ collections.notes.length }} total)</span>
|
||||
<span class="text-sm">({{ collections.listedNotes.length }} total)</span>
|
||||
</p>
|
||||
|
||||
{% if paginatedNotes.length > 0 %}
|
||||
|
||||
Reference in New Issue
Block a user