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

View File

@ -6,6 +6,7 @@ type Props = {
date: Date | string;
title: string;
type: "blog" | "portfolio" | "es/videos";
lang: string;
};
export default function PostItem(props: Props) {
@ -16,9 +17,16 @@ export default function PostItem(props: Props) {
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"
>
<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">
{formatDate(props.date)}
{formatDate(props.date, props.lang)}
</span>
<span className="text-primary text-underline text-lg font-semibold underline">
{props.title}

View File

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

View File

@ -4,35 +4,48 @@ 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">;
post: CollectionEntry<"blog">;
}
export async function getStaticPaths() {
const allBlogPosts = await getCollection(
"blog",
({ data }) => data.draft !== true
);
const allBlogPosts = await getCollection(
"blog",
({ data }) => data.draft !== true,
);
const filterEnPosts = allBlogPosts.map((post) => {
const [lang, ...slug] = post.slug.split("/");
return allBlogPosts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
if (lang === "en")
return {
...post,
slug: slug.toString(),
};
else null;
});
return filterEnPosts.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>Posted: </strong>
{post.data.date && formatDate(new Date(post.data.date))}
</p>
</article>
<article class="prose prose-invert">
<h1>{post.data.title}</h1>
<Content components={{ ...components }} />
<hr />
<p>
<strong>Posted: </strong>
{post.data.date && formatDate(new Date(post.data.date), lang)}
</p>
</article>
</Layout>

View File

@ -1,35 +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: "Long format about thoughts and other topics.",
title: "Blog",
description: "Long format about thoughts and other topics.",
};
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}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
allPosts.map((blogpost: any) => (
<li>
<PostItem
type="blog"
slug={blogpost.slug}
date={blogpost.data.date!}
title={blogpost.data.title!}
/>
</li>
))
}
</ul>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
filterEnPosts.map(
(blogpost) =>
blogpost && (
<li>
<PostItem
type="blog"
lang={lang}
slug={blogpost.slug}
date={blogpost.data.date!}
title={blogpost.data.title!}
/>
</li>
),
)
}
</ul>
</Layout>

View File

@ -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>

View File

@ -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>

View File

@ -1,24 +1,114 @@
---
import LinkButton from "@/components/link-button";
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 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
title="juancmandev"
description="Bienvenido a mi dominio, extraño. Soy juancmandev; Desarrollador Web, entusiasta de Linux, y defensor de la privacidad."
title="juancmandev"
description="Bienvenido a mi dominio, extraño. Soy juancmandev; Desarrollador Web, entusiasta de Linux, y defensor de la privacidad."
>
<div class="prose prose-invert">
<h1 class="text-primary">Bienvenido a mi dominio, extraño.</h1>
<p>
Soy <strong class="text-primary">juancmandev</strong>; <strong
>Desarrollador Web</strong
>, entusiasta de <strong>Linux</strong> y defensor de la <strong
>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>
<div class="prose prose-invert">
<h1 class="text-primary">Bienvenido a mi dominio, extraño.</h1>
<p>
Soy <strong class="text-primary">juancmandev</strong>; <strong
>Desarrollador Web</strong
>, entusiasta de <strong>Linux</strong> y defensor de la <strong
>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>
<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>
</Layout>

View File

@ -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>

View File

@ -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>

View File

@ -4,74 +4,106 @@ import LinkButton from "@/components/link-button";
import { getCollection } from "astro:content";
import PostItem from "@/components/post-item";
import { sortContentByDate } from "@/utils/sorts";
import { getLangFromUrl } from "@/i18n/utils";
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
sortContentByDate(allPosts);
const last3Blogs = allPosts.slice(0, 3);
const allEnPosts = allPosts.map((post) => {
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(
"portfolio",
({ data }) => data.draft !== true
"portfolio",
({ data }) => data.draft !== true,
);
sortContentByDate(allProjects);
const last3Projects = allProjects.slice(0, 3);
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
title="juancmandev"
description="Welcome to my domain, stranger. I am juancmandev; Web Developer, Linux enthusiast, and privacy defender."
title="juancmandev"
description="Welcome to my domain, stranger. I am juancmandev; Web Developer, Linux enthusiast, and privacy defender."
>
<div class="prose prose-invert">
<h1 class="text-primary">Welcome to my domain, stranger.</h1>
<p>
I am <strong class="text-primary">juancmandev</strong>; <strong
>Web Developer</strong
>, <strong>Linux</strong> enthusiast, and <strong>privacy</strong> defender.
</p>
<p>
This is my <strong>website</strong>, a piece of the Internet that I could
call my <strong>home base</strong>. Here, I share my passion about open
source projects and other topics.
</p>
<section>
<h2>Latest posts</h2>
<ul class="mt-0 p-0 list-none">
{
last3Blogs.map((blogpost: any) => (
<li class="p-0">
<PostItem
type="blog"
slug={blogpost.slug}
date={blogpost.data.date!}
title={blogpost.data.title!}
/>
</li>
))
}
</ul>
<LinkButton variant="secondary" href="/blog" className="no-underline"
>More posts</LinkButton
>
</section>
<section>
<h2>Latest projects</h2>
<ul class="mt-0 p-0 list-none">
{
last3Projects.map((project: any) => (
<li class="p-0">
<PostItem
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 class="prose prose-invert">
<h1 class="text-primary">Welcome to my domain, stranger.</h1>
<p>
I am <strong class="text-primary">juancmandev</strong>; <strong
>Web Developer</strong
>, <strong>Linux</strong> enthusiast, and <strong>privacy</strong> defender.
</p>
<p>
This is my <strong>website</strong>, a piece of the Internet that I
could call my <strong>home base</strong>. Here, I share my passion
about open source projects and other topics.
</p>
<section>
<h2>Latest posts</h2>
<ul class="mt-0 p-0 list-none">
{
last3Blogs.map((blogpost: any) => (
<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">More posts</LinkButton
>
</section>
<section>
<h2>Latest projects</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>
</Layout>

View File

@ -4,35 +4,48 @@ 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">;
project: CollectionEntry<"portfolio">;
}
export async function getStaticPaths() {
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true
);
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true,
);
const filterEnProjects = allProjects.map((project) => {
const [lang, ...slug] = project.slug.split("/");
return allProjects.map((project) => ({
params: { slug: project.slug },
props: { project },
}));
if (lang === "en")
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>Posted: </strong>
{project.data.date && formatDate(new Date(project.data.date))}
</p>
</article>
<article class="prose prose-invert">
<h1>{project.data.title}</h1>
<Content components={{ ...components }} />
<hr />
<p>
<strong>Posted: </strong>
{project.data.date && formatDate(new Date(project.data.date), lang)}
</p>
</article>
</Layout>

View File

@ -1,38 +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: "Check my projects.",
title: "Portfolio",
description: "Check my projects.",
};
const allProjects = await getCollection(
"portfolio",
({ data }) => data.draft !== true
"portfolio",
({ 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}>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
allProjects.map((project: any) => (
<li>
<PostItem
type="portfolio"
slug={project.slug}
date={project.data.date!}
title={project.data.title!}
/>
</li>
))
}
</ul>
<section class="prose prose-invert">
<h1>{pageData.title}</h1>
<p>{pageData.description}</p>
</section>
<ul class="mt-4 flex flex-col gap-4">
{
allEnProjects.map(
(project) =>
project && (
<li>
<PostItem
lang={lang}
type="portfolio"
slug={project.slug}
date={project.data.date!}
title={project.data.title!}
/>
</li>
),
)
}
</ul>
</Layout>

View File

@ -12,12 +12,29 @@ const months = [
"November",
"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 month = months[newDate.getMonth()];
const mes = meses[newDate.getMonth()];
const day = newDate.getDate();
const year = newDate.getFullYear();
return `${month} ${day}, ${year}`;
return lang !== "es"
? `${month} ${day}, ${year}`
: `${day} de ${mes} del ${year}`;
}