From 63b1df19b82b389546291a1e0e593589539ae6b8 Mon Sep 17 00:00:00 2001 From: Al Murad Uzzaman Date: Sun, 5 Jan 2025 15:55:16 +0600 Subject: [PATCH] Updated to Astro v5 --- astro.config.mjs | 5 +- package.json | 53 ++++---- readme.md | 2 +- src/content.config.ts | 163 ++++++++++++++++++++++++ src/content/config.ts | 57 --------- src/env.d.ts | 2 - src/layouts/Base.astro | 4 +- src/layouts/PostSingle.astro | 3 +- src/layouts/components/AuthorCard.astro | 2 +- src/layouts/components/BlogCard.astro | 7 +- src/lib/contentParser.astro | 2 +- src/pages/[regular].astro | 5 +- src/pages/about.astro | 7 +- src/pages/authors/[single].astro | 7 +- src/pages/authors/index.astro | 7 +- src/pages/blog/[single].astro | 2 +- src/pages/blog/index.astro | 8 +- src/pages/blog/page/[slug].astro | 6 +- src/pages/contact.astro | 6 +- src/pages/index.astro | 21 ++- tsconfig.json | 4 +- 21 files changed, 254 insertions(+), 119 deletions(-) create mode 100755 src/content.config.ts delete mode 100755 src/content/config.ts delete mode 100755 src/env.d.ts diff --git a/astro.config.mjs b/astro.config.mjs index bae7e44..dbb8620 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -3,10 +3,11 @@ import react from "@astrojs/react"; import sitemap from "@astrojs/sitemap"; import tailwind from "@astrojs/tailwind"; import AutoImport from "astro-auto-import"; -import { defineConfig, squooshImageService } from "astro/config"; +import { defineConfig } from "astro/config"; import remarkCollapse from "remark-collapse"; import remarkToc from "remark-toc"; import config from "./src/config/config.json"; +import sharp from "sharp"; // https://astro.build/config export default defineConfig({ @@ -14,7 +15,7 @@ export default defineConfig({ base: config.site.base_path ? config.site.base_path : "/", trailingSlash: config.site.trailing_slash ? "always" : "never", image: { - service: squooshImageService(), + service: sharp(), }, integrations: [ react(), diff --git a/package.json b/package.json index 795bbbc..6715bdd 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "astroplate", - "version": "4.1.0", + "version": "5.0.0", "description": "Astro and Tailwindcss boilerplate", "author": "zeon.studio", "license": "MIT", @@ -9,53 +9,54 @@ "dev": "yarn generate-json && astro dev", "build": "yarn generate-json && astro build", "preview": "astro preview", + "check": "astro check", "format": "prettier -w ./src", "generate-json": "node scripts/jsonGenerator.js", "remove-darkmode": "node scripts/removeDarkmode.js && yarn format" }, "dependencies": { - "@astrojs/check": "^0.9.3", - "@astrojs/mdx": "^3.1.4", - "@astrojs/react": "^3.6.2", - "@astrojs/rss": "^4.0.7", - "@astrojs/sitemap": "^3.1.6", - "@astrojs/tailwind": "^5.1.0", - "astro": "^4.14.5", - "astro-auto-import": "^0.4.2", + "@astrojs/check": "0.9.4", + "@astrojs/mdx": "4.0.3", + "@astrojs/react": "4.1.2", + "@astrojs/rss": "4.0.11", + "@astrojs/sitemap": "3.2.1", + "@astrojs/tailwind": "5.1.4", + "astro": "5.1.2", + "astro-auto-import": "^0.4.4", "astro-font": "^0.1.81", - "date-fns": "^3.6.0", + "date-fns": "^4.1.0", "disqus-react": "^1.1.5", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", - "marked": "^14.1.0", + "marked": "^15.0.5", "prettier-plugin-astro": "^0.14.1", - "prettier-plugin-tailwindcss": "^0.6.6", + "prettier-plugin-tailwindcss": "^0.6.9", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-icons": "^5.3.0", + "react-icons": "^5.4.0", "react-lite-youtube-embed": "^2.4.0", "remark-collapse": "^0.1.2", "remark-toc": "^9.0.0", - "swiper": "^11.1.10" + "swiper": "^11.2.0" }, "devDependencies": { - "@tailwindcss/forms": "^0.5.7", - "@tailwindcss/typography": "^0.5.14", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", "@types/marked": "^5.0.2", - "@types/node": "22.5.0", - "@types/react": "18.3.4", - "@types/react-dom": "18.3.0", + "@types/node": "22.10.5", + "@types/react": "19.0.2", + "@types/react-dom": "19.0.2", "autoprefixer": "^10.4.20", - "eslint": "^9.9.1", - "postcss": "^8.4.41", - "prettier": "^3.3.3", + "eslint": "^9.17.0", + "postcss": "^8.4.49", + "prettier": "^3.4.2", "prettier-plugin-astro": "^0.14.1", - "prettier-plugin-tailwindcss": "^0.6.6", - "sass": "^1.77.8", + "prettier-plugin-tailwindcss": "^0.6.9", + "sass": "^1.83.1", "sharp": "0.33.5", "tailwind-bootstrap-grid": "^5.1.0", - "tailwindcss": "^3.4.10", - "typescript": "^5.5.4" + "tailwindcss": "^3.4.17", + "typescript": "^5.7.2" } } diff --git a/readme.md b/readme.md index ab5c00c..9d9b949 100755 --- a/readme.md +++ b/readme.md @@ -66,7 +66,7 @@ ### 📦 Dependencies -- astro v4.12+ +- astro v5.1+ - node v20.10+ - npm v10.2+ - tailwind v3.4+ diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100755 index 0000000..4247322 --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,163 @@ +import { glob } from "astro/loaders"; +import { defineCollection, z } from "astro:content"; + +// Post collection schema +const blogCollection = defineCollection({ + loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/blog" }), + schema: z.object({ + title: z.string(), + meta_title: z.string().optional(), + description: z.string().optional(), + date: z.date().optional(), + image: z.string().optional(), + author: z.string().default("Admin"), + categories: z.array(z.string()).default(["others"]), + tags: z.array(z.string()).default(["others"]), + draft: z.boolean().optional(), + }), +}); + +// Author collection schema +const authorsCollection = defineCollection({ + loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/authors" }), + schema: z.object({ + title: z.string(), + meta_title: z.string().optional(), + email: z.string().optional(), + image: z.string().optional(), + description: z.string().optional(), + social: z + .array( + z + .object({ + name: z.string().optional(), + icon: z.string().optional(), + link: z.string().optional(), + }) + .optional(), + ) + .optional(), + draft: z.boolean().optional(), + }), +}); + +// Pages collection schema +const pagesCollection = defineCollection({ + loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/pages" }), + schema: z.object({ + title: z.string(), + meta_title: z.string().optional(), + description: z.string().optional(), + image: z.string().optional(), + draft: z.boolean().optional(), + }), +}); + +// about collection schema +const aboutCollection = defineCollection({ + loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/about" }), + schema: z.object({ + title: z.string(), + meta_title: z.string().optional(), + description: z.string().optional(), + image: z.string().optional(), + draft: z.boolean().optional(), + }), +}); + +// contact collection schema +const contactCollection = defineCollection({ + loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/contact" }), + schema: z.object({ + title: z.string(), + meta_title: z.string().optional(), + description: z.string().optional(), + image: z.string().optional(), + draft: z.boolean().optional(), + }), +}); + +// Homepage collection schema +const homepageCollection = defineCollection({ + loader: glob({ pattern: "**/-*.{md,mdx}", base: "src/content/homepage" }), + schema: z.object({ + banner: z.object({ + title: z.string(), + content: z.string(), + image: z.string(), + button: z.object({ + enable: z.boolean(), + label: z.string(), + link: z.string(), + }), + }), + features: z.array( + z.object({ + title: z.string(), + image: z.string(), + content: z.string(), + bulletpoints: z.array(z.string()), + button: z.object({ + enable: z.boolean(), + label: z.string(), + link: z.string(), + }), + }), + ), + }), +}); + +// Call to Action collection schema +const ctaSectionCollection = defineCollection({ + loader: glob({ + pattern: "call-to-action.{md,mdx}", + base: "src/content/sections", + }), + schema: z.object({ + enable: z.boolean(), + title: z.string(), + description: z.string(), + image: z.string(), + button: z.object({ + enable: z.boolean(), + label: z.string(), + link: z.string(), + }), + }), +}); + +// Testimonials Section collection schema +const testimonialSectionCollection = defineCollection({ + loader: glob({ + pattern: "testimonial.{md,mdx}", + base: "src/content/sections", + }), + schema: z.object({ + enable: z.boolean(), + title: z.string(), + description: z.string(), + testimonials: z.array( + z.object({ + name: z.string(), + avatar: z.string(), + designation: z.string(), + content: z.string(), + }), + ), + }), +}); + +// Export collections +export const collections = { + // Pages + homepage: homepageCollection, + blog: blogCollection, + authors: authorsCollection, + pages: pagesCollection, + about: aboutCollection, + contact: contactCollection, + + // sections + ctaSection: ctaSectionCollection, + testimonialSection: testimonialSectionCollection, +}; diff --git a/src/content/config.ts b/src/content/config.ts deleted file mode 100755 index 6b926a5..0000000 --- a/src/content/config.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { defineCollection, z } from "astro:content"; - -// Post collection schema -const blogCollection = defineCollection({ - schema: z.object({ - title: z.string(), - meta_title: z.string().optional(), - description: z.string().optional(), - date: z.date().optional(), - image: z.string().optional(), - author: z.string().default("Admin"), - categories: z.array(z.string()).default(["others"]), - tags: z.array(z.string()).default(["others"]), - draft: z.boolean().optional(), - }), -}); - -// Author collection schema -const authorsCollection = defineCollection({ - schema: z.object({ - title: z.string(), - meta_title: z.string().optional(), - email: z.string().optional(), - image: z.string().optional(), - description: z.string().optional(), - social: z - .array( - z - .object({ - name: z.string().optional(), - icon: z.string().optional(), - link: z.string().optional(), - }) - .optional(), - ) - .optional(), - draft: z.boolean().optional(), - }), -}); - -// Pages collection schema -const pagesCollection = defineCollection({ - schema: z.object({ - title: z.string(), - meta_title: z.string().optional(), - description: z.string().optional(), - image: z.string().optional(), - draft: z.boolean().optional(), - }), -}); - -// Export collections -export const collections = { - blog: blogCollection, - authors: authorsCollection, - pages: pagesCollection, -}; diff --git a/src/env.d.ts b/src/env.d.ts deleted file mode 100755 index acef35f..0000000 --- a/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 5c189eb..3e80aee 100755 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -7,7 +7,7 @@ import Footer from "@/partials/Footer.astro"; import Header from "@/partials/Header.astro"; import "@/styles/main.scss"; import { AstroFont } from "astro-font"; -import { ViewTransitions } from "astro:transitions"; +import { ClientRouter } from "astro:transitions"; import SearchModal from "./helpers/SearchModal"; // font families @@ -111,7 +111,7 @@ const { title, meta_title, description, image, noindex, canonical } = )} /> - + diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index 5f59a02..607be15 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -8,13 +8,14 @@ import similarItems from "@/lib/utils/similarItems"; import { humanize, markdownify, slugify } from "@/lib/utils/textConverter"; import { FaRegClock, FaRegFolder, FaRegUserCircle } from "react-icons/fa"; import ImageMod from "./components/ImageMod.astro"; +import { render } from "astro:content"; const COLLECTION_FOLDER = "blog"; const { post } = Astro.props; const posts = await getSinglePage(COLLECTION_FOLDER); const similarPosts = similarItems(post, posts); -const { Content } = await post.render(); +const { Content } = await render(post); const { title, description, author, categories, image, date, tags } = post.data; --- diff --git a/src/layouts/components/AuthorCard.astro b/src/layouts/components/AuthorCard.astro index bd00f86..1cc4644 100644 --- a/src/layouts/components/AuthorCard.astro +++ b/src/layouts/components/AuthorCard.astro @@ -23,7 +23,7 @@ const { title, image, social } = data.data; ) }

