Refactor related posts functions

This commit is contained in:
prototypa
2024-04-14 18:45:29 -04:00
parent cc6dbfbcdf
commit 55459a6103
4 changed files with 39 additions and 42 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "@onwidget/astrowind", "name": "@onwidget/astrowind",
"version": "1.0.0-beta.30", "version": "1.0.0-beta.31",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@onwidget/astrowind", "name": "@onwidget/astrowind",
"version": "1.0.0-beta.30", "version": "1.0.0-beta.31",
"dependencies": { "dependencies": {
"@astrojs/rss": "^4.0.5", "@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.2", "@astrojs/sitemap": "^3.1.2",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@onwidget/astrowind", "name": "@onwidget/astrowind",
"version": "1.0.0-beta.30", "version": "1.0.0-beta.31",
"description": "AstroWind: A free template using Astro 4.0 and Tailwind CSS. Astro starter theme.", "description": "AstroWind: A free template using Astro 4.0 and Tailwind CSS. Astro starter theme.",
"type": "module", "type": "module",
"private": true, "private": true,

View File

@@ -11,8 +11,8 @@ export interface Props {
} }
const { post } = Astro.props; const { post } = Astro.props;
const fetchedPosts = await fetchPosts();
const relatedPosts = post.tags ? getRelatedPosts(fetchedPosts, post.slug, post.tags) : []; const relatedPosts = post.tags ? await getRelatedPosts(post, 4) : [];
--- ---
{ {

View File

@@ -100,29 +100,6 @@ const getNormalizedPost = async (post: CollectionEntry<'post'>): Promise<Post> =
}; };
}; };
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;
};
function hasMatchingTaxonomies(
arr1?: Taxonomy[],
arr2?: Taxonomy[]
): boolean {
if (!arr1 || !arr2) {
return false;
}
const slugsSet = new Set(arr1.map((item) => item.slug));
return arr2.some((item) => slugsSet.has(item.slug));
}
const load = async function (): Promise<Array<Post>> { const load = async function (): Promise<Array<Post>> {
const posts = await getCollection('post'); const posts = await getCollection('post');
const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post)); const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post));
@@ -245,7 +222,10 @@ export const getStaticPathsBlogTag = async ({ paginate }: { paginate: PaginateFu
const posts = await fetchPosts(); const posts = await fetchPosts();
const tags = {}; const tags = {};
posts.map((post) => { posts.map((post) => {
Array.isArray(post.tags) && post.tags.map((tag) => { tags[tag?.slug] = tag; }); Array.isArray(post.tags) &&
post.tags.map((tag) => {
tags[tag?.slug] = tag;
});
}); });
return Array.from(Object.keys(tags)).flatMap((tagSlug) => return Array.from(Object.keys(tags)).flatMap((tagSlug) =>
@@ -261,21 +241,38 @@ export const getStaticPathsBlogTag = async ({ paginate }: { paginate: PaginateFu
}; };
/** */ /** */
export function getRelatedPosts(allPosts: Post[], currentSlug: string, currentTags: Array<Taxonomy>) { export async function getRelatedPosts(originalPost: Post, maxResults: number = 4): Promise<Post[]> {
if (!isBlogEnabled || !isRelatedPostsEnabled) return []; const allPosts = await fetchPosts();
const originalTagsSet = new Set(originalPost.tags ? originalPost.tags.map(tag => tag.slug) : []);
const relatedPosts = getRandomizedPosts( const postsWithScores = allPosts.reduce((acc: { post: Post; score: number }[], iteratedPost: Post) => {
allPosts.filter((post) => post.slug !== currentSlug && hasMatchingTaxonomies(post.tags, currentTags)), if (iteratedPost.slug === originalPost.slug) return acc;
APP_BLOG.relatedPostsCount
);
if (relatedPosts.length < APP_BLOG.relatedPostsCount) { let score = 0;
const morePosts = getRandomizedPosts( if (iteratedPost.category && originalPost.category && iteratedPost.category.slug === originalPost.category.slug) {
allPosts.filter((post) => post.slug !== currentSlug && hasMatchingTaxonomies(post.tags, currentTags)), score += 5;
APP_BLOG.relatedPostsCount - relatedPosts.length }
);
relatedPosts.push(...morePosts); if (iteratedPost.tags) {
iteratedPost.tags.forEach(tag => {
if (originalTagsSet.has(tag.slug)) {
score += 1;
}
});
}
acc.push({ post: iteratedPost, score });
return acc;
}, []);
postsWithScores.sort((a, b) => b.score - a.score);
const selectedPosts: Post[] = [];
let i = 0;
while (selectedPosts.length < maxResults && i < postsWithScores.length) {
selectedPosts.push(postsWithScores[i].post);
i++;
} }
return relatedPosts; return selectedPosts;
} }