142 lines
4.0 KiB
Plaintext
142 lines
4.0 KiB
Plaintext
---
|
|
import { YouTube } from "astro-embed";
|
|
import MainLayout from "../../../layouts/MainLayout.astro";
|
|
import Header from "../../../components/Header.astro";
|
|
import CarouselSection from "../../../components/section/CarouselSection.astro";
|
|
import { Image } from "@unpic/astro";
|
|
import { getCollection, render } from "astro:content";
|
|
import TitleSection from "../../../components/section/TitleSection.astro";
|
|
import FooterSection from "../../../components/section/FooterSection.astro";
|
|
import { getLocalizedRoute } from "@/i18n";
|
|
export const prerender = true;
|
|
// 1. Generate a new path for every collection entry
|
|
export async function getStaticPaths() {
|
|
const posts = await getCollection("news");
|
|
return posts.map((post) => ({
|
|
params: {
|
|
id: post.id,
|
|
locale: post.data.locale,
|
|
news_slug: getLocalizedRoute("news", post.data.locale),
|
|
},
|
|
props: { post },
|
|
}));
|
|
}
|
|
|
|
const { locale, news_slug } = Astro.params;
|
|
|
|
// 2. For your template, you can get the entry directly from the prop
|
|
const { post } = Astro.props;
|
|
const { Content } = await render(post);
|
|
|
|
const baseSlug = news_slug;
|
|
|
|
const rawContent = post.body || "";
|
|
const plainText = rawContent
|
|
.replace(/^#.*$/gm, "")
|
|
.replace(/^###.*$/gm, "")
|
|
.replace(/\*\*([^*]+)\*\*/g, "$1")
|
|
.replace(/\*([^*]+)\*/g, "$1")
|
|
.replace(/_([^_]+)_/g, "$1")
|
|
.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
|
|
.replace(/^>.*$/gm, "")
|
|
.replace(/`[^`]+`/g, "")
|
|
.replace(/^[-*]\s+/gm, "")
|
|
.trim();
|
|
const words = plainText
|
|
.split(/\s+/)
|
|
.filter((w) => w.length > 0)
|
|
.slice(0, 35);
|
|
const excerpt = words.join(" ") + (words.length === 35 ? "..." : "");
|
|
|
|
const canonicalUrl = new URL(`/${locale}/${news_slug}/${post.id}`, Astro.site);
|
|
const imageUrl = post.data.thumbnail
|
|
? new URL(post.data.thumbnail, Astro.site).toString()
|
|
: null;
|
|
const localeDate = new Intl.DateTimeFormat(locale || "es", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
}).format(post.data.date);
|
|
const y = post.data.date.getFullYear();
|
|
const m = String(post.data.date.getMonth() + 1).padStart(2, "0");
|
|
const d = String(post.data.date.getDate()).padStart(2, "0");
|
|
const dateISO = `${y}-${m}-${d}`;
|
|
---
|
|
|
|
<MainLayout
|
|
title={post.data.title}
|
|
description={excerpt}
|
|
image={post.data.thumbnail}
|
|
url={canonicalUrl.toString()}
|
|
date={post.data.date}
|
|
>
|
|
<script
|
|
type="application/ld+json"
|
|
set:html={JSON.stringify({
|
|
"@context": "https://schema.org",
|
|
"@type": "NewsArticle",
|
|
headline: post.data.title,
|
|
datePublished: post.data.date,
|
|
description: excerpt,
|
|
image: imageUrl,
|
|
url: canonicalUrl.toString(),
|
|
author: {
|
|
"@type": "Organization",
|
|
name: "Centro del Reino de Paz y Justicia",
|
|
},
|
|
})}
|
|
></script>
|
|
<div class="container mx-auto md:py-16 py-8">
|
|
<Header />
|
|
</div>
|
|
|
|
<a class="block">
|
|
<TitleSection title={post.data.title} />
|
|
</a>
|
|
|
|
<div class="container mx-auto">
|
|
<a class="block">
|
|
{
|
|
post.data.gallery?.length ? (
|
|
<CarouselSection images={post.data.gallery} />
|
|
) : post.data.thumbnail ? (
|
|
<Image
|
|
src={post.data.thumbnail}
|
|
alt={post.data.title}
|
|
class="hover:opacity-90 transition-opacity"
|
|
/>
|
|
) : null
|
|
}
|
|
</a>
|
|
</div>
|
|
<div class="grid md:grid-cols-10 container mx-auto">
|
|
<div
|
|
id="article-content"
|
|
class="md:col-span-7 content bg-white p-8 md:p-20 prose-p:mb-4 text-[#003421] text-justify"
|
|
>
|
|
<article id="article-body">
|
|
<time
|
|
id="article-date"
|
|
class="block text-center text-[#003421]/60 text-sm mb-8 hidden"
|
|
datetime={dateISO}
|
|
>
|
|
{localeDate}
|
|
</time>
|
|
<Content />
|
|
</article>
|
|
</div>
|
|
<div class="md:col-span-3 bg-tertiary md:sticky top-0 h-fit">
|
|
{post.data.youtube && <YouTube id={post.data.youtube} />}
|
|
|
|
{
|
|
post.data.gallery &&
|
|
post.data.gallery.map((galleryImage) => (
|
|
<Image src={galleryImage.image} alt={galleryImage.text} />
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|
|
</MainLayout>
|
|
|
|
<FooterSection />
|