config i18n

This commit is contained in:
juancmandev
2024-07-31 13:41:41 -06:00
parent 16f07bf63b
commit 373a4af4b1
24 changed files with 400 additions and 96 deletions

View File

@@ -1,14 +1,9 @@
---
import Layout from "@/layouts/Layout.astro";
import LinkButton from "@/components/link-button";
---
<Layout lang="en" title="juancmandev" description="Error 404. Not found.">
<Layout title="Not found" description="Error 404: Not found.">
<div class="prose prose-invert">
<h1 class="">Error 404: Not found</h1>
<p>Do not worry, you can <strong>go back to home</strong>.</p>
<LinkButton variant="default" href="/" className="no-underline"
>Home</LinkButton
>
</div>
</Layout>

View File

@@ -21,7 +21,7 @@ const { page } = Astro.props;
const { Content } = await page.render();
---
<Layout lang="en" title={page.data.title} description={page.data.description}>
<Layout {...page.data}>
<article class="prose prose-invert">
<Content components={{ ...components }} />
</article>

View File

@@ -25,7 +25,7 @@ const { post } = Astro.props;
const { Content } = await post.render();
---
<Layout lang="en" title={post.data.title} description={post.data.description}>
<Layout title={post.data.title} description={post.data.description}>
<article class="prose prose-invert">
<h1>{post.data.title}</h1>
<Content components={{ ...components }} />

View File

@@ -13,7 +13,7 @@ const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
sortContentByDate(allPosts);
---
<Layout {...pageData} lang="en">
<Layout {...pageData}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>

View File

@@ -0,0 +1,28 @@
---
import Layout from "@/layouts/Layout.astro";
import { getCollection } from "astro:content";
import type { CollectionEntry } from "astro:content";
import components from "@/components/mdx/wrapper";
interface Props {
page: CollectionEntry<"pages">;
}
export async function getStaticPaths() {
const allPages = await getCollection("pages");
return allPages.map((page: CollectionEntry<"pages">) => ({
params: { slug: page.slug },
props: { page },
}));
}
const { page } = Astro.props;
const { Content } = await page.render();
---
<Layout {...page.data}>
<article class="prose prose-invert">
<Content components={{ ...components }} />
</article>
</Layout>

129
src/pages/es/feed.xml.ts Normal file
View File

@@ -0,0 +1,129 @@
import rss from "@astrojs/rss";
import type { RSSFeedItem } from "@astrojs/rss";
import { getCollection } from "astro:content";
import sanitizeHtml from "sanitize-html";
import MarkdownIt from "markdown-it";
import { parse as htmlParser } from "node-html-parser";
import { getImage } from "astro:assets";
import type { ImageMetadata } from "astro";
const markdownParser = new MarkdownIt();
const imagesBlog = import.meta.glob<{ default: ImageMetadata }>(
"/src/assets/blog/**/**/*.{jpeg,jpg,png,gif,webp}",
);
const imagesPortfolio = import.meta.glob<{ default: ImageMetadata }>(
"/src/assets/portfolio/**/**/*.{jpeg,jpg,png,gif,webp}",
);
export async function GET(context: any) {
const items: RSSFeedItem[] = [];
const blog = await getCollection(
"blog",
({ data }) => data.draft !== true && data.rss === true,
);
const portfolio = await getCollection(
"portfolio",
({ data }) => data.draft !== true && data.rss === true,
);
for await (const post of blog) {
const body = markdownParser.render(post.body);
const html = htmlParser.parse(body);
const images = html.querySelectorAll("img");
for await (const img of images) {
const src = img.getAttribute("src")!;
if (src.startsWith("@/")) {
const prefixRemoved = src.replace("@/", "");
const imagePathPrefix = `/src/${prefixRemoved}`;
const imagePath = await imagesBlog[imagePathPrefix]?.()?.then(
(res: any) => res.default,
);
if (imagePath) {
const optimizedImg = await getImage({ src: imagePath });
img.setAttribute(
"src",
context.site + optimizedImg.src.replace("/", ""),
);
}
} else if (src.startsWith("/images")) {
img.setAttribute("src", context.site + src.replace("/", ""));
} else {
throw Error("src unknown");
}
}
items.push({
title: post.data.title,
pubDate: post.data.date,
description: post.data.description,
link: `/blog/${post.slug}/`,
content: sanitizeHtml(html.toString(), {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
}),
});
}
for await (const project of portfolio) {
const body = markdownParser.render(project.body);
const html = htmlParser.parse(body);
const images = html.querySelectorAll("img");
for await (const img of images) {
const src = img.getAttribute("src")!;
if (src.startsWith("@/")) {
const prefixRemoved = src.replace("@/", "");
const imagePathPrefix = `/src/${prefixRemoved}`;
const imagePath = await imagesPortfolio[imagePathPrefix]?.()?.then(
(res: any) => res.default,
);
if (imagePath) {
const optimizedImg = await getImage({ src: imagePath });
img.setAttribute(
"src",
context.site + optimizedImg.src.replace("/", ""),
);
}
} else if (src.startsWith("/images")) {
// images starting with `/images/` is the public dir
img.setAttribute("src", context.site + src.replace("/", ""));
} else {
throw Error("src unknown");
}
}
items.push({
title: project.data.title,
pubDate: project.data.date,
description: project.data.description,
link: `/portfolio/${project.slug}/`,
content: sanitizeHtml(html.toString(), {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
}),
});
}
return rss({
xmlns: { atom: "http://www.w3.org/2005/Atom" },
title: "juancmandev",
description: "Bienvenido a mi dominio, extraño.",
site: `${context.site}es/`,
customData: [
"<language>es-mx</language>",
`<image>
<url>https://juancman.dev/logo.png</url>
<title>juancmandev</title>
<link>https://juancman.dev</link>
</image>`,
`<atom:link href="${context.site}es/feed.xml" rel="self" type="application/rss+xml"/>`,
].join(""),
items,
trailingSlash: false,
});
}

View File

@@ -3,7 +3,6 @@ import Layout from "@/layouts/Layout.astro";
---
<Layout
lang="es"
title="juancmandev"
description="Bienvenido a mi dominio, extraño. Soy juancmandev; Desarrollador Web, entusiasta de Linux, y defensor de la privacidad."
>
@@ -16,5 +15,10 @@ import Layout from "@/layouts/Layout.astro";
>privacidad.</strong
>
</p>
<p>
Este es mi <strong>website</strong>, un pedazo de Internet al que puedo
llamar <strong>hogar</strong>. Aquí comparto mi pasión por proyectos open
source y otros temas.
</p>
</div>
</Layout>

View File

@@ -25,11 +25,7 @@ const { project } = Astro.props;
const { Content } = await project.render();
---
<Layout
lang="es"
title={project.data.title}
description={project.data.description}
>
<Layout title={project.data.title} description={project.data.description}>
<article class="prose prose-invert">
<h1>{project.data.title}</h1>
<Content components={{ ...components }} />

View File

@@ -16,7 +16,7 @@ const allVideos = await getCollection(
sortContentByDate(allVideos);
---
<Layout {...pageData} lang="es">
<Layout {...pageData}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>

View File

@@ -121,7 +121,7 @@ export async function GET(context: any) {
<title>juancmandev</title>
<link>https://juancman.dev</link>
</image>`,
`<atom:link href="${context.site}rss.xml" rel="self" type="application/rss+xml"/>`,
`<atom:link href="${context.site}feed.xml" rel="self" type="application/rss+xml"/>`,
].join(""),
items,
trailingSlash: false,

View File

@@ -18,7 +18,6 @@ const last3Projects = allProjects.slice(0, 3);
---
<Layout
lang="en"
title="juancmandev"
description="Welcome to my domain, stranger. I am juancmandev; Web Developer, Linux enthusiast, and privacy defender."
>

View File

@@ -11,7 +11,6 @@ const data = await pb.collection("microblogs").getFullList({
---
<Layout
lang="en"
title="Microblog"
description="Short-format writing. Instead of using shitty social media."
>

View File

@@ -25,11 +25,7 @@ const { project } = Astro.props;
const { Content } = await project.render();
---
<Layout
lang="en"
title={project.data.title}
description={project.data.description}
>
<Layout title={project.data.title} description={project.data.description}>
<article class="prose prose-invert">
<h1>{project.data.title}</h1>
<Content components={{ ...components }} />

View File

@@ -16,7 +16,7 @@ const allProjects = await getCollection(
sortContentByDate(allProjects);
---
<Layout {...pageData} lang="en">
<Layout {...pageData}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>