Add support for new config.yaml

This commit is contained in:
prototypa
2023-07-27 21:52:04 -04:00
parent 8c4698412e
commit d6f3055e31
54 changed files with 860 additions and 591 deletions

View File

@ -1,9 +1,20 @@
import { getCollection } from 'astro:content';
import type { CollectionEntry } from 'astro:content';
import type { Post } from '~/types';
import { cleanSlug, trimSlash, POST_PERMALINK_PATTERN } from './permalinks';
import { APP_BLOG_CONFIG } from '~/utils/config';
import { cleanSlug, trimSlash, BLOG_BASE, POST_PERMALINK_PATTERN, CATEGORY_BASE, TAG_BASE } from './permalinks';
const generatePermalink = async ({ id, slug, publishDate, category }) => {
const generatePermalink = async ({
id,
slug,
publishDate,
category,
}: {
id: string;
slug: string;
publishDate: Date;
category: string | undefined;
}) => {
const year = String(publishDate.getFullYear()).padStart(4, '0');
const month = String(publishDate.getMonth() + 1).padStart(2, '0');
const day = String(publishDate.getDate()).padStart(2, '0');
@ -33,33 +44,46 @@ const getNormalizedPost = async (post: CollectionEntry<'post'>): Promise<Post> =
const { Content, remarkPluginFrontmatter } = await post.render();
const {
publishDate: rawPublishDate = new Date(),
updateDate: rawUpdateDate,
title,
excerpt,
image,
tags: rawTags = [],
category: rawCategory,
author = 'Anonymous',
publishDate: rawPublishDate = new Date(),
...rest
author,
draft = false,
metadata = {},
} = data;
const slug = cleanSlug(rawSlug.split('/').pop());
const publishDate = new Date(rawPublishDate);
const updateDate = rawUpdateDate ? new Date(rawUpdateDate) : undefined;
const category = rawCategory ? cleanSlug(rawCategory) : undefined;
const tags = rawTags.map((tag: string) => cleanSlug(tag));
return {
id: id,
slug: slug,
permalink: await generatePermalink({ id, slug, publishDate, category }),
publishDate: publishDate,
updateDate: updateDate,
title: title,
excerpt: excerpt,
image: image,
category: category,
tags: tags,
author: author,
...rest,
draft: draft,
metadata,
Content: Content,
// or 'body' in case you consume from API
permalink: await generatePermalink({ id, slug, publishDate, category }),
// or 'content' in case you consume from API
readingTime: remarkPluginFrontmatter?.readingTime,
};
@ -78,6 +102,20 @@ const load = async function (): Promise<Array<Post>> {
let _posts: Array<Post>;
/** */
export const isBlogEnabled = APP_BLOG_CONFIG.isEnabled;
export const isBlogListRouteEnabled = APP_BLOG_CONFIG.list.isEnabled;
export const isBlogPostRouteEnabled = APP_BLOG_CONFIG.post.isEnabled;
export const isBlogCategoryRouteEnabled = APP_BLOG_CONFIG.category.isEnabled;
export const isBlogTagRouteEnabled = APP_BLOG_CONFIG.tag.isEnabled;
export const blogListRobots = APP_BLOG_CONFIG.list.robots;
export const blogPostRobots = APP_BLOG_CONFIG.post.robots;
export const blogCategoryRobots = APP_BLOG_CONFIG.category.robots;
export const blogTagRobots = APP_BLOG_CONFIG.tag.robots;
export const blogPostsPerPage = APP_BLOG_CONFIG?.postsPerPage;
/** */
export const fetchPosts = async (): Promise<Array<Post>> => {
if (!_posts) {
@ -124,25 +162,71 @@ export const findLatestPosts = async ({ count }: { count?: number }): Promise<Ar
};
/** */
export const findTags = async (): Promise<Array<string>> => {
const posts = await fetchPosts();
const tags = posts.reduce((acc, post: Post) => {
if (post.tags && Array.isArray(post.tags)) {
return [...acc, ...post.tags];
}
return acc;
}, []);
return [...new Set(tags)];
export const getStaticPathsBlogList =
() =>
async ({ paginate }) => {
if (!isBlogEnabled || !isBlogListRouteEnabled) return [];
return paginate(await fetchPosts(), {
params: { blog: BLOG_BASE || undefined },
pageSize: blogPostsPerPage,
});
};
/** */
export const getStaticPathsBlogPost = () => async () => {
if (!isBlogEnabled || !isBlogPostRouteEnabled) return [];
return (await fetchPosts()).map((post) => ({
params: {
blog: post.permalink,
},
props: { post },
}));
};
/** */
export const findCategories = async (): Promise<Array<string>> => {
const posts = await fetchPosts();
const categories = posts.reduce((acc, post: Post) => {
if (post.category) {
return [...acc, post.category];
}
return acc;
}, []);
return [...new Set(categories)];
};
export const getStaticPathsBlogCategory =
() =>
async ({ paginate }) => {
if (!isBlogEnabled || !isBlogCategoryRouteEnabled) return [];
const posts = await fetchPosts();
const categories = new Set();
posts.map((post) => {
typeof post.category === 'string' && categories.add(post.category.toLowerCase());
});
return Array.from(categories).map((category: string) =>
paginate(
posts.filter((post) => typeof post.category === 'string' && category === post.category.toLowerCase()),
{
params: { category: category, blog: CATEGORY_BASE || undefined },
pageSize: blogPostsPerPage,
props: { category },
}
)
);
};
/** */
export const getStaticPathsBlogTag =
() =>
async ({ paginate }) => {
if (!isBlogEnabled || !isBlogTagRouteEnabled) return [];
const posts = await fetchPosts();
const tags = new Set();
posts.map((post) => {
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
});
return Array.from(tags).map((tag: string) =>
paginate(
posts.filter((post) => Array.isArray(post.tags) && post.tags.find((elem) => elem.toLowerCase() === tag)),
{
params: { tag: tag, blog: TAG_BASE || undefined },
pageSize: blogPostsPerPage,
props: { tag },
}
)
);
};