diff --git a/package.json b/package.json
index 47fb75f..91aee3a 100755
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "astroplate",
- "version": "5.5.2",
+ "version": "5.6.0",
"description": "Astro and Tailwindcss boilerplate",
"author": "zeon.studio",
"license": "MIT",
- "type": "module",
"packageManager": "yarn@1.22.22",
+ "type": "module",
"scripts": {
"dev": "yarn generate-json && astro dev",
"build": "yarn generate-json && astro build",
@@ -17,20 +17,19 @@
},
"dependencies": {
"@astrojs/check": "0.9.4",
- "@astrojs/mdx": "4.3.6",
+ "@astrojs/mdx": "4.3.7",
"@astrojs/react": "4.4.0",
- "@astrojs/rss": "4.0.12",
"@astrojs/sitemap": "3.6.0",
"@digi4care/astro-google-tagmanager": "^1.6.0",
"@justinribeiro/lite-youtube": "^1.8.2",
- "astro": "5.14.1",
- "astro-auto-import": "^0.4.4",
+ "astro": "5.14.4",
+ "astro-auto-import": "^0.4.5",
"astro-font": "^1.1.0",
"date-fns": "^4.1.0",
"disqus-react": "^1.1.7",
"github-slugger": "^2.0.0",
"gray-matter": "^4.0.3",
- "marked": "^16.3.0",
+ "marked": "^16.4.0",
"prop-types": "^15.8.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
@@ -44,9 +43,9 @@
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.14",
- "@types/node": "24.6.2",
- "@types/react": "19.2.0",
- "@types/react-dom": "19.2.0",
+ "@types/node": "24.7.2",
+ "@types/react": "19.2.2",
+ "@types/react-dom": "19.2.2",
"eslint": "^9.37.0",
"prettier": "^3.6.2",
"prettier-plugin-astro": "^0.14.1",
diff --git a/readme.md b/readme.md
index 0b32044..15ad7fa 100755
--- a/readme.md
+++ b/readme.md
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/src/content.config.ts b/src/content.config.ts
index 4247322..14e4505 100755
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,6 +1,15 @@
import { glob } from "astro/loaders";
import { defineCollection, z } from "astro:content";
+const commonFields = {
+ title: z.string(),
+ description: z.string(),
+ meta_title: z.string().optional(),
+ date: z.date().optional(),
+ image: z.string().optional(),
+ draft: z.boolean(),
+};
+
// Post collection schema
const blogCollection = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "src/content/blog" }),
@@ -21,11 +30,7 @@ const blogCollection = defineCollection({
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(),
+ ...commonFields,
social: z
.array(
z
@@ -45,11 +50,7 @@ const authorsCollection = defineCollection({
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(),
+ ...commonFields,
}),
});
@@ -57,11 +58,7 @@ const pagesCollection = defineCollection({
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(),
+ ...commonFields,
}),
});
@@ -69,11 +66,7 @@ const aboutCollection = defineCollection({
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(),
+ ...commonFields,
}),
});
diff --git a/src/content/authors/-index.md b/src/content/authors/-index.md
index 799f730..da93ef3 100644
--- a/src/content/authors/-index.md
+++ b/src/content/authors/-index.md
@@ -2,4 +2,6 @@
title: "Authors"
meta_title: ""
description: "this is meta description"
+image: ""
+draft: false
---
diff --git a/src/content/blog/-index.md b/src/content/blog/-index.md
index 17564a2..4e1470b 100755
--- a/src/content/blog/-index.md
+++ b/src/content/blog/-index.md
@@ -2,4 +2,6 @@
title: "Blog Posts"
meta_title: ""
description: "this is meta description"
+image: ""
+draft: false
---
diff --git a/src/content/contact/-index.md b/src/content/contact/-index.md
index bd6b9f6..f19bc88 100644
--- a/src/content/contact/-index.md
+++ b/src/content/contact/-index.md
@@ -1,6 +1,7 @@
---
title: "Contact"
-meta_title: ""
description: "this is meta description"
+meta_title: ""
+image: ""
draft: false
---
diff --git a/src/content/pages/elements.mdx b/src/content/pages/elements.mdx
index 40a7329..bfc0a93 100755
--- a/src/content/pages/elements.mdx
+++ b/src/content/pages/elements.mdx
@@ -133,7 +133,8 @@ window.addEventListener("load", (e) => {
### Button
-
+
+
---
@@ -243,7 +244,7 @@ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
### Youtube video
-
+
---
diff --git a/src/layouts/shortcodes/Youtube.tsx b/src/layouts/shortcodes/Youtube.tsx
index 13fb624..4c6bce5 100644
--- a/src/layouts/shortcodes/Youtube.tsx
+++ b/src/layouts/shortcodes/Youtube.tsx
@@ -14,7 +14,7 @@ const Youtube = ({
}, []);
// @ts-ignore
- return ;
+ return ;
};
export default Youtube;
diff --git a/src/lib/contentParser.astro b/src/lib/contentParser.astro
index fc1654a..efe38ff 100644
--- a/src/lib/contentParser.astro
+++ b/src/lib/contentParser.astro
@@ -1,6 +1,7 @@
---
import {
getCollection,
+ getEntry,
type CollectionEntry,
type CollectionKey,
} from "astro:content";
@@ -16,15 +17,28 @@ type PageData = {
export const getSinglePage = async (
collectionName: C
): Promise[]> => {
- const allPages = await getCollection(collectionName);
+ const allPages = await getCollection(
+ collectionName,
+ ({ data, id }) => !(data as PageData)?.draft && !id.startsWith("-")
+ );
+ return allPages;
+};
- const removeIndex = allPages.filter((data) => data.id.match(/^(?!-)/));
+export const getListPage = async (
+ collectionName: C,
+ documentId: "-index" | string
+): Promise> => {
+ const data = (await getEntry(
+ collectionName,
+ documentId
+ )) as CollectionEntry | null;
- const removeDrafts = removeIndex.filter((data) => {
- const pageData = data.data as PageData;
- return pageData.draft !== true;
- });
+ if (!data) {
+ throw new Error(
+ `No page found for the collection: ${collectionName} with filename: ${documentId}`
+ );
+ }
- return removeDrafts;
+ return data;
};
---
diff --git a/src/pages/about.astro b/src/pages/about.astro
index 5dac8fb..81514da 100644
--- a/src/pages/about.astro
+++ b/src/pages/about.astro
@@ -1,13 +1,17 @@
---
import ImageMod from "@/components/ImageMod.astro";
import Base from "@/layouts/Base.astro";
+import { getListPage } from "@/lib/contentParser.astro";
import { markdownify } from "@/lib/utils/textConverter";
-import type { CollectionEntry } from "astro:content";
-import { getEntry, render } from "astro:content";
+import { render } from "astro:content";
-const about = (await getEntry("about", "-index")) as CollectionEntry<"about">;
-const { Content } = await render(about);
-const { title, description, meta_title, image } = about.data;
+const aboutIndex = await getListPage("about", "-index");
+const { Content } = await render(aboutIndex);
+const { title, description, meta_title, image } = aboutIndex.data;
+
+if (aboutIndex.data.draft) {
+ return Astro.redirect("/404");
+}
---
;
-const authors = await getSinglePage(COLLECTION_FOLDER);
+if (authorIndex.data.draft) {
+ return Astro.redirect("/404");
+}
+
+const authors = await getSinglePage("authors");
---
diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro
index fa0fcb1..3a7e0a6 100755
--- a/src/pages/blog/index.astro
+++ b/src/pages/blog/index.astro
@@ -3,20 +3,18 @@ import BlogCard from "@/components/BlogCard.astro";
import Pagination from "@/components/Pagination.astro";
import config from "@/config/config.json";
import Base from "@/layouts/Base.astro";
-import { getSinglePage } from "@/lib/contentParser.astro";
+import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
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"
-)) as CollectionEntry<"blog">;
+const postIndex = await getListPage(BLOG_FOLDER, "-index");
+if (postIndex.data.draft) {
+ return Astro.redirect("/404");
+}
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/blog/page/[slug].astro b/src/pages/blog/page/[slug].astro
index fb2b0ef..fd4c170 100755
--- a/src/pages/blog/page/[slug].astro
+++ b/src/pages/blog/page/[slug].astro
@@ -3,21 +3,21 @@ import BlogCard from "@/components/BlogCard.astro";
import Pagination from "@/components/Pagination.astro";
import config from "@/config/config.json";
import Base from "@/layouts/Base.astro";
-import { getSinglePage } from "@/lib/contentParser.astro";
+import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
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"
-)) as CollectionEntry<"blog">;
+const postIndex = await getListPage(BLOG_FOLDER, "-index");
+
+if (postIndex.data.draft) {
+ return Astro.redirect("/404");
+}
+
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 430f639..21106ce 100644
--- a/src/pages/contact.astro
+++ b/src/pages/contact.astro
@@ -1,16 +1,16 @@
---
import config from "@/config/config.json";
import Base from "@/layouts/Base.astro";
+import { getListPage } from "@/lib/contentParser.astro";
import PageHeader from "@/partials/PageHeader.astro";
-import { getEntry } from "astro:content";
-import type { CollectionEntry } from "astro:content";
-const contact = (await getEntry(
- "contact",
- "-index"
-)) as CollectionEntry<"contact">;
+const contactIndex = await getListPage("contact", "-index");
const { contact_form_action }: { contact_form_action: string } = config.params;
-const { title, description, meta_title, image } = contact.data;
+const { title, description, meta_title, image } = contactIndex.data;
+
+if (contactIndex.data.draft) {
+ return Astro.redirect("/404");
+}
---
@@ -47,6 +48,7 @@ const { title, description, meta_title, image } = contact.data;
class="form-input"
placeholder="john.doe@email.com"
type="email"
+ required
/>
@@ -58,6 +60,7 @@ const { title, description, meta_title, image } = contact.data;
name="message"
class="form-input"
placeholder="Message goes here..."
+ required
rows="8">
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 8c1e473..33883db 100755
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,40 +1,17 @@
---
import ImageMod from "@/components/ImageMod.astro";
import Base from "@/layouts/Base.astro";
+import { getListPage } from "@/lib/contentParser.astro";
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";
-interface Homepage {
- banner: {
- title: string;
- content: string;
- image: string;
- button: Button;
- };
- features: Feature[];
-}
+const homepage = await getListPage("homepage", "-index");
+const call_to_action = await getListPage("ctaSection", "call-to-action");
+const testimonial = await getListPage("testimonialSection", "testimonial");
-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;
+const { banner, features } = homepage.data;
---
diff --git a/src/styles/base.css b/src/styles/base.css
index 397aec3..e58498b 100755
--- a/src/styles/base.css
+++ b/src/styles/base.css
@@ -57,3 +57,7 @@ code {
blockquote > p {
@apply my-0!;
}
+
+button {
+ @apply cursor-pointer;
+}