- {title} + {title}

{plainify(data.body?.slice(0, 100))} diff --git a/src/layouts/components/BlogCard.astro b/src/layouts/components/BlogCard.astro index 268a532..7d1390b 100644 --- a/src/layouts/components/BlogCard.astro +++ b/src/layouts/components/BlogCard.astro @@ -27,7 +27,7 @@ const { title, image, date, author, categories } = data.data; ) }

- + {title}

@@ -52,10 +52,7 @@ const { title, image, date, author, categories } = data.data; {date &&
  • {dateFormat(date)}
  • }

    {plainify(data.body?.slice(0, Number(summary_length)))}

    - + read more diff --git a/src/lib/contentParser.astro b/src/lib/contentParser.astro index a6d1013..85685c8 100644 --- a/src/lib/contentParser.astro +++ b/src/lib/contentParser.astro @@ -6,7 +6,7 @@ import { } from "astro:content"; export const getSinglePage = async ( - collectionName: C, + collectionName: C ): Promise[]> => { const allPages = await getCollection(collectionName); const removeIndex = allPages.filter((data) => data.id.match(/^(?!-)/)); diff --git a/src/pages/[regular].astro b/src/pages/[regular].astro index 9990e6a..0de149a 100755 --- a/src/pages/[regular].astro +++ b/src/pages/[regular].astro @@ -2,6 +2,7 @@ import Base from "@/layouts/Base.astro"; import { getSinglePage } from "@/lib/contentParser.astro"; import PageHeader from "@/partials/PageHeader.astro"; +import { render } from "astro:content"; // get static paths for all pages export async function getStaticPaths() { @@ -11,7 +12,7 @@ export async function getStaticPaths() { const paths = pages.map((page) => ({ params: { - regular: page.slug, + regular: page.id, }, props: { page }, })); @@ -20,7 +21,7 @@ export async function getStaticPaths() { const { page } = Astro.props; const { title, meta_title, description, image } = page.data; -const { Content } = await page.render(); +const { Content } = await render(page); --- ; +const { Content } = await render(about); const { title, description, meta_title, image } = about.data; --- diff --git a/src/pages/authors/[single].astro b/src/pages/authors/[single].astro index aff6b94..7308c2c 100755 --- a/src/pages/authors/[single].astro +++ b/src/pages/authors/[single].astro @@ -5,6 +5,7 @@ import Social from "@/components/Social.astro"; import Base from "@/layouts/Base.astro"; import { getSinglePage } from "@/lib/contentParser.astro"; import { slugify } from "@/lib/utils/textConverter"; +import { render } from "astro:content"; // get all static paths for authors export async function getStaticPaths() { @@ -13,7 +14,7 @@ export async function getStaticPaths() { const paths = authors.map((author) => ({ params: { - single: author.slug, + single: author.id, }, props: { author }, })); @@ -22,13 +23,13 @@ export async function getStaticPaths() { const { author } = Astro.props; const { title, social, meta_title, description, image } = author.data; -const { Content } = await author.render(); +const { Content } = await render(author); // get all posts by author const BLOG_FOLDER = "blog"; const posts = await getSinglePage(BLOG_FOLDER); const postFilterByAuthor = posts.filter( - (post) => slugify(post.data.author) === slugify(title), + (post) => slugify(post.data.author) === slugify(title) ); --- diff --git a/src/pages/authors/index.astro b/src/pages/authors/index.astro index 8df557f..78707c3 100755 --- a/src/pages/authors/index.astro +++ b/src/pages/authors/index.astro @@ -3,11 +3,14 @@ import AuthorCard from "@/components/AuthorCard.astro"; import Base from "@/layouts/Base.astro"; import { getSinglePage } from "@/lib/contentParser.astro"; import PageHeader from "@/partials/PageHeader.astro"; -import { getEntry } from "astro:content"; +import { getEntry, type CollectionEntry } from "astro:content"; const COLLECTION_FOLDER = "authors"; -const authorIndex = await getEntry(COLLECTION_FOLDER, "-index"); +const authorIndex = (await getEntry( + COLLECTION_FOLDER, + "-index" +)) as CollectionEntry<"authors">; const authors = await getSinglePage(COLLECTION_FOLDER); --- diff --git a/src/pages/blog/[single].astro b/src/pages/blog/[single].astro index 984477b..62fb1f9 100755 --- a/src/pages/blog/[single].astro +++ b/src/pages/blog/[single].astro @@ -9,7 +9,7 @@ export async function getStaticPaths() { const paths = posts.map((post) => ({ params: { - single: post.slug, + single: post.id, }, props: { post }, })); diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index 4a29c30..fa0fcb1 100755 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -8,11 +8,15 @@ import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro"; import { sortByDate } from "@/lib/utils/sortFunctions"; import PageHeader from "@/partials/PageHeader.astro"; import PostSidebar from "@/partials/PostSidebar.astro"; +import type { CollectionEntry } from "astro:content"; import { getEntry } from "astro:content"; const BLOG_FOLDER = "blog"; -const postIndex = await getEntry(BLOG_FOLDER, "-index"); +const postIndex = (await getEntry( + BLOG_FOLDER, + "-index" +)) as CollectionEntry<"blog">; const posts = await getSinglePage(BLOG_FOLDER); const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories"); const categories = await getTaxonomy(BLOG_FOLDER, "categories"); @@ -28,7 +32,7 @@ const currentPosts = sortedPosts.slice(0, config.settings.pagination); image={postIndex.data.image} description={postIndex.data.description} > - +
    diff --git a/src/pages/blog/page/[slug].astro b/src/pages/blog/page/[slug].astro index 26b7e1e..fb2b0ef 100755 --- a/src/pages/blog/page/[slug].astro +++ b/src/pages/blog/page/[slug].astro @@ -8,12 +8,16 @@ import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro"; import { sortByDate } from "@/lib/utils/sortFunctions"; import PageHeader from "@/partials/PageHeader.astro"; import PostSidebar from "@/partials/PostSidebar.astro"; +import type { CollectionEntry } from "astro:content"; import { getEntry } from "astro:content"; const BLOG_FOLDER = "blog"; const { slug } = Astro.params; -const postIndex = await getEntry(BLOG_FOLDER, "-index"); +const postIndex = (await getEntry( + BLOG_FOLDER, + "-index" +)) as CollectionEntry<"blog">; const posts = await getSinglePage(BLOG_FOLDER); const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories"); const categories = await getTaxonomy(BLOG_FOLDER, "categories"); diff --git a/src/pages/contact.astro b/src/pages/contact.astro index 56742a8..430f639 100644 --- a/src/pages/contact.astro +++ b/src/pages/contact.astro @@ -3,8 +3,12 @@ import config from "@/config/config.json"; import Base from "@/layouts/Base.astro"; import PageHeader from "@/partials/PageHeader.astro"; import { getEntry } from "astro:content"; +import type { CollectionEntry } from "astro:content"; -const contact = await getEntry("contact", "-index"); +const contact = (await getEntry( + "contact", + "-index" +)) as CollectionEntry<"contact">; const { contact_form_action }: { contact_form_action: string } = config.params; const { title, description, meta_title, image } = contact.data; --- diff --git a/src/pages/index.astro b/src/pages/index.astro index 19d3f99..8c1e473 100755 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -5,6 +5,7 @@ import { markdownify } from "@/lib/utils/textConverter"; import CallToAction from "@/partials/CallToAction.astro"; import Testimonial from "@/partials/Testimonial.astro"; import type { Button, Feature } from "@/types"; +import type { CollectionEntry } from "astro:content"; import { getEntry } from "astro:content"; import { FaCheck } from "react-icons/fa"; @@ -18,10 +19,22 @@ interface Homepage { features: Feature[]; } -const homepage = await getEntry("homepage", "-index"); -const testimonial = await getEntry("sections", "testimonial"); -const call_to_action = await getEntry("sections", "call-to-action"); -const { banner, features }: Homepage = homepage.data; +const homepage = (await getEntry( + "homepage", + "-index" +)) as CollectionEntry<"homepage">; + +const testimonial = (await getEntry( + "testimonialSection", + "testimonial" +)) as CollectionEntry<"testimonialSection">; + +const call_to_action = (await getEntry( + "ctaSection", + "call-to-action" +)) as CollectionEntry<"ctaSection">; + +const { banner, features } = homepage.data as Homepage; --- diff --git a/tsconfig.json b/tsconfig.json index 18d9566..a1ea013 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,6 @@ "@/*": ["./src/*"] } }, - "include": ["**/*.ts", "**/*.tsx", "**/*.astro"], - "exclude": ["node_modules"] + "include": [".astro/types.d.ts", "**/*.ts", "**/*.tsx", "**/*.astro"], + "exclude": ["node_modules", "dist"] }