From d7b7baa4147f40456e3cd178d704201a1839fdd2 Mon Sep 17 00:00:00 2001 From: prototypa Date: Sun, 1 Jan 2023 18:32:52 -0500 Subject: [PATCH] Migrate blog to new astro Content Collections --- .gitignore | 4 +- astro.config.mjs | 4 ++ data/.gitkeep | 0 package.json | 2 +- src/components/blog/HighlightedPosts.astro | 8 +-- src/components/widgets/FAQs.astro | 4 +- .../blog/astrowind-template-in-depth.md | 0 ...started-website-with-astro-tailwind-css.md | 0 ...ow-to-customize-astrowind-to-your-brand.md | 0 .../blog/markdown-elements-demo-post.mdx | 0 .../useful-resources-to-create-websites.md | 0 src/content/config.js | 27 +++++++++ src/utils/permalinks.js | 2 +- src/utils/posts.js | 59 +++++++++---------- tsconfig.json | 1 + 15 files changed, 71 insertions(+), 40 deletions(-) delete mode 100644 data/.gitkeep rename {data => src/content}/blog/astrowind-template-in-depth.md (100%) rename {data => src/content}/blog/get-started-website-with-astro-tailwind-css.md (100%) rename {data => src/content}/blog/how-to-customize-astrowind-to-your-brand.md (100%) rename {data => src/content}/blog/markdown-elements-demo-post.mdx (100%) rename {data => src/content}/blog/useful-resources-to-create-websites.md (100%) create mode 100644 src/content/config.js diff --git a/.gitignore b/.gitignore index befce08..b08221d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,6 @@ pnpm-debug.log* .DS_Store package-lock.json -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml + +src/content/types.generated.d.ts \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index 48fed18..e81e746 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -55,4 +55,8 @@ export default defineConfig({ }, }, }, + + experimental: { + contentCollections: true, + }, }); diff --git a/data/.gitkeep b/data/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/package.json b/package.json index 4e8a709..50bd10a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@onwidget/astrowind", "description": "A template to make your website using Astro + Tailwind CSS.", - "version": "0.8.7", + "version": "0.9.0", "private": true, "scripts": { "dev": "astro dev", diff --git a/src/components/blog/HighlightedPosts.astro b/src/components/blog/HighlightedPosts.astro index 15b70e6..ed1181b 100644 --- a/src/components/blog/HighlightedPosts.astro +++ b/src/components/blog/HighlightedPosts.astro @@ -4,10 +4,10 @@ import Grid from '~/components/blog/Grid.astro'; import { findPostsByIds } from '~/utils/posts'; const ids = [ - 'get-started-website-with-astro-tailwind-css', - 'how-to-customize-astrowind-to-your-brand', - 'useful-resources-to-create-websites', - 'astrowind-template-in-depth', + 'get-started-website-with-astro-tailwind-css.md', + 'how-to-customize-astrowind-to-your-brand.md', + 'useful-resources-to-create-websites.md', + 'astrowind-template-in-depth.md', ]; const posts = await findPostsByIds(ids); --- diff --git a/src/components/widgets/FAQs.astro b/src/components/widgets/FAQs.astro index 49cf929..f4c1613 100644 --- a/src/components/widgets/FAQs.astro +++ b/src/components/widgets/FAQs.astro @@ -54,10 +54,10 @@ const items = [
{subitems.map(({ question, answer }) => (
-

+

{question} -

+

{answer.split('\n\n').map((paragraph) => (

))} diff --git a/data/blog/astrowind-template-in-depth.md b/src/content/blog/astrowind-template-in-depth.md similarity index 100% rename from data/blog/astrowind-template-in-depth.md rename to src/content/blog/astrowind-template-in-depth.md diff --git a/data/blog/get-started-website-with-astro-tailwind-css.md b/src/content/blog/get-started-website-with-astro-tailwind-css.md similarity index 100% rename from data/blog/get-started-website-with-astro-tailwind-css.md rename to src/content/blog/get-started-website-with-astro-tailwind-css.md diff --git a/data/blog/how-to-customize-astrowind-to-your-brand.md b/src/content/blog/how-to-customize-astrowind-to-your-brand.md similarity index 100% rename from data/blog/how-to-customize-astrowind-to-your-brand.md rename to src/content/blog/how-to-customize-astrowind-to-your-brand.md diff --git a/data/blog/markdown-elements-demo-post.mdx b/src/content/blog/markdown-elements-demo-post.mdx similarity index 100% rename from data/blog/markdown-elements-demo-post.mdx rename to src/content/blog/markdown-elements-demo-post.mdx diff --git a/data/blog/useful-resources-to-create-websites.md b/src/content/blog/useful-resources-to-create-websites.md similarity index 100% rename from data/blog/useful-resources-to-create-websites.md rename to src/content/blog/useful-resources-to-create-websites.md diff --git a/src/content/config.js b/src/content/config.js new file mode 100644 index 0000000..e855425 --- /dev/null +++ b/src/content/config.js @@ -0,0 +1,27 @@ +import { z, defineCollection } from 'astro:content'; + +const blog = defineCollection({ + schema: { + title: z.string(), + description: z.string().optional(), + image: z.string().optional(), + + canonical: z.string().url().optional(), + permalink: z.string().optional(), + + publishDate: z.string().transform((str) => new Date(str)), + draft: z.boolean().optional(), + + excerpt: z.string().optional(), + category: z.string().optional(), + tags: z.array(z.string()).optional(), + authors: z.array(z.string()).optional(), + }, + slug: ({ defaultSlug, data }) => { + return data.permalink || defaultSlug; + }, +}); + +export const collections = { + blog: blog, +}; diff --git a/src/utils/permalinks.js b/src/utils/permalinks.js index a2fa936..0882ad9 100644 --- a/src/utils/permalinks.js +++ b/src/utils/permalinks.js @@ -2,7 +2,7 @@ import slugify from 'limax'; import { SITE, BLOG } from '~/config.mjs'; -const trim = (str, ch) => { +const trim = (str = "", ch) => { let start = 0, end = str.length || 0; while (start < end && str[start] === ch) ++start; diff --git a/src/utils/posts.js b/src/utils/posts.js index 6f81fb4..b361085 100644 --- a/src/utils/posts.js +++ b/src/utils/posts.js @@ -1,44 +1,29 @@ +import { getCollection, getEntry } from 'astro:content'; + const getNormalizedPost = async (post) => { - const { frontmatter, Content, file } = post; - const ID = file.split('/').pop().split('.').shift(); + const { id, slug, data } = post; + const { Content, injectedFrontmatter } = await post.render(); return { - id: ID, - - publishDate: frontmatter.publishDate, - draft: frontmatter.draft, - - canonical: frontmatter.canonical, - slug: frontmatter.slug || ID, - - title: frontmatter.title, - description: frontmatter.description, - image: frontmatter.image, + id: id, + slug: slug, + ...data, Content: Content, // or 'body' in case you consume from API - excerpt: frontmatter.excerpt, - authors: frontmatter.authors, - category: frontmatter.category, - tags: frontmatter.tags, - readingTime: frontmatter.readingTime, + readingTime: injectedFrontmatter.readingTime, }; }; const load = async function () { - const posts = import.meta.glob(['~/../data/blog/**/*.md', '~/../data/blog/**/*.mdx'], { - eager: true, - }); - - const normalizedPosts = Object.keys(posts).map(async (key) => { - const post = await posts[key]; - return await getNormalizedPost(post); - }); + const posts = await getCollection('blog'); + const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post)); const results = (await Promise.all(normalizedPosts)) - .sort((a, b) => new Date(b.publishDate).valueOf() - new Date(a.publishDate).valueOf()) + .sort((a, b) => b.publishDate.valueOf() - a.publishDate.valueOf()) .filter((post) => !post.draft); + return results; }; @@ -52,19 +37,31 @@ export const fetchPosts = async () => { }; /** */ -export const findPostsByIds = async (ids) => { - if (!Array.isArray(ids)) return []; +export const findPostsBySlugs = async (slugs) => { + if (!Array.isArray(slugs)) return []; const posts = await fetchPosts(); - return ids.reduce(function (r, id) { + return slugs.reduce(function (r, slug) { posts.some(function (post) { - return id === post.id && r.push(post); + return slug === post.slug && r.push(post); }); return r; }, []); }; +/** */ +export const findPostsByIds = async (ids) => { + if (!Array.isArray(ids)) return []; + + return await Promise.all( + ids.map(async (id) => { + const post = await getEntry('blog', id); + return await getNormalizedPost(post); + }) + ); +}; + /** */ export const findLatestPosts = async ({ count }) => { const _count = count || 4; diff --git a/tsconfig.json b/tsconfig.json index d0a369f..7d01264 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "extends": "astro/tsconfigs/base", "compilerOptions": { "types": ["astro/client"], + "strictNullChecks": true, "allowJs": true, "baseUrl": ".", "paths": {