--- import { getCollection } from 'astro:content'; import MainGridLayout from "../../layouts/MainGridLayout.astro"; import ButtonTag from "../../components/control/ButtonTag.astro"; import ImageBox from "../../components/misc/ImageBox.astro"; import {Icon} from "astro-icon/components"; import {formatDateToYYYYMMDD} from "../../utils/date-utils"; import PostMetadata from "../../components/PostMetadata.astro"; import {getPostUrlBySlug} from "../../utils/content-utils"; import Button from "../../components/control/Button.astro"; import {getConfig} from "../../utils/config-utils"; import {i18n} from "../../i18n/translation"; import I18nKey from "../../i18n/i18nKey"; export async function getStaticPaths() { const blogEntries = await getCollection('posts'); return blogEntries.map(entry => ({ params: { slug: entry.slug }, props: { entry }, })); } const { entry } = Astro.props; const { Content } = await entry.render(); const { remarkPluginFrontmatter } = await entry.render(); const enableBanner = getConfig().banner.enable; --- <MainGridLayout banner={entry.data.cover} title={entry.data.title}> <div class="flex w-full rounded-[var(--radius-large)] overflow-hidden relative mb-4"> <div class:list={["card-base z-10 px-9 py-6 relative w-full ", {} ]}> <!-- word count and reading time --> <div class="flex flex-row text-black/30 dark:text-white/30 gap-5 mb-3 transition"> <div class="flex flex-row items-center"> <div class="transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2"> <Icon name="material-symbols:notes-rounded"></Icon> </div> <div class="text-sm">{remarkPluginFrontmatter.words} {" " + i18n(I18nKey.wordsCount)}</div> </div> <div class="flex flex-row items-center"> <div class="transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2"> <Icon name="material-symbols:schedule-outline-rounded"></Icon> </div> <div class="text-sm">{remarkPluginFrontmatter.minutes} {" " + i18n(I18nKey.minutesCount)}</div> </div> </div> <!-- title --> <div class="relative"> <div class="transition w-full block font-bold mb-3 text-[40px]/[44px] text-black/90 dark:text-white/90 before:w-1 before:h-5 before:rounded-md before:bg-[var(--primary)] before:absolute before:top-[12px] before:left-[-18px] "> {entry.data.title} </div> </div> <!-- metadata --> <PostMetadata class="mb-5" pubDate={entry.data.pubDate} tags={entry.data.tags} categories={entry.data.categories} ></PostMetadata> <!-- always show cover as long as it has one --> {entry.data.cover && <ImageBox src={entry.data.cover} class="mb-8 rounded-xl"/> } {!entry.data.cover && <div class="border-[var(--line-divider)] border-dashed border-b-[1px] mb-5"></div>} <div class="prose dark:prose-invert max-w-none prose-h1:text-3xl"> <Content /> </div> </div> </div> <div class="flex justify-between gap-4 overflow-hidden w-full"> <a href={getPostUrlBySlug(entry.data.prevSlug)} class="w-full font-bold overflow-hidden"> {entry.data.prevSlug && <Button class="w-full max-w-full h-10 px-4 rounded-2xl flex items-center justify-start gap-4" card height="60px"> <Icon name="material-symbols:chevron-left-rounded" size={32} class="text-[var(--primary)]" /> <div class="overflow-hidden overflow-ellipsis whitespace-nowrap max-w-[calc(100%_-_48px)] text-black/75 dark:text-white/75"> {entry.data.prevTitle} </div> </Button>} </a> <a href={getPostUrlBySlug(entry.data.nextSlug)} class="w-full font-bold overflow-hidden"> {entry.data.nextSlug && <Button class="w-full max-w-full h-10 px-4 rounded-2xl flex items-center justify-end gap-4" card height="60px"> <div class="overflow-hidden overflow-ellipsis whitespace-nowrap max-w-[calc(100%_-_48px)] text-black/75 dark:text-white/75"> {entry.data.nextTitle} </div> <Icon name="material-symbols:chevron-right-rounded" size={32} class="text-[var(--primary)]" /> </Button>} </a> </div> </MainGridLayout>