From 13cbe429cc487d93b47d446c41c3ef9707772fab Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Sun, 14 Jan 2024 07:51:36 -0500 Subject: [PATCH] feat: add related blog posts component --- src/components/blog/RelatedPosts.astro | 28 ++++++++++++++++++++++ src/config.yaml | 2 ++ src/pages/[...blog]/index.astro | 2 ++ src/utils/blog.ts | 33 ++++++++++++++++++++++++++ src/utils/config.ts | 2 ++ 5 files changed, 67 insertions(+) create mode 100644 src/components/blog/RelatedPosts.astro diff --git a/src/components/blog/RelatedPosts.astro b/src/components/blog/RelatedPosts.astro new file mode 100644 index 0000000..e193baf --- /dev/null +++ b/src/components/blog/RelatedPosts.astro @@ -0,0 +1,28 @@ +--- +import { APP_BLOG } from "~/utils/config"; + +import { fetchPosts, getRelatedPosts } from "~/utils/blog"; +import BlogHighlightedPosts from "../widgets/BlogHighlightedPosts.astro"; +import type { Post } from "~/types"; +import { getBlogPermalink } from "~/utils/permalinks"; + +export interface Props { + post: Post; +} + +const { post } = Astro.props; +const fetchedPosts = await fetchPosts(); +const relatedPosts = post.tags ? getRelatedPosts(fetchedPosts, post.slug, post.tags) : []; +--- + +{ + APP_BLOG.isRelatedPostsEnabled ? ( + post.id)} + /> + ) : null +} diff --git a/src/config.yaml b/src/config.yaml index 97f086c..e25340b 100644 --- a/src/config.yaml +++ b/src/config.yaml @@ -35,6 +35,8 @@ apps: blog: isEnabled: true postsPerPage: 6 + isRelatedPostsEnabled: true + relatedPostsCount: 4 post: isEnabled: true diff --git a/src/pages/[...blog]/index.astro b/src/pages/[...blog]/index.astro index 87ef541..ffeedcb 100644 --- a/src/pages/[...blog]/index.astro +++ b/src/pages/[...blog]/index.astro @@ -11,6 +11,7 @@ import { getCanonical, getPermalink } from '~/utils/permalinks'; import { getStaticPathsBlogPost, blogPostRobots } from '~/utils/blog'; import { findImage } from '~/utils/images'; import type { MetaData } from '~/types'; +import RelatedPosts from '~/components/blog/RelatedPosts.astro'; export const prerender = true; @@ -45,4 +46,5 @@ const metadata = merge( + diff --git a/src/utils/blog.ts b/src/utils/blog.ts index 5bdd676..f0ef94f 100644 --- a/src/utils/blog.ts +++ b/src/utils/blog.ts @@ -90,6 +90,18 @@ const getNormalizedPost = async (post: CollectionEntry<'post'>): Promise = }; }; +const getRandomizedPosts = (array: Post[], num: number) => { + const newArray: Post[] = []; + + while (newArray.length < num && array.length > 0) { + const randomIndex = Math.floor(Math.random() * array.length); + newArray.push(array[randomIndex]); + array.splice(randomIndex, 1); + } + + return newArray; +}; + const load = async function (): Promise> { const posts = await getCollection('post'); const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post)); @@ -105,6 +117,7 @@ let _posts: Array; /** */ export const isBlogEnabled = APP_BLOG.isEnabled; +export const isRelatedPostsEnabled = APP_BLOG.isRelatedPostsEnabled; export const isBlogListRouteEnabled = APP_BLOG.list.isEnabled; export const isBlogPostRouteEnabled = APP_BLOG.post.isEnabled; export const isBlogCategoryRouteEnabled = APP_BLOG.category.isEnabled; @@ -225,3 +238,23 @@ export const getStaticPathsBlogTag = async ({ paginate }: { paginate: PaginateFu ) ); }; + +/** */ +export function getRelatedPosts(allPosts: Post[], currentSlug: string, currentTags: string[]) { + if (!isBlogEnabled || !isRelatedPostsEnabled) return []; + + const relatedPosts = getRandomizedPosts( + allPosts.filter((post) => post.slug !== currentSlug && post.tags?.some((tag) => currentTags.includes(tag))), + APP_BLOG.relatedPostsCount + ); + + if (relatedPosts.length < APP_BLOG.relatedPostsCount) { + const morePosts = getRandomizedPosts( + allPosts.filter((post) => post.slug !== currentSlug && !post.tags?.some((tag) => currentTags.includes(tag))), + APP_BLOG.relatedPostsCount - relatedPosts.length + ); + relatedPosts.push(...morePosts); + } + + return relatedPosts; +} diff --git a/src/utils/config.ts b/src/utils/config.ts index bbeb7a2..6e2a2e7 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -25,6 +25,8 @@ export interface I18NConfig { export interface AppBlogConfig { isEnabled: boolean; postsPerPage: number; + isRelatedPostsEnabled: boolean; + relatedPostsCount: number; post: { isEnabled: boolean; permalink: string;