reestructure content lang

This commit is contained in:
Juan Carlos Manzanero Domínguez 2024-10-07 16:42:47 -06:00
parent 57cb8933e2
commit ad33d51489
26 changed files with 579 additions and 163 deletions

@ -6,6 +6,7 @@ type Props = {
date: Date | string; date: Date | string;
title: string; title: string;
type: "blog" | "portfolio" | "es/videos"; type: "blog" | "portfolio" | "es/videos";
lang: string;
}; };
export default function PostItem(props: Props) { export default function PostItem(props: Props) {
@ -16,9 +17,16 @@ export default function PostItem(props: Props) {
variant="link" variant="link"
className="px-4 whitespace-normal py-2 hover:no-underline focus:no-underline flex flex-col items-start italic border border-secondary hover:border-foreground focus:border-foreground transition-colors rounded-md" className="px-4 whitespace-normal py-2 hover:no-underline focus:no-underline flex flex-col items-start italic border border-secondary hover:border-foreground focus:border-foreground transition-colors rounded-md"
> >
<a className="no-underline" href={`/${props.type}/${props.slug}`}> <a
className="no-underline"
href={
props.lang === "en"
? `/${props.type}/${props.slug}`
: `/es/${props.type}/${[props.slug]}`
}
>
<span className="text-sm font-light no-underline"> <span className="text-sm font-light no-underline">
{formatDate(props.date)} {formatDate(props.date, props.lang)}
</span> </span>
<span className="text-primary text-underline text-lg font-semibold underline"> <span className="text-primary text-underline text-lg font-semibold underline">
{props.title} {props.title}

@ -1,5 +1,5 @@
--- ---
title: A Better Way for Consuming Content title: Una Mejor Forma de Consumir Contenido
description: description:
Get your news without visiting websites with algorithms that shows content Get your news without visiting websites with algorithms that shows content
that you don't want to see. that you don't want to see.

@ -4,6 +4,7 @@ import { getCollection } from "astro:content";
import components from "@/components/mdx/wrapper"; import components from "@/components/mdx/wrapper";
import formatDate from "@/utils/format-date"; import formatDate from "@/utils/format-date";
import type { CollectionEntry } from "astro:content"; import type { CollectionEntry } from "astro:content";
import { getLangFromUrl } from "@/i18n/utils";
interface Props { interface Props {
post: CollectionEntry<"blog">; post: CollectionEntry<"blog">;
@ -12,17 +13,29 @@ interface Props {
export async function getStaticPaths() { export async function getStaticPaths() {
const allBlogPosts = await getCollection( const allBlogPosts = await getCollection(
"blog", "blog",
({ data }) => data.draft !== true ({ data }) => data.draft !== true,
); );
const filterEnPosts = allBlogPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
return allBlogPosts.map((post) => ({ if (lang === "en")
params: { slug: post.slug }, return {
...post,
slug: slug.toString(),
};
else null;
});
return filterEnPosts.map((post) => ({
params: { slug: post?.slug },
props: { post }, props: { post },
})); }));
} }
const { post } = Astro.props; const { post } = Astro.props;
const { Content } = await post.render(); const { Content } = await post.render();
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout title={post.data.title} description={post.data.description}> <Layout title={post.data.title} description={post.data.description}>
@ -32,7 +45,7 @@ const { Content } = await post.render();
<hr /> <hr />
<p> <p>
<strong>Posted: </strong> <strong>Posted: </strong>
{post.data.date && formatDate(new Date(post.data.date))} {post.data.date && formatDate(new Date(post.data.date), lang)}
</p> </p>
</article> </article>
</Layout> </Layout>

@ -1,5 +1,6 @@
--- ---
import PostItem from "@/components/post-item"; import PostItem from "@/components/post-item";
import { getLangFromUrl } from "@/i18n/utils";
import Layout from "@/layouts/Layout.astro"; import Layout from "@/layouts/Layout.astro";
import { sortContentByDate } from "@/utils/sorts"; import { sortContentByDate } from "@/utils/sorts";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
@ -10,7 +11,19 @@ const pageData = {
}; };
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true); const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
sortContentByDate(allPosts); const filterEnPosts = allPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
if (lang === "en")
return {
...post,
slug: slug.toString(),
};
else null;
});
sortContentByDate(filterEnPosts);
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout {...pageData}> <Layout {...pageData}>
@ -20,16 +33,20 @@ sortContentByDate(allPosts);
</section> </section>
<ul class="mt-4 flex flex-col gap-4"> <ul class="mt-4 flex flex-col gap-4">
{ {
allPosts.map((blogpost: any) => ( filterEnPosts.map(
(blogpost) =>
blogpost && (
<li> <li>
<PostItem <PostItem
type="blog" type="blog"
lang={lang}
slug={blogpost.slug} slug={blogpost.slug}
date={blogpost.data.date!} date={blogpost.data.date!}
title={blogpost.data.title!} title={blogpost.data.title!}
/> />
</li> </li>
)) ),
)
} }
</ul> </ul>
</Layout> </Layout>

@ -0,0 +1,51 @@
---
import Layout from "@/layouts/Layout.astro";
import { getCollection } from "astro:content";
import components from "@/components/mdx/wrapper";
import formatDate from "@/utils/format-date";
import type { CollectionEntry } from "astro:content";
import { getLangFromUrl } from "@/i18n/utils";
interface Props {
post: CollectionEntry<"blog">;
}
export async function getStaticPaths() {
const allBlogPosts = await getCollection(
"blog",
({ data }) => data.draft !== true,
);
const filterEsPosts = allBlogPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
if (lang === "es")
return {
...post,
slug: slug.toString(),
};
else null;
});
return filterEsPosts.map((post) => ({
params: { slug: post?.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
const lang = getLangFromUrl(Astro.url);
---
<Layout title={post.data.title} description={post.data.description}>
<article class="prose prose-invert">
<h1>{post.data.title}</h1>
<Content components={{ ...components }} />
<hr />
<p>
<strong>Publicado: </strong>
{post.data.date && formatDate(new Date(post.data.date), lang)}
</p>
</article>
</Layout>

@ -0,0 +1,52 @@
---
import PostItem from "@/components/post-item";
import { getLangFromUrl } from "@/i18n/utils";
import Layout from "@/layouts/Layout.astro";
import { sortContentByDate } from "@/utils/sorts";
import { getCollection } from "astro:content";
const pageData = {
title: "Blog",
description: "Formato largo sobre pensamientos y otros temas.",
};
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
const filterEsPosts = allPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
if (lang === "es")
return {
...post,
slug: slug.toString(),
};
else null;
});
sortContentByDate(filterEsPosts);
const lang = getLangFromUrl(Astro.url);
---
<Layout {...pageData}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
filterEsPosts.map(
(post) =>
post && (
<li>
<PostItem
type="blog"
lang={lang}
slug={post?.slug}
date={post?.data.date!}
title={post?.data.title!}
/>
</li>
),
)
}
</ul>
</Layout>

@ -1,5 +1,43 @@
--- ---
import LinkButton from "@/components/link-button";
import PostItem from "@/components/post-item";
import { getLangFromUrl } from "@/i18n/utils";
import Layout from "@/layouts/Layout.astro"; import Layout from "@/layouts/Layout.astro";
import { sortContentByDate } from "@/utils/sorts";
import { getCollection } from "astro:content";
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
const allEsPosts = allPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
if (lang === "es")
return {
...post,
slug: slug.toString(),
};
else null;
});
sortContentByDate(allEsPosts);
const last3Blogs = allEsPosts.slice(0, 3);
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true,
);
const allEnProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
if (lang === "es")
return {
...project,
slug: slug.toString(),
};
else null;
});
sortContentByDate(allEnProjects);
const last3Projects = allEnProjects.slice(0, 3);
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout <Layout
@ -16,9 +54,61 @@ import Layout from "@/layouts/Layout.astro";
> >
</p> </p>
<p> <p>
Este es mi <strong>website</strong>, un pedazo de Internet al que puedo Este es mi <strong>website</strong>, un pedazo de Internet al que
llamar <strong>hogar</strong>. Aquí comparto mi pasión por proyectos open puedo llamar <strong>hogar</strong>. Aquí comparto mi pasión por
source y otros temas. proyectos open source y otros temas.
</p> </p>
<section>
<h2>Últimos posts</h2>
<ul class="mt-0 p-0 list-none">
{
last3Blogs.map(
(blogpost) =>
blogpost && (
<li class="p-0">
<PostItem
type="blog"
lang={lang}
slug={blogpost?.slug}
date={blogpost.data.date}
title={blogpost.data.title}
/>
</li>
),
)
}
</ul>
<LinkButton
variant="secondary"
href="/blog"
className="no-underline">Más posts</LinkButton
>
</section>
<section>
<h2>Últimos proyectos</h2>
<ul class="mt-0 p-0 list-none">
{
last3Projects.map(
(project) =>
project && (
<li class="p-0">
<PostItem
lang={lang}
type="portfolio"
slug={project.slug}
date={project.data.date!}
title={project.data.title!}
/>
</li>
),
)
}
</ul>
<LinkButton
variant="secondary"
href="/portfolio"
className="no-underline">More projects</LinkButton
>
</section>
</div> </div>
</Layout> </Layout>

@ -0,0 +1,51 @@
---
import Layout from "@/layouts/Layout.astro";
import { getCollection } from "astro:content";
import components from "@/components/mdx/wrapper";
import formatDate from "@/utils/format-date";
import type { CollectionEntry } from "astro:content";
import { getLangFromUrl } from "@/i18n/utils";
interface Props {
project: CollectionEntry<"portfolio">;
}
export async function getStaticPaths() {
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true,
);
const filterEnProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
if (lang === "es")
return {
...project,
slug: slug.toString(),
};
else null;
});
return filterEnProjects.map((project) => ({
params: { slug: project?.slug },
props: { project },
}));
}
const { project } = Astro.props;
const { Content } = await project.render();
const lang = getLangFromUrl(Astro.url);
---
<Layout title={project.data.title} description={project.data.description}>
<article class="prose prose-invert">
<h1>{project.data.title}</h1>
<Content components={{ ...components }} />
<hr />
<p>
<strong>Publicado: </strong>
{project.data.date && formatDate(new Date(project.data.date), lang)}
</p>
</article>
</Layout>

@ -0,0 +1,55 @@
---
import PostItem from "@/components/post-item";
import { getLangFromUrl } from "@/i18n/utils";
import Layout from "@/layouts/Layout.astro";
import { sortContentByDate } from "@/utils/sorts";
import { getCollection } from "astro:content";
const pageData = {
title: "Portfolio",
description: "Revisa mis proyectos.",
};
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true,
);
const allEsProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
if (lang === "es")
return {
...project,
slug: slug.toString(),
};
else null;
});
sortContentByDate(allEsProjects);
const lang = getLangFromUrl(Astro.url);
---
<Layout {...pageData}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
allEsProjects.map(
(project) =>
project && (
<li>
<PostItem
lang={lang}
type="portfolio"
slug={project.slug}
date={project.data.date!}
title={project.data.title!}
/>
</li>
),
)
}
</ul>
</Layout>

@ -4,17 +4,40 @@ import LinkButton from "@/components/link-button";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import PostItem from "@/components/post-item"; import PostItem from "@/components/post-item";
import { sortContentByDate } from "@/utils/sorts"; import { sortContentByDate } from "@/utils/sorts";
import { getLangFromUrl } from "@/i18n/utils";
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true); const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
sortContentByDate(allPosts); const allEnPosts = allPosts.map((post) => {
const last3Blogs = allPosts.slice(0, 3); const [lang, ...slug] = post.slug.split("/");
if (lang !== "es")
return {
...post,
slug: slug.toString(),
};
else null;
});
sortContentByDate(allEnPosts);
const last3Blogs = allEnPosts.slice(0, 3);
const allProjects = await getCollection( const allProjects = await getCollection(
"portfolio", "portfolio",
({ data }) => data.draft !== true ({ data }) => data.draft !== true,
); );
sortContentByDate(allProjects); const allEnProjects = allProjects.map((project) => {
const last3Projects = allProjects.slice(0, 3); const [lang, ...slug] = project.slug.split("/");
if (lang !== "es")
return {
...project,
slug: slug.toString(),
};
else null;
});
sortContentByDate(allEnProjects);
const last3Projects = allEnProjects.slice(0, 3);
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout <Layout
@ -29,9 +52,9 @@ const last3Projects = allProjects.slice(0, 3);
>, <strong>Linux</strong> enthusiast, and <strong>privacy</strong> defender. >, <strong>Linux</strong> enthusiast, and <strong>privacy</strong> defender.
</p> </p>
<p> <p>
This is my <strong>website</strong>, a piece of the Internet that I could This is my <strong>website</strong>, a piece of the Internet that I
call my <strong>home base</strong>. Here, I share my passion about open could call my <strong>home base</strong>. Here, I share my passion
source projects and other topics. about open source projects and other topics.
</p> </p>
<section> <section>
<h2>Latest posts</h2> <h2>Latest posts</h2>
@ -41,6 +64,7 @@ const last3Projects = allProjects.slice(0, 3);
<li class="p-0"> <li class="p-0">
<PostItem <PostItem
type="blog" type="blog"
lang={lang}
slug={blogpost.slug} slug={blogpost.slug}
date={blogpost.data.date!} date={blogpost.data.date!}
title={blogpost.data.title!} title={blogpost.data.title!}
@ -49,28 +73,36 @@ const last3Projects = allProjects.slice(0, 3);
)) ))
} }
</ul> </ul>
<LinkButton variant="secondary" href="/blog" className="no-underline" <LinkButton
>More posts</LinkButton variant="secondary"
href="/blog"
className="no-underline">More posts</LinkButton
> >
</section> </section>
<section> <section>
<h2>Latest projects</h2> <h2>Latest projects</h2>
<ul class="mt-0 p-0 list-none"> <ul class="mt-0 p-0 list-none">
{ {
last3Projects.map((project: any) => ( last3Projects.map(
(project) =>
project && (
<li class="p-0"> <li class="p-0">
<PostItem <PostItem
lang={lang}
type="portfolio" type="portfolio"
slug={project.slug} slug={project.slug}
date={project.data.date!} date={project.data.date!}
title={project.data.title!} title={project.data.title!}
/> />
</li> </li>
)) ),
)
} }
</ul> </ul>
<LinkButton variant="secondary" href="/portfolio" className="no-underline" <LinkButton
>More projects</LinkButton variant="secondary"
href="/portfolio"
className="no-underline">More projects</LinkButton
> >
</section> </section>
</div> </div>

@ -4,6 +4,7 @@ import { getCollection } from "astro:content";
import components from "@/components/mdx/wrapper"; import components from "@/components/mdx/wrapper";
import formatDate from "@/utils/format-date"; import formatDate from "@/utils/format-date";
import type { CollectionEntry } from "astro:content"; import type { CollectionEntry } from "astro:content";
import { getLangFromUrl } from "@/i18n/utils";
interface Props { interface Props {
project: CollectionEntry<"portfolio">; project: CollectionEntry<"portfolio">;
@ -12,17 +13,29 @@ interface Props {
export async function getStaticPaths() { export async function getStaticPaths() {
const allProjects = await getCollection( const allProjects = await getCollection(
"portfolio", "portfolio",
({ data }) => data.draft !== true ({ data }) => data.draft !== true,
); );
const filterEnProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
return allProjects.map((project) => ({ if (lang === "en")
params: { slug: project.slug }, return {
...project,
slug: slug.toString(),
};
else null;
});
return filterEnProjects.map((project) => ({
params: { slug: project?.slug },
props: { project }, props: { project },
})); }));
} }
const { project } = Astro.props; const { project } = Astro.props;
const { Content } = await project.render(); const { Content } = await project.render();
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout title={project.data.title} description={project.data.description}> <Layout title={project.data.title} description={project.data.description}>
@ -32,7 +45,7 @@ const { Content } = await project.render();
<hr /> <hr />
<p> <p>
<strong>Posted: </strong> <strong>Posted: </strong>
{project.data.date && formatDate(new Date(project.data.date))} {project.data.date && formatDate(new Date(project.data.date), lang)}
</p> </p>
</article> </article>
</Layout> </Layout>

@ -1,5 +1,6 @@
--- ---
import PostItem from "@/components/post-item"; import PostItem from "@/components/post-item";
import { getLangFromUrl } from "@/i18n/utils";
import Layout from "@/layouts/Layout.astro"; import Layout from "@/layouts/Layout.astro";
import { sortContentByDate } from "@/utils/sorts"; import { sortContentByDate } from "@/utils/sorts";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
@ -11,9 +12,21 @@ const pageData = {
const allProjects = await getCollection( const allProjects = await getCollection(
"portfolio", "portfolio",
({ data }) => data.draft !== true ({ data }) => data.draft !== true,
); );
sortContentByDate(allProjects); const allEnProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
if (lang === "en")
return {
...project,
slug: slug,
};
else null;
});
sortContentByDate(allEnProjects);
const lang = getLangFromUrl(Astro.url);
--- ---
<Layout {...pageData}> <Layout {...pageData}>
@ -23,16 +36,20 @@ sortContentByDate(allProjects);
</section> </section>
<ul class="mt-4 flex flex-col gap-4"> <ul class="mt-4 flex flex-col gap-4">
{ {
allProjects.map((project: any) => ( allEnProjects.map(
(project) =>
project && (
<li> <li>
<PostItem <PostItem
lang={lang}
type="portfolio" type="portfolio"
slug={project.slug} slug={project.slug}
date={project.data.date!} date={project.data.date!}
title={project.data.title!} title={project.data.title!}
/> />
</li> </li>
)) ),
)
} }
</ul> </ul>
</Layout> </Layout>

@ -12,12 +12,29 @@ const months = [
"November", "November",
"December", "December",
]; ];
const meses = [
"Enero",
"Febrero",
"Marzo",
"Abril",
"Mayo",
"Junio",
"Julio",
"Agosto",
"Septiembre",
"Octubre",
"Noviembre",
"Diciembre",
];
export default function formatDate(date: Date | string) { export default function formatDate(date: Date | string, lang: string) {
const newDate = new Date(date); const newDate = new Date(date);
const month = months[newDate.getMonth()]; const month = months[newDate.getMonth()];
const mes = meses[newDate.getMonth()];
const day = newDate.getDate(); const day = newDate.getDate();
const year = newDate.getFullYear(); const year = newDate.getFullYear();
return `${month} ${day}, ${year}`; return lang !== "es"
? `${month} ${day}, ${year}`
: `${day} de ${mes} del ${year}`;
} }