mirror of
https://github.com/10h30/astroplate.git
synced 2026-06-05 15:08:00 +09:00
Add draft functionality for pages
This commit is contained in:
+9
-10
@@ -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",
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
</h2>
|
||||
|
||||
<p align=center>
|
||||
<a href="https://github.com/withastro/astro/releases/tag/astro%405.7.8">
|
||||
<img src="https://img.shields.io/static/v1?label=ASTRO&message=5.7&color=000&logo=astro" alt="Astro Version 5.7"/>
|
||||
<a href="https://github.com/withastro/astro/releases/tag/astro%405.14.4">
|
||||
<img src="https://img.shields.io/static/v1?label=ASTRO&message=5.14&color=000&logo=astro" alt="Astro Version 5.14"/>
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/zeon-studio/astroplate/blob/main/LICENSE">
|
||||
|
||||
+13
-20
@@ -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,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
title: "Authors"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
image: ""
|
||||
draft: false
|
||||
---
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
title: "Blog Posts"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
image: ""
|
||||
draft: false
|
||||
---
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: "Contact"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
meta_title: ""
|
||||
image: ""
|
||||
draft: false
|
||||
---
|
||||
|
||||
@@ -133,7 +133,8 @@ window.addEventListener("load", (e) => {
|
||||
|
||||
### Button
|
||||
|
||||
<Button label="Button" link="#" style="solid" />
|
||||
<Button label="Solid" link="#" style="solid" />
|
||||
<Button label="Outline" link="#" style="outline" />
|
||||
|
||||
---
|
||||
|
||||
@@ -243,7 +244,7 @@ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
|
||||
|
||||
### Youtube video
|
||||
|
||||
<Youtube client:load id="C0DPdy98e4c" title="Play:Youtube"/>
|
||||
<Youtube client:load id="C0DPdy98e4c" title="Play:Youtube" />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ const Youtube = ({
|
||||
}, []);
|
||||
|
||||
// @ts-ignore
|
||||
return <lite-youtube videoid={id} videotitle={title} {...rest} />;
|
||||
return <lite-youtube className="rounded-lg" videoid={id} videotitle={title} {...rest} />;
|
||||
};
|
||||
|
||||
export default Youtube;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import {
|
||||
getCollection,
|
||||
getEntry,
|
||||
type CollectionEntry,
|
||||
type CollectionKey,
|
||||
} from "astro:content";
|
||||
@@ -16,15 +17,28 @@ type PageData = {
|
||||
export const getSinglePage = async <C extends CollectionKey>(
|
||||
collectionName: C
|
||||
): Promise<CollectionEntry<C>[]> => {
|
||||
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 <C extends CollectionKey>(
|
||||
collectionName: C,
|
||||
documentId: "-index" | string
|
||||
): Promise<CollectionEntry<C>> => {
|
||||
const data = (await getEntry(
|
||||
collectionName,
|
||||
documentId
|
||||
)) as CollectionEntry<C> | 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;
|
||||
};
|
||||
---
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
---
|
||||
|
||||
<Base
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
---
|
||||
import AuthorCard from "@/components/AuthorCard.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { getEntry, type CollectionEntry } from "astro:content";
|
||||
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
const authorIndex = await getListPage("authors", "-index");
|
||||
|
||||
const authorIndex = (await getEntry(
|
||||
COLLECTION_FOLDER,
|
||||
"-index"
|
||||
)) as CollectionEntry<"authors">;
|
||||
const authors = await getSinglePage(COLLECTION_FOLDER);
|
||||
if (authorIndex.data.draft) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
|
||||
const authors = await getSinglePage("authors");
|
||||
---
|
||||
|
||||
<Base title={authorIndex.data.title}>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
+10
-7
@@ -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");
|
||||
}
|
||||
---
|
||||
|
||||
<Base
|
||||
@@ -35,6 +35,7 @@ const { title, description, meta_title, image } = contact.data;
|
||||
class="form-input"
|
||||
placeholder="John Doe"
|
||||
type="text"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
@@ -47,6 +48,7 @@ const { title, description, meta_title, image } = contact.data;
|
||||
class="form-input"
|
||||
placeholder="john.doe@email.com"
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
@@ -58,6 +60,7 @@ const { title, description, meta_title, image } = contact.data;
|
||||
name="message"
|
||||
class="form-input"
|
||||
placeholder="Message goes here..."
|
||||
required
|
||||
rows="8"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
|
||||
+5
-28
@@ -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;
|
||||
---
|
||||
|
||||
<Base>
|
||||
|
||||
@@ -57,3 +57,7 @@ code {
|
||||
blockquote > p {
|
||||
@apply my-0!;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user