config i18n
This commit is contained in:
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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 }} />
|
||||
|
@@ -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>
|
||||
|
28
src/pages/es/[...slug].astro
Normal file
28
src/pages/es/[...slug].astro
Normal 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
129
src/pages/es/feed.xml.ts
Normal 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,
|
||||
});
|
||||
}
|
@@ -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>
|
||||
|
@@ -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 }} />
|
||||
|
@@ -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>
|
||||
|
@@ -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,
|
@@ -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."
|
||||
>
|
||||
|
@@ -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."
|
||||
>
|
||||
|
@@ -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 }} />
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user