changed the content folder structure && fixed breadcrumps

This commit is contained in:
Al Murad Uzzaman
2024-05-23 15:39:53 +06:00
parent 521fd4804d
commit d5e012e6f8
54 changed files with 295 additions and 60 deletions
+6 -5
View File
@@ -9,11 +9,12 @@ const CONTENT_DEPTH = 3;
const BLOG_FOLDER = "blog";
// get data from markdown
const getData = (folder, groupDepth) => {
const getData = (folder, groupDepth, langIndex = 0) => {
// get paths
const getPaths = languages
.map((lang) => {
const dir = path.join(CONTENT_ROOT, lang.contentDir, folder);
.map((lang, index) => {
const langFolder = lang.contentDir ? lang.contentDir : lang.languageCode;
const dir = path.join(CONTENT_ROOT, folder, langFolder);
return fs
.readdirSync(dir)
.filter(
@@ -27,7 +28,7 @@ const getData = (folder, groupDepth) => {
const isFolder = stats.isDirectory();
if (isFolder) {
return getData(filepath, groupDepth);
return getData(filepath, groupDepth, index);
} else {
const file = fs.readFileSync(filepath, "utf-8");
const { data, content } = matter(file);
@@ -41,7 +42,7 @@ const getData = (folder, groupDepth) => {
const group = pathParts[groupDepth];
return {
lang: lang.languageCode,
lang: languages[langIndex].languageCode,
group: group,
slug: slug,
frontmatter: data,
+1 -1
View File
@@ -3,7 +3,7 @@
"title": "Astroplate",
"base_url": "https://astroplate.netlify.app",
"base_path": "/",
"trailing_slash": false,
"trailing_slash": true,
"favicon": "/images/favicon.png",
"logo": "/images/logo.png",
"logo_darkmode": "/images/logo-darkmode.png",
+11
View File
@@ -0,0 +1,11 @@
import { z } from "zod";
const AboutSchema = z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string().optional(),
image: z.string(),
draft: z.boolean().optional(),
});
export default AboutSchema;
@@ -6,4 +6,4 @@ image: "/images/avatar.png"
draft: false
---
L'entreprise elle-même est une entreprise très prospère. Ils ne connaissent pas les bienfaits du corps, ou sauf qu'ils le recevront à d'autres moments, le tout, les temps de travail, qu'il déteste à partir de ce moment mais. Il fuit les plaisirs perçus pour être supposés n'être rien, tout ou, et la douleur est ce qui est la plus grande option, car cela lui est facile, et avec ce que cela s'ensuit, ils lui procurent de la douleur et ainsi de suite ! Car ledit expédient de la vérité repousse le plaisir et empêche la douleur, ils fournissent comme si
L'entreprise elle-même est une entreprise très prospère. Ils ne connaissent pas les bienfaits du corps, ou sauf qu'ils le recevront à d'autres moments, le tout, les temps de travail, qu'il déteste à partir de ce moment mais. Il fuit les plaisirs perçus pour être supposés n'être rien, tout ou, et la douleur est ce qui est la plus grande option, car cela lui est facile, et avec ce que cela s'ensuit, ils lui procurent de la douleur et ainsi de suite ! Car ledit expédient de la vérité repousse le plaisir et empêche la douleur, ils fournissent comme si
+29
View File
@@ -0,0 +1,29 @@
import { defineCollection, z } from "astro:content";
// 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(),
}),
});
// Export collections
export const collections = {
authors: authorsCollection,
};
+33
View File
@@ -0,0 +1,33 @@
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(),
}),
});
// 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,
pages: pagesCollection,
};
+14
View File
@@ -0,0 +1,14 @@
import { defineCollection, z } from "astro:content";
const contactCollection = defineCollection({
schema: z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string(),
draft: z.boolean().optional(),
}),
});
export const collections = {
contact: contactCollection,
};
+42
View File
@@ -0,0 +1,42 @@
import { defineCollection, z } from "astro:content";
// Banner schema
const bannerSchema = z.object({
title: z.string(),
content: z.string(),
image: z.string(),
button: z.object({
enable: z.boolean(),
label: z.string(),
link: z.string(),
}),
});
// Features schema
const featureSchema = 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().optional(),
link: z.string().optional(),
}),
});
// Main content schema
const contentSchema = z.object({
banner: bannerSchema,
features: z.array(featureSchema),
});
// Define the collection
const contentCollection = defineCollection({
schema: contentSchema,
});
// Export collections
export const collections = {
content: contentCollection,
};
@@ -50,4 +50,4 @@ features:
enable: false
label: ""
link: ""
---
---
+24
View File
@@ -0,0 +1,24 @@
import { defineCollection, z } from "astro:content";
const elementsCollection = defineCollection({
schema: z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string(),
draft: z.boolean().optional(),
}),
});
const privacyCollection = defineCollection({
schema: z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string(),
draft: z.boolean().optional(),
}),
});
export const collections = {
elements: elementsCollection,
privacy: privacyCollection,
};
+28
View File
@@ -0,0 +1,28 @@
import { z } from "zod";
const TestimonialSchema = z.object({
name: z.string(),
designation: z.string(),
avatar: z.string(),
content: z.string(),
});
const TestimonialsSchema = z.array(TestimonialSchema);
const CallToActionSchema = z.object({
enable: z.boolean(),
title: z.string(),
image: z.string(),
description: z.string(),
button: z.object({
enable: z.boolean(),
label: z.string(),
link: z.string().url(),
}),
});
export const collections = {
Testimonial: TestimonialSchema,
Testimonials: TestimonialsSchema,
CallToAction: CallToActionSchema,
};
+5
View File
@@ -18,6 +18,11 @@ const { title, image, date, author, categories } = data.data;
const lang = getLangFromUrl(Astro.url);
const { read_more } = await getTranslations(lang as keyof ContentEntryMap);
const slugParts = data.slug.split("/");
slugParts[0] = "blog";
const modifiedSlug = slugParts.join("/");
data.slug = modifiedSlug;
---
<div class="bg-body dark:bg-darkmode-body">
+4 -3
View File
@@ -11,19 +11,20 @@ if (supportedLang.includes(paths[0])) {
lang = paths.shift()!;
}
let baseHref = lang ? `/${lang}` : "/";
let parts = [
{
label: "Home",
href: `/${lang}`,
href: baseHref,
"aria-label":
Astro.url.pathname === `/${lang}` || Astro.url.pathname === `/${lang}/`
Astro.url.pathname === baseHref || Astro.url.pathname === `${baseHref}/`
? "page"
: undefined,
},
];
paths.forEach((label: string, i: number) => {
const href = `/${lang}/${paths.slice(0, i + 1).join("/")}`;
const href = `${baseHref}${paths.slice(0, i + 1).join("/")}`;
label !== "page" &&
parts.push({
label: humanize(label.replace(".html", "").replace(/[-_]/g, " ")) || "",
+1 -1
View File
@@ -67,7 +67,7 @@ const { testimonial } = Astro.props;
</div>
</div>
</div>
),
)
)}
</div>
<div class="testimonial-slider-pagination mt-9 flex items-center justify-center text-center" />
+66 -2
View File
@@ -9,7 +9,7 @@ import {
import config from "@/config/config.json";
import languages from "@/config/language.json";
export const getSinglePage = async <C extends CollectionKey>(
export const getSP = async <C extends CollectionKey>(
collectionName: C,
lang: keyof ContentEntryMap | undefined
): Promise<CollectionEntry<C>[]> => {
@@ -40,7 +40,7 @@ export const getSinglePage = async <C extends CollectionKey>(
return removeDrafts;
};
export const getListPage = async <C extends CollectionKey>(
export const getLP = async <C extends CollectionKey>(
collectionName: C,
lang: keyof ContentEntryMap | undefined
): Promise<CollectionEntry<C>[]> => {
@@ -67,4 +67,68 @@ export const getListPage = async <C extends CollectionKey>(
return pages;
};
export const getSinglePage = async <C extends CollectionKey>(
collectionName: C,
lang: keyof ContentEntryMap | undefined,
subCollectionName?: string
): Promise<CollectionEntry<C>[]> => {
const { default_language } = config.settings;
const selectedLanguageCode = lang || default_language;
const language = languages.find(
(l: any) => l.languageCode === selectedLanguageCode
);
if (!language) {
throw new Error("Language not found");
}
const { contentDir } = language;
const path = subCollectionName
? `${contentDir}/${subCollectionName}`
: contentDir;
const pages: CollectionEntry<C>[] = (await getCollection(
collectionName as any,
({ id }: any) => {
return id.startsWith(path) && !id.endsWith("-index.md");
}
)) as CollectionEntry<C>[];
// @ts-ignore
const removeDrafts = pages.filter((data) => !data.data.draft);
return removeDrafts;
};
export const getListPage = async <C extends CollectionKey>(
collectionName: C,
lang: keyof ContentEntryMap | undefined
): Promise<CollectionEntry<C>[]> => {
const { default_language } = config.settings;
const selectedLanguageCode = lang || default_language;
const language = languages.find(
(l: any) => l.languageCode == selectedLanguageCode
);
if (!language) {
throw new Error("Language not found");
}
const { contentDir } = language;
const pages: CollectionEntry<C>[] = (await getCollection(
collectionName as any,
({ id }: any) => {
return id.startsWith(contentDir);
}
)) as CollectionEntry<C>[];
return pages;
};
---
+8 -8
View File
@@ -16,7 +16,7 @@ export const getTaxonomy = async (collection: string, name: string) => {
actualCollection = language.contentDir;
} else {
const defaultLanguageMatch = languages.find(
(l) => l.languageCode === default_language,
(l) => l.languageCode === default_language
);
if (defaultLanguageMatch) {
actualCollection = defaultLanguageMatch.contentDir;
@@ -24,10 +24,10 @@ export const getTaxonomy = async (collection: string, name: string) => {
}
const singlePages = await getCollection(
actualCollection as keyof ContentEntryMap,
"blog" as keyof ContentEntryMap,
({ id }: any) => {
return id.startsWith("blog") && !id.endsWith("-index.md");
},
return id.startsWith(actualCollection) && !id.endsWith("-index.md");
}
);
const taxonomyPages = singlePages.map((page: any) => page.data[name]);
let taxonomies: string[] = [];
@@ -52,7 +52,7 @@ export const getAllTaxonomy = async (collection: string, name: string) => {
actualCollection = language.contentDir;
} else {
const defaultLanguageMatch = languages.find(
(l) => l.languageCode === default_language,
(l) => l.languageCode === default_language
);
if (defaultLanguageMatch) {
actualCollection = defaultLanguageMatch.contentDir;
@@ -60,10 +60,10 @@ export const getAllTaxonomy = async (collection: string, name: string) => {
}
const singlePages = await getCollection(
actualCollection as keyof ContentEntryMap,
"blog" as keyof ContentEntryMap,
({ id }: any) => {
return id.startsWith("blog") && !id.endsWith("-index.md");
},
return id.startsWith(actualCollection) && !id.endsWith("-index.md");
}
);
const taxonomyPages = singlePages.map((page: any) => page.data[name]);
let taxonomies: string[] = [];
+1 -1
View File
@@ -10,7 +10,7 @@ export async function getStaticPaths() {
supportedLang.map(async (lang) => {
const pages = await getSinglePage("pages", lang as keyof ContentEntryMap);
return pages.map((page: any) => ({
return pages.map((page) => ({
params: {
lang: lang || undefined,
regular: page.slug.split("/").pop(),
+2 -5
View File
@@ -4,7 +4,7 @@ import Base from "@/layouts/Base.astro";
import { getListPage } from "@/lib/contentParser.astro";
import { supportedLang } from "@/lib/utils/languageParser";
import { markdownify } from "@/lib/utils/textConverter";
import type { ContentCollectionKey, ContentEntryMap } from "astro:content";
import type { ContentEntryMap } from "astro:content";
export function getStaticPaths() {
const paths = supportedLang.map((lang) => ({
@@ -14,10 +14,7 @@ export function getStaticPaths() {
}
const { lang } = Astro.params;
const about: any = await getListPage(
"about" as ContentCollectionKey,
lang as keyof ContentEntryMap
);
const about = await getListPage("about", lang as keyof ContentEntryMap);
const { Content } = await about[0].render();
const { title, description, meta_title, image } = about[0].data;
+3 -3
View File
@@ -14,12 +14,12 @@ export async function getStaticPaths() {
const paths = await Promise.all(
supportedLang.map(async (lang) => {
const authors: any = await getSinglePage(
const authors = await getSinglePage(
COLLECTION_FOLDER,
lang as keyof ContentEntryMap
);
return authors.map((author: any) => ({
return authors.map((author) => ({
params: {
lang: lang || undefined,
single: author.slug.split("/").pop(),
@@ -42,7 +42,7 @@ const { Content } = await author.render();
const BLOG_FOLDER = "blog";
const posts = await getSinglePage(BLOG_FOLDER, lang as keyof ContentEntryMap);
const postFilterByAuthor = posts.filter(
(post: any) => slugify(post.data.author) === slugify(title)
(post) => slugify(post.data.author) === slugify(title)
);
---
+1 -1
View File
@@ -16,7 +16,7 @@ export function getStaticPaths() {
}
const { lang } = Astro.params;
const authorIndex: any = await getListPage(
const authorIndex = await getListPage(
COLLECTION_FOLDER,
lang as keyof ContentEntryMap
);
+2 -2
View File
@@ -10,12 +10,12 @@ export async function getStaticPaths() {
const paths = await Promise.all(
supportedLang.map(async (lang) => {
const posts: any = await getSinglePage(
const posts = await getSinglePage(
BLOG_FOLDER,
lang as keyof ContentEntryMap
);
return posts.map((post: any) => ({
return posts.map((post) => ({
params: {
lang: lang || undefined,
single: post.slug.split("/").pop(),
+1 -1
View File
@@ -19,7 +19,7 @@ export function getStaticPaths() {
}
const { lang } = Astro.params;
const BLOG_FOLDER = "blog";
const postIndex: any = await getListPage(
const postIndex = await getListPage(
BLOG_FOLDER,
lang as keyof ContentEntryMap
);
+1 -5
View File
@@ -4,7 +4,6 @@ import Base from "@/layouts/Base.astro";
import { getListPage } from "@/lib/contentParser.astro";
import { getTranslations, supportedLang } from "@/lib/utils/languageParser";
import PageHeader from "@/partials/PageHeader.astro";
import type { CollectionKey } from "astro:content";
import { type ContentEntryMap } from "astro:content";
export function getStaticPaths() {
@@ -15,10 +14,7 @@ export function getStaticPaths() {
}
const { lang } = Astro.params;
const contact: any = await getListPage(
"contact" as CollectionKey,
lang as keyof ContentEntryMap
);
const contact = await getListPage("contact", lang as keyof ContentEntryMap);
const { contact_form_action }: { contact_form_action: string } = config.params;
const { title, description, meta_title, image } = contact[0].data;
+10 -20
View File
@@ -6,18 +6,9 @@ import { supportedLang } from "@/lib/utils/languageParser";
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 { ContentCollectionKey, ContentEntryMap } from "astro:content";
import type { Feature } from "@/types";
import type { ContentEntryMap } from "astro:content";
import { FaCheck } from "react-icons/fa";
interface Homepage {
banner: {
title: string;
content: string;
image: string;
button: Button;
};
features: Feature[];
}
export function getStaticPaths() {
const paths = supportedLang.map((lang) => ({
@@ -27,20 +18,19 @@ export function getStaticPaths() {
}
const { lang } = Astro.params;
const homepage: any = await getListPage(
"homepage" as ContentCollectionKey,
lang as keyof ContentEntryMap
);
const { banner, features }: Homepage = homepage[0].data;
const homepage = await getListPage("homepage", lang as keyof ContentEntryMap);
const { banner, features } = homepage[0].data;
const testimonial = await getSinglePage(
"sections/testimonial" as ContentCollectionKey,
lang as keyof ContentEntryMap
"sections",
lang as keyof ContentEntryMap,
"testimonial"
);
const call_to_action = await getSinglePage(
"sections/call-to-action" as ContentCollectionKey,
lang as keyof ContentEntryMap
"sections",
lang as keyof ContentEntryMap,
"call-to-action"
);
---