mirror of
https://github.com/10h30/astroplate.git
synced 2026-06-05 15:08:00 +09:00
config ln array changed
This commit is contained in:
@@ -13,8 +13,7 @@
|
||||
},
|
||||
|
||||
"language": {
|
||||
"defaultLang": "en",
|
||||
"supported": ["", "en", "fr", "ar"]
|
||||
"defaultLang": "en"
|
||||
},
|
||||
|
||||
"settings": {
|
||||
@@ -24,7 +23,8 @@
|
||||
"default_theme": "system",
|
||||
"pagination": 2,
|
||||
"summary_length": 200,
|
||||
"blog_folder": "blog"
|
||||
"blog_folder": "blog",
|
||||
"default_language": "en"
|
||||
},
|
||||
|
||||
"params": {
|
||||
|
||||
+17
-42
@@ -1,42 +1,17 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "البدء"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "الاسم الكامل"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "بريد العمل"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "أي شيء آخر؟"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "الرسالة تذهب هنا..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "يُقدِّم"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "الصفحة غير موجودة"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "ربما تمت إزالة الصفحة التي تبحث عنها، أو تم تغيير اسمها، أو أنها غير متاحة مؤقتًا."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "العودة إلى المنزل"
|
||||
}
|
||||
]
|
||||
{
|
||||
"full_name": "الاسم الكامل",
|
||||
"full_name_placeholder": "أدخل اسمك الكامل",
|
||||
"mail": "البريد الإلكتروني العملي",
|
||||
"mail_placeholder": "john.doe@email.com",
|
||||
"message": "هل هناك شيء آخر؟",
|
||||
"message_placeholder": "رسالتك هنا...",
|
||||
"submit": "إرسال",
|
||||
"read_more": "اقرأ المزيد",
|
||||
"page_not_found": "الصفحة غير موجودة",
|
||||
"working_mail": "البريد الإلكتروني العملي",
|
||||
"anything_else": "هل هناك شيء آخر؟",
|
||||
"contact_message_placeholder": "رسالتك هنا...",
|
||||
"page_not_found_content": "قد تمت إزالة الصفحة التي تبحث عنها، أو تغيير اسمها، أو أصبحت غير متوفرة مؤقتًا.",
|
||||
"back_to_home": "العودة إلى الصفحة الرئيسية",
|
||||
"get_started": "البدئة"
|
||||
}
|
||||
|
||||
+17
-42
@@ -1,42 +1,17 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "Get Started"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "Full Name"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "Working Mail"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "Anything else?"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "Message goes here..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "Submit"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "Page Not Found"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "Back to home"
|
||||
}
|
||||
]
|
||||
{
|
||||
"full_name": "Full Name",
|
||||
"full_name_placeholder": "Enter your full name",
|
||||
"mail": "Work Email",
|
||||
"mail_placeholder": "john.doe@email.com",
|
||||
"message": "Anything else?",
|
||||
"message_placeholder": "Your message here...",
|
||||
"submit": "Submit",
|
||||
"read_more": "Read More",
|
||||
"page_not_found": "Page Not Found",
|
||||
"working_mail": "Work Email",
|
||||
"anything_else": "Anything else?",
|
||||
"contact_message_placeholder": "Your message here...",
|
||||
"page_not_found_content": "The page you are looking for may have been removed, renamed, or is temporarily unavailable.",
|
||||
"back_to_home": "Back to Home",
|
||||
"get_started": "Get Started"
|
||||
}
|
||||
|
||||
+17
-42
@@ -1,42 +1,17 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "Commencer"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "Nom et prénom"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "Courrier de travail"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "Rien d'autre?"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "Le message va ici..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "Soumettre"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "Page non trouvée"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "La page que vous recherchez a peut-être été supprimée, son nom a changé ou est temporairement indisponible."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "De retour à la maison"
|
||||
}
|
||||
]
|
||||
{
|
||||
"full_name": "Nom complet",
|
||||
"full_name_placeholder": "Entrez votre nom complet",
|
||||
"mail": "E-mail de travail",
|
||||
"mail_placeholder": "john.doe@email.com",
|
||||
"message": "Autre chose?",
|
||||
"message_placeholder": "Votre message ici...",
|
||||
"submit": "Soumettre",
|
||||
"read_more": "Lire la suite",
|
||||
"page_not_found": "Page non trouvée",
|
||||
"working_mail": "Courrier de travail",
|
||||
"anything_else": "Autre chose ?",
|
||||
"contact_message_placeholder": "Votre message ici...",
|
||||
"page_not_found_content": "La page que vous recherchez a peut-être été supprimée, changée de nom ou temporairement inaccessible.",
|
||||
"back_to_home": "Retour à l'accueil",
|
||||
"get_started": "Commencez à utiliser"
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import enDataJSON from './en.json';
|
||||
import frDataJSON from './fr.json';
|
||||
import arDataJSON from './ar.json';
|
||||
|
||||
|
||||
interface TranslationItem {
|
||||
id: string;
|
||||
translation: string;
|
||||
}
|
||||
|
||||
export function convertJsonToUiObject(jsonData: TranslationItem[], language: string): Record<string, Record<string, string>> {
|
||||
const ui: Record<string, Record<string, string>> = {};
|
||||
ui[language] = {};
|
||||
|
||||
for (const item of jsonData) {
|
||||
ui[language][item.id] = item.translation;
|
||||
}
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
|
||||
export const ui = {
|
||||
...convertJsonToUiObject(enDataJSON, 'en'),
|
||||
...convertJsonToUiObject(frDataJSON, 'fr'),
|
||||
...convertJsonToUiObject(arDataJSON, 'ar')
|
||||
} as const;
|
||||
|
||||
|
||||
// import { readdirSync } from 'fs';
|
||||
// import path from 'path';
|
||||
// import { fileURLToPath } from 'url';
|
||||
|
||||
// interface TranslationItem {
|
||||
// id: string;
|
||||
// translation: string;
|
||||
// }
|
||||
|
||||
// function convertJsonToUiObject(jsonData: TranslationItem[]): Record<string, string> {
|
||||
// const ui: Record<string, string> = {};
|
||||
|
||||
// for (const item of jsonData) {
|
||||
// ui[item.id] = item.translation;
|
||||
// }
|
||||
|
||||
// return ui;
|
||||
// }
|
||||
|
||||
// const __filename = fileURLToPath(import.meta.url);
|
||||
// const i18nFolderPath = path.join(path.dirname(__filename));
|
||||
// const ui: Record<string, Record<string, string>> = {};
|
||||
|
||||
// readdirSync(i18nFolderPath).forEach((file) => {
|
||||
// if (file.endsWith('.json')) {
|
||||
// const language = file.split('.')[0];
|
||||
// import(path.join(i18nFolderPath, file)).then((module) => {
|
||||
// const jsonData: TranslationItem[] = module.default;
|
||||
// ui[language] = convertJsonToUiObject(jsonData);
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// export { ui };
|
||||
@@ -1,20 +1,23 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import dateFormat from "@/lib/utils/dateFormat";
|
||||
import { getLangFromUrl, getTranslations } from "@/lib/utils/i18nUtils";
|
||||
import { humanize, plainify, slugify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { FaRegFolder, FaRegUserCircle } from "react-icons/fa";
|
||||
import ImageMod from "./ImageMod.astro";
|
||||
import { getLangFromUrl } from "@/lib/utils/i18nUtils";
|
||||
|
||||
const {
|
||||
summary_length,
|
||||
blog_folder,
|
||||
}: { summary_length: number; blog_folder: string } = config.settings;
|
||||
const { defaultLang } = config.language;
|
||||
const { data } = Astro.props;
|
||||
const { title, image, date, author, categories } = data.data;
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const path = Astro.url.pathname;
|
||||
const { read_more } = await getTranslations(lang as keyof ContentEntryMap);
|
||||
---
|
||||
|
||||
<div class="bg-body dark:bg-darkmode-body">
|
||||
@@ -33,8 +36,8 @@ const path = Astro.url.pathname;
|
||||
<h4 class="mb-3">
|
||||
<a
|
||||
href={path.includes("/categories")
|
||||
? `/${lang === "en" ? "/" : lang}/blog/${data.slug}`
|
||||
: `/${lang === "en" ? "/" : lang}/${data.slug}`}
|
||||
? `${lang === defaultLang ? "" : `/${lang}`}/blog/${data.slug}`
|
||||
: `${lang === defaultLang ? "" : `/${lang}`}/${data.slug}`}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
@@ -63,9 +66,9 @@ const path = Astro.url.pathname;
|
||||
<a
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
href={path.includes("/categories")
|
||||
? `/${lang === "en" ? "/" : lang}/blog/${data.slug}`
|
||||
: `/${lang === "en" ? "/" : lang}/${data.slug}`}
|
||||
? `${lang === defaultLang ? "" : `/${lang}`}/blog/${data.slug}`
|
||||
: `${lang === defaultLang ? "" : `/${lang}`}/${data.slug}`}
|
||||
>
|
||||
read more
|
||||
{read_more}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
---
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import config from "@/config/config.json";
|
||||
|
||||
const { supported } = config.language;
|
||||
|
||||
const { className }: { className?: string } = Astro.props;
|
||||
|
||||
const paths = Astro.url.pathname.split("/").filter((x) => x);
|
||||
|
||||
let lang = "";
|
||||
if (supported.includes(paths[0])) {
|
||||
if (supportedLang.includes(paths[0])) {
|
||||
lang = paths.shift()!;
|
||||
}
|
||||
|
||||
@@ -17,7 +15,10 @@ let parts = [
|
||||
{
|
||||
label: "Home",
|
||||
href: `/${lang}`,
|
||||
"aria-label": Astro.url.pathname === `/${lang}` || Astro.url.pathname === `/${lang}/` ? "page" : undefined,
|
||||
"aria-label":
|
||||
Astro.url.pathname === `/${lang}` || Astro.url.pathname === `/${lang}/`
|
||||
? "page"
|
||||
: undefined,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -30,7 +31,6 @@ paths.forEach((label: string, i: number) => {
|
||||
"aria-label": Astro.url.pathname === href ? "page" : undefined,
|
||||
});
|
||||
});
|
||||
|
||||
---
|
||||
|
||||
<nav aria-label="Breadcrumb" class={className}>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import languages from "@/config/language.json";
|
||||
import React from 'react';
|
||||
|
||||
const LanguageSwitcher = ({ lang, languages, pathname }: { lang: string; languages: string[]; pathname: string }) => {
|
||||
const LanguageSwitcher = ({ lang, pathname }: { lang: string; pathname: string }) => {
|
||||
|
||||
return (
|
||||
<div className="mr-5">
|
||||
<select
|
||||
@@ -12,20 +14,19 @@ const LanguageSwitcher = ({ lang, languages, pathname }: { lang: string; languag
|
||||
: `/${selectedLang}${pathname.replace(`/${lang}`, "")}`;
|
||||
window.location.href = newPath;
|
||||
}}
|
||||
value={languages.includes(lang) ? lang : 'en'}
|
||||
value={lang}
|
||||
>
|
||||
{languages.map((child: string) => (
|
||||
{languages.map((language) => (
|
||||
<option
|
||||
key={child}
|
||||
value={child}
|
||||
key={language.languageCode}
|
||||
value={language.languageCode}
|
||||
>
|
||||
{child}
|
||||
{language.languageName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default LanguageSwitcher
|
||||
export default LanguageSwitcher;
|
||||
|
||||
@@ -3,21 +3,18 @@ import Logo from "@/components/Logo.astro";
|
||||
import ThemeSwitcher from "@/components/ThemeSwitcher.astro";
|
||||
import config from "@/config/config.json";
|
||||
import LanguageSwitcher from "@/helpers/LanguageSwitcher";
|
||||
import {
|
||||
getLangFromUrl,
|
||||
languages,
|
||||
useTranslations,
|
||||
} from "@/lib/utils/i18nUtils";
|
||||
import { getLangFromUrl, getTranslations } from "@/lib/utils/i18nUtils";
|
||||
import { loadMenu } from "@/lib/utils/loadMenu";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getRelativeLocaleUrl } from "astro:i18n";
|
||||
import { IoSearch } from "react-icons/io5";
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const menu = loadMenu(lang);
|
||||
|
||||
const { navigation_button, settings } = config;
|
||||
const { pathname } = Astro.url;
|
||||
|
||||
const t = useTranslations(lang as any);
|
||||
const { get_started } = await getTranslations(lang as keyof ContentEntryMap);
|
||||
---
|
||||
|
||||
<header class={`header z-30 ${settings.sticky_header && "sticky top-0"}`}>
|
||||
@@ -113,7 +110,7 @@ const t = useTranslations(lang as any);
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
href={navigation_button.link}
|
||||
>
|
||||
{t("get_started")}
|
||||
{get_started}
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
@@ -133,19 +130,14 @@ const t = useTranslations(lang as any);
|
||||
)
|
||||
}
|
||||
<ThemeSwitcher className="mr-5" />
|
||||
<LanguageSwitcher
|
||||
client:load
|
||||
lang={lang}
|
||||
languages={languages}
|
||||
pathname={pathname}
|
||||
/>
|
||||
<LanguageSwitcher client:load lang={lang} pathname={pathname} />
|
||||
{
|
||||
navigation_button.enable && (
|
||||
<a
|
||||
class="btn btn-outline-primary btn-sm hidden lg:inline-block"
|
||||
href={navigation_button.link}
|
||||
>
|
||||
{t("get_started")}
|
||||
{get_started}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
+12
-22
@@ -1,19 +1,4 @@
|
||||
---
|
||||
// import {
|
||||
// getCollection,
|
||||
// type CollectionEntry,
|
||||
// type CollectionKey,
|
||||
// } from "astro:content";
|
||||
|
||||
// export const getSinglePage = async <C extends CollectionKey>(
|
||||
// collectionName: C,
|
||||
// ): Promise<CollectionEntry<C>[]> => {
|
||||
// const allPages = await getCollection(collectionName);
|
||||
// const removeIndex = allPages.filter((data) => data.id.match(/^(?!-)/));
|
||||
// const removeDrafts = removeIndex.filter((data) => !data.data.draft);
|
||||
// return removeDrafts;
|
||||
// };
|
||||
|
||||
import {
|
||||
getCollection,
|
||||
type CollectionEntry,
|
||||
@@ -31,15 +16,17 @@ export const getSinglePage = async <C extends CollectionKey>(
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
|
||||
// Explicitly define the type of pages to CollectionEntry<C>[]
|
||||
const pages: CollectionEntry<C>[] = await getCollection(langCollection || defaultLang, ({ id }) => {
|
||||
return id.startsWith(collectionName) && !id.endsWith("-index.md");
|
||||
}) as CollectionEntry<C>[];
|
||||
const pages: CollectionEntry<C>[] = (await getCollection(
|
||||
langCollection || defaultLang,
|
||||
({ id }: any) => {
|
||||
return id.startsWith(collectionName) && !id.endsWith("-index.md");
|
||||
}
|
||||
)) as CollectionEntry<C>[];
|
||||
|
||||
const removeDrafts = pages.filter((data) => !data.data.draft);
|
||||
return removeDrafts;
|
||||
};
|
||||
|
||||
|
||||
export const getListPage = async <C extends CollectionKey>(
|
||||
collectionName: C,
|
||||
lang: keyof ContentEntryMap
|
||||
@@ -47,9 +34,12 @@ export const getListPage = async <C extends CollectionKey>(
|
||||
const { defaultLang } = config.language;
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
// Fetch the collection based on the language
|
||||
const pages: CollectionEntry<C>[] = await getCollection(langCollection || defaultLang, ({ id }) => {
|
||||
return id.startsWith(collectionName);
|
||||
}) as CollectionEntry<C>[];
|
||||
const pages: CollectionEntry<C>[] = (await getCollection(
|
||||
langCollection || defaultLang,
|
||||
({ id }: any) => {
|
||||
return id.startsWith(collectionName);
|
||||
}
|
||||
)) as CollectionEntry<C>[];
|
||||
|
||||
return pages;
|
||||
};
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
---
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
|
||||
// get taxonomy from frontmatter
|
||||
export const getTaxonomy = async (collection: any, name: string) => {
|
||||
// const singlePages = await getSinglePage(collection);
|
||||
const singlePages = await getCollection(
|
||||
collection as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return id.startsWith("blog") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
@@ -31,7 +29,7 @@ export const getAllTaxonomy = async (collection: any, name: string) => {
|
||||
// const singlePages = await getSinglePage(collection);
|
||||
const singlePages = await getCollection(
|
||||
collection as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return id.startsWith("blog") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
|
||||
+23
-41
@@ -1,14 +1,18 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import config from "@/config/config.json";
|
||||
import languagesJSON from "@/config/language.json";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
const { defaultLang } = config.language;
|
||||
|
||||
const menusFolderPath = './src/config';
|
||||
const menusFolderPath = "./src/config";
|
||||
|
||||
const locales = fs.readdirSync(menusFolderPath)
|
||||
.filter(file => /^menu\.[a-z]{2}\.json$/.test(file))
|
||||
.map(file => {
|
||||
const locales = fs
|
||||
.readdirSync(menusFolderPath)
|
||||
.filter((file) => /^menu\.[a-z]{2}\.json$/.test(file))
|
||||
.map((file) => {
|
||||
const filePath = path.join(menusFolderPath, file);
|
||||
const localeName = file.split('.')[1]; // Extract language code from file name
|
||||
const localeData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
const localeName = file.split(".")[1]; // Extract language code from file name
|
||||
const localeData = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||
return { [localeName]: localeData };
|
||||
})
|
||||
.reduce((accumulator, locale) => {
|
||||
@@ -19,44 +23,22 @@ const locales = fs.readdirSync(menusFolderPath)
|
||||
const languages = Object.keys(locales);
|
||||
|
||||
// Export the locales and languages
|
||||
export { locales, languages };
|
||||
export { languages, locales };
|
||||
|
||||
export function getLangFromUrl(url: URL): string {
|
||||
const [, lang] = url.pathname.split('/');
|
||||
const [, lang] = url.pathname.split("/");
|
||||
if (locales.hasOwnProperty(lang)) {
|
||||
return lang;
|
||||
}
|
||||
return 'en';
|
||||
return defaultLang;
|
||||
}
|
||||
|
||||
export const getTranslations = async (lang: string) => {
|
||||
const menu = await import(`../../config/menu.${lang || defaultLang}.json`);
|
||||
const dictionary = await import(`../../i18n/${lang || defaultLang}.json`);
|
||||
return { ...menu, ...dictionary };
|
||||
};
|
||||
|
||||
|
||||
// import { ui } from '@/i18n/ui';
|
||||
// import config from "@/config/config.json";
|
||||
// const {defaultLang}: {defaultLang : keyof typeof ui} = config.language as any;
|
||||
|
||||
// export function useTranslations(lang: keyof typeof ui) {
|
||||
// return function t(key: keyof typeof ui[typeof defaultLang]) {
|
||||
// return ui[lang][key] || ui[defaultLang][key];
|
||||
// }
|
||||
// }
|
||||
|
||||
import { ui } from '@/i18n/ui';
|
||||
import config from "@/config/config.json";
|
||||
|
||||
const { defaultLang }: { defaultLang: keyof typeof ui } = config.language as any;
|
||||
|
||||
export function useTranslations(lang?: keyof typeof ui) {
|
||||
const activeLang = lang || defaultLang;
|
||||
|
||||
return function t(key: keyof typeof ui[typeof defaultLang]): string {
|
||||
const translation = ui[activeLang][key];
|
||||
|
||||
// If not found, fall back to the default language
|
||||
if (translation) {
|
||||
return translation;
|
||||
} else {
|
||||
return ui[defaultLang][key];
|
||||
}
|
||||
};
|
||||
}
|
||||
export const supportedLang = [""].concat(
|
||||
languagesJSON.map((lang) => lang.languageCode),
|
||||
);
|
||||
|
||||
+13
-9
@@ -1,17 +1,21 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import config from "@/config/config.json";
|
||||
import { getLangFromUrl, useTranslations } from "@/lib/utils/i18nUtils";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getLangFromUrl, getTranslations } from "@/lib/utils/i18nUtils";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const t = useTranslations(lang as any);
|
||||
const {defaultLang} = config.language;
|
||||
const { page_not_found_content, page_not_found, back_to_home } =
|
||||
await getTranslations(lang as keyof ContentEntryMap);
|
||||
const { defaultLang } = config.language;
|
||||
const href = lang && lang !== defaultLang ? `/${lang}/` : "/";
|
||||
---
|
||||
|
||||
@@ -25,11 +29,11 @@ const href = lang && lang !== defaultLang ? `/${lang}/` : "/";
|
||||
>
|
||||
404
|
||||
</span>
|
||||
<h1 class="h2 mb-4">{t("page_not_found")}</h1>
|
||||
<h1 class="h2 mb-4">{page_not_found}</h1>
|
||||
<div class="content">
|
||||
<p>{t("page_not_found_content")}</p>
|
||||
<p>{page_not_found_content}</p>
|
||||
</div>
|
||||
<a href={href} class="btn btn-primary mt-8">{t("back_to_home")}</a>
|
||||
<a href={href} class="btn btn-primary mt-8">{back_to_home}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
supportedLang.map(async (lang) => {
|
||||
const pages = await getSinglePage("pages", lang as keyof ContentEntryMap);
|
||||
|
||||
return pages.map((page) => ({
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
---
|
||||
import ImageMod from "@/components/ImageMod.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
import config from "@/config/config.json";
|
||||
import { getListPage } from "@/lib/contentParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const about = await getListPage("about", lang as keyof ContentEntryMap);
|
||||
const about = await getListPage("about", lang);
|
||||
|
||||
const { Content } = await about[0].render();
|
||||
const { title, description, meta_title, image } = about[0].data;
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
import BlogCard from "@/components/BlogCard.astro";
|
||||
import ImageMod from "@/components/ImageMod.astro";
|
||||
import Social from "@/components/Social.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
// get all static paths for authors
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const authors = await getSinglePage(COLLECTION_FOLDER, lang as keyof ContentEntryMap);
|
||||
supportedLang.map(async (lang) => {
|
||||
const authors = await getSinglePage(
|
||||
COLLECTION_FOLDER,
|
||||
lang as keyof ContentEntryMap
|
||||
);
|
||||
|
||||
return authors.map((author) => ({
|
||||
params: {
|
||||
@@ -25,7 +26,7 @@ export async function getStaticPaths() {
|
||||
},
|
||||
props: {
|
||||
author,
|
||||
lang
|
||||
lang,
|
||||
},
|
||||
}));
|
||||
})
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
---
|
||||
import AuthorCard from "@/components/AuthorCard.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { type ContentEntryMap } from "astro:content";
|
||||
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import PostSingle from "@/layouts/PostSingle.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const posts = await getSinglePage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
supportedLang.map(async (lang) => {
|
||||
const posts = await getSinglePage(
|
||||
BLOG_FOLDER,
|
||||
lang as keyof ContentEntryMap
|
||||
);
|
||||
|
||||
return posts.map((post) => ({
|
||||
params: {
|
||||
@@ -31,6 +32,7 @@ export async function getStaticPaths() {
|
||||
const { post } = Astro.props;
|
||||
const { title, meta_title, description, image } = post.data;
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
|
||||
@@ -5,14 +5,14 @@ import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import PostSidebar from "@/partials/PostSidebar.astro";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
|
||||
@@ -4,26 +4,29 @@ import Pagination from "@/components/Pagination.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import PostSidebar from "@/partials/PostSidebar.astro";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const { slug, lang } = Astro.params;
|
||||
|
||||
const postIndex = await getCollection(
|
||||
lang as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return id.startsWith(BLOG_FOLDER);
|
||||
}
|
||||
);
|
||||
|
||||
const posts = await getCollection(lang as keyof ContentEntryMap, ({ id }) => {
|
||||
return id.startsWith(BLOG_FOLDER) && !id.endsWith("-index.md");
|
||||
});
|
||||
const posts = await getCollection(
|
||||
lang as keyof ContentEntryMap,
|
||||
({ id }: any) => {
|
||||
return id.startsWith(BLOG_FOLDER) && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
const allCategories = await getAllTaxonomy(langCollection, "categories");
|
||||
@@ -37,14 +40,13 @@ const indexOfFirstPost = indexOfLastPost - config.settings.pagination;
|
||||
const currentPosts = sortedPosts.slice(indexOfFirstPost, indexOfLastPost);
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
supportedLang.map(async (lang) => {
|
||||
const posts = await getCollection(
|
||||
lang as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return id.startsWith(BLOG_FOLDER) && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
---
|
||||
import BlogCard from "@/components/BlogCard.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
// get all static paths for categories
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
supportedLang.map(async (lang) => {
|
||||
const categories = await getTaxonomy(lang, "categories");
|
||||
|
||||
return categories.map((category) => ({
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import config from "@/config/config.json";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported } = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage } from "@/lib/contentParser.astro";
|
||||
import { useTranslations } from "@/lib/utils/i18nUtils";
|
||||
import { getTranslations, supportedLang } from "@/lib/utils/i18nUtils";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { type ContentEntryMap } from "astro:content";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
@@ -18,7 +19,13 @@ 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;
|
||||
|
||||
const t = useTranslations(lang as any);
|
||||
const {
|
||||
working_mail,
|
||||
full_name,
|
||||
anything_else,
|
||||
contact_message_placeholder,
|
||||
submit,
|
||||
} = await getTranslations(lang as keyof ContentEntryMap);
|
||||
---
|
||||
|
||||
<Base
|
||||
@@ -35,7 +42,7 @@ const t = useTranslations(lang as any);
|
||||
<form action={contact_form_action} method="POST">
|
||||
<div class="mb-6">
|
||||
<label for="name" class="form-label">
|
||||
{t("full_name")}
|
||||
{full_name}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -48,7 +55,8 @@ const t = useTranslations(lang as any);
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="email" class="form-label">
|
||||
{t("working_mail")} <span class="text-red-500">*</span>
|
||||
{working_mail}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
@@ -60,16 +68,17 @@ const t = useTranslations(lang as any);
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="message" class="form-label">
|
||||
{t("anything_else")} <span class="text-red-500">*</span>
|
||||
{anything_else}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<textarea
|
||||
id="message"
|
||||
name="message"
|
||||
class="form-input"
|
||||
placeholder={t("contact_message_placeholder")}
|
||||
placeholder={contact_message_placeholder}
|
||||
rows="8"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">{t("submit")}</button>
|
||||
<button type="submit" class="btn btn-primary">{submit}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
import { FaCheck } from "react-icons/fa";
|
||||
const { defaultLang } = config.language;
|
||||
import { supportedLang } from "@/lib/utils/i18nUtils";
|
||||
|
||||
interface Homepage {
|
||||
banner: {
|
||||
@@ -23,29 +24,25 @@ interface Homepage {
|
||||
}
|
||||
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
const paths = supportedLang.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const homepage = await getListPage("homepage", lang as keyof ContentEntryMap);
|
||||
|
||||
// const testimonial = await getEntry("sections", "testimonial");
|
||||
// const call_to_action = await getEntry("sections", "call-to-action");
|
||||
const homepage = await getListPage("homepage", lang);
|
||||
const { banner, features }: Homepage = homepage[0].data;
|
||||
|
||||
const testimonial = await getCollection(
|
||||
(lang as keyof ContentEntryMap) || defaultLang,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return id.startsWith("sections/testimonial") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
const call_to_action = await getCollection(
|
||||
(lang as keyof ContentEntryMap) || defaultLang,
|
||||
({ id }) => {
|
||||
({ id }: any) => {
|
||||
return (
|
||||
id.startsWith("sections/call-to-action") && !id.endsWith("-index.md")
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user