translate a better way for consuming content post
This commit is contained in:
parent
ad33d51489
commit
9ba7c8416d
@ -2,6 +2,19 @@ import { Code, RssIcon } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import formatDate from "@/utils/format-date";
|
||||
|
||||
const locales = {
|
||||
en: {
|
||||
developed_by: "Developed by",
|
||||
build_handcrafted: "Built handcrafted with",
|
||||
last_build: "Last build",
|
||||
},
|
||||
es: {
|
||||
developed_by: "Desarrollado por",
|
||||
build_handcrafted: "Construido a mano con",
|
||||
last_build: "Última build",
|
||||
},
|
||||
};
|
||||
|
||||
type Props = {
|
||||
lang: "en" | "es";
|
||||
};
|
||||
@ -11,11 +24,11 @@ export default function Footer(props: Props) {
|
||||
<footer className="border-t border-secondary px-4 py-12 text-center text-sm md:px-16 prose prose-invert min-w-full">
|
||||
<section>
|
||||
<p>
|
||||
Developed by{" "}
|
||||
{locales[props.lang].developed_by}{" "}
|
||||
<strong className="font-bold text-primary">juancmandev</strong>
|
||||
</p>
|
||||
<p>
|
||||
Built handcrafted with{" "}
|
||||
{locales[props.lang].build_handcrafted}{" "}
|
||||
<Button
|
||||
asChild
|
||||
size={null}
|
||||
@ -27,7 +40,10 @@ export default function Footer(props: Props) {
|
||||
</a>
|
||||
</Button>
|
||||
</p>
|
||||
<p>Last built {formatDate(new Date())}.</p>
|
||||
<p>
|
||||
{locales[props.lang].last_build}: {formatDate(new Date(), props.lang)}
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
<section className="w-max mx-auto flex items-center gap-12">
|
||||
<Button
|
||||
|
@ -1,31 +1,33 @@
|
||||
---
|
||||
import { marked } from "marked";
|
||||
import formatDate from "@/utils/format-date";
|
||||
import { getLangFromUrl } from "@/i18n/utils";
|
||||
|
||||
const props = Astro.props;
|
||||
const content = marked.parse(props.content);
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
---
|
||||
|
||||
<article class="rounded-md border px-4 py-2">
|
||||
<header class="mb-2">
|
||||
<section class="flex items-center justify-between text-sm">
|
||||
<span class="font-light">
|
||||
{formatDate(new Date(props.published))}{" "}
|
||||
</span>
|
||||
<span class="text-sm font-thin">
|
||||
{new Date(props.published).toLocaleTimeString()}
|
||||
</span>
|
||||
</section>
|
||||
<section class="mt-1">
|
||||
{
|
||||
props &&
|
||||
props.expand.tags &&
|
||||
props?.expand.tags.map(
|
||||
(tag: any) =>
|
||||
tag && <span class="text-sm">#{tag.name} </span>,
|
||||
)
|
||||
}
|
||||
</section>
|
||||
</header>
|
||||
<main set:html={content} />
|
||||
<header class="mb-2">
|
||||
<section class="flex items-center justify-between text-sm">
|
||||
<span class="font-light">
|
||||
{formatDate(new Date(props.published), lang)}{" "}
|
||||
</span>
|
||||
<span class="text-sm font-thin">
|
||||
{new Date(props.published).toLocaleTimeString()}
|
||||
</span>
|
||||
</section>
|
||||
<section class="mt-1">
|
||||
{
|
||||
props &&
|
||||
props.expand.tags &&
|
||||
props?.expand.tags.map(
|
||||
(tag: any) => tag && <span class="text-sm">#{tag.name} </span>,
|
||||
)
|
||||
}
|
||||
</section>
|
||||
</header>
|
||||
<main set:html={content} />
|
||||
</article>
|
||||
|
@ -53,8 +53,7 @@ you don't open the post link in your RSS Reader.
|
||||
The good thing is that almost every RSS Reader shows you content sorted by date,
|
||||
not by a creepy algorithm that wants you to be mad.
|
||||
|
||||
[For my website](https://github.com/juancmandev/website/blob/main/scripts/rss.ts),
|
||||
I use a Node.js script that takes the `.mdx` files inside `content/blog` and
|
||||
For my website I use a Node.js script that takes the `.mdx` files inside `content/blog` and
|
||||
`content/portfolio`, then generates the RSS Items, those with the `rss: true` in
|
||||
the metadata.
|
||||
|
||||
@ -115,6 +114,7 @@ https://youtube.com/feeds/videos.xml?channel_id=[CHANNEL ID]
|
||||
- [Astronomic Picture of the Day (apod)](https://apod.com/feed.rss)
|
||||
- [Earth Science Picture of the Day (epod)](https://feeds2.feedburner.com/EarthSciencePictureoftheDay)
|
||||
- [Erick Murphy (cool guy)](https://ericmurphy.xyz/index.xml)
|
||||
- [Luke Smith](https://lukesmith.xyz/index.xml)
|
||||
|
||||
## More About RSS
|
||||
|
||||
|
@ -1,14 +1,114 @@
|
||||
---
|
||||
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.
|
||||
description: Obtén tus noticias sin visitar websites con algoritmos que muestran contenido que no quieres ver.
|
||||
tags: [Tech]
|
||||
image: /blog/a-better-way-for-consuming-content/banner.webp
|
||||
imageCaption: Newspapers. Photo by Ashni on Unsplash
|
||||
imageCaption: Periódicos. Foto de Ashni en Unsplash
|
||||
date: 2024-4-11
|
||||
author: Juan Manzanero
|
||||
rss: true
|
||||
---
|
||||
|
||||
Hola
|
||||
 _Foto de
|
||||
[Ashni](https://unsplash.com/@ashni_ahlawat?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash)
|
||||
en
|
||||
[Unsplash](https://unsplash.com/photos/text-ePWaAwUn80k?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash)_
|
||||
|
||||
Obtén tus noticias sin visitar websites con algoritmos que muestran contenido que no quieres ver.
|
||||
|
||||
## Algoritmos que dictan lo que ves
|
||||
|
||||
Las redes sociales no están diseñadas para mostrarte las noticias más novedosas e importantes,
|
||||
sino para mostrarte contenido dictado por un algoritmo.
|
||||
|
||||
Y este contenido es normalmente, viral; y viral no quiere decir interesante.
|
||||
|
||||
Normalmente estos algoritmos priorizan contenido que te hacen enojar.
|
||||
|
||||
Contenido que promueve la negatividad obtiene más "clicks" que aquel que promueve la positividad.
|
||||
|
||||
Esa es la razón por la cual Twitter y Facebook están llenos de posts estúpidos e irrelevantes (por lo regular).
|
||||
|
||||
Por supuesto, es genial cuando el algoritmo te muestra contenido que te gusta,
|
||||
descubriendo nuevas personas y páginas, pero eso no es lo usual.
|
||||
|
||||
Sin mencionar los molestos anuncios y más cosas que quieren que les hagas click.
|
||||
|
||||
Meta (anteriormente Facebook) sabe sobre esto, y promueve en sus productos como Instagram y Facebook,
|
||||
lo mismo con Twitter.
|
||||
|
||||
## La Solución: News Aggregators (RSS)
|
||||
|
||||
RSS es un acrónimo de "Really Simple Syndication".
|
||||
|
||||
Es una tecnología antigua, no muy promovida por las compañías.
|
||||
|
||||
Esto es debido a que cuando lees un post en un RSS Reader, no debes de visitar el website,
|
||||
y el website no puede mostrarte anuncios usando Google Ads (por ejemplo). No generas tráfico,
|
||||
tus visitas no cuentan, al menos no si no abres el link del post en tu RSS Reader.
|
||||
|
||||
Lo bueno que casi cualquier RSS Reader te muestra el contenido organizado por fechas,
|
||||
no por un algoritmo raro que quiere hacerte enojar.
|
||||
|
||||
Para mi website utilizo un script en Node.js que toma todos los archivos `.mdx` dentro de `content/blog`
|
||||
y `content/portfolio`, entonces genera los RSS Items, aquellos con `rss: true` en sus metadatos.
|
||||
|
||||
## Cómo usar un RSS Reader
|
||||
|
||||
Primero, debes descargar uno.
|
||||
|
||||
Hay muchas opciones:
|
||||
|
||||
- [NetNewsWire](https://netnewswire.com/): un RSS Reader nativo para macOS y iOS, gratis y Open Source,
|
||||
mi opción favorita como ~~Pecador~~ usuario de Apple
|
||||
- [Akregator](https://apps.kde.org/akregator): del proyecto KDE para Linux
|
||||
- [Feeder](https://play.google.com/store/apps/details?id=com.nononsenseapps.feeder.play): para Android
|
||||
- [Raven Reader](https://ravenreader.app/): aplicación de escritorio multiplataforma
|
||||
|
||||
### Agregando Feeds
|
||||
|
||||
Ahora debes buscar por el link RSS de tu website favorito, ¡[como este](https://juancman.dev/es/rss.xml)!
|
||||
|
||||
```
|
||||
https://juancman.dev/es/rss.xml
|
||||
```
|
||||
|
||||
Si lo abres, verás una página rara con código similar a HTML.
|
||||
|
||||
Una vez copiado, ve a tu RSS app y busca "Agregar feed" o algo similar, y pega el link, ¡y listo!,
|
||||
ahora obtendrás los últimos posts de mi website.
|
||||
|
||||
### Agregando Feeds de Redes Sociales
|
||||
|
||||
Puedes agregar incluso feeds de sitios como Reddit o YouTube.
|
||||
|
||||
#### Reddit
|
||||
|
||||
Solo cambia `[SUBREDDIT]` por el nombre del subreddit a añadir:
|
||||
|
||||
```
|
||||
https://reddit.com/r/[SUBREDDIT]/new/.rss
|
||||
```
|
||||
|
||||
#### YouTube
|
||||
|
||||
Ve a el canal por añadir, luego ve a la pestaña "Acerca de", da click en **Compartir > Copiar ID del Canal**.
|
||||
|
||||
Ahora solo cambia `[CHANNEL ID]` por el copiado:
|
||||
|
||||
```
|
||||
https://youtube.com/feeds/videos.xml?channel_id=[CHANNEL ID]
|
||||
```
|
||||
|
||||
### Mis Feeds Favoritos
|
||||
|
||||
- [juancman.dev (¡obviamente!)](https://www.juancman.dev/es/rss.xml)
|
||||
- [Astronomic Picture of the Day (apod)](https://apod.com/feed.rss)
|
||||
- [Earth Science Picture of the Day (epod)](https://feeds2.feedburner.com/EarthSciencePictureoftheDay)
|
||||
- [Erick Murphy](https://ericmurphy.xyz/index.xml)
|
||||
- [Luke Smith](https://lukesmith.xyz/index.xml)
|
||||
|
||||
## Más Sobre RSS
|
||||
|
||||
- [Privacy Tools - RSS Feed Readers](https://www.privacytools.io/privacy-rss-feed-readers)
|
||||
- [Privacy Guides - News Aggregators](https://www.privacyguides.org/en/news-aggregators/)
|
||||
|
@ -6,33 +6,39 @@ import Layout from "@/layouts/Layout.astro";
|
||||
import { sortContentByDate } from "@/utils/sorts";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const pageData = {
|
||||
title: "juancmandev",
|
||||
description:
|
||||
"Bienvenido a mi dominio, extraño. Soy juancmandev; Desarrollador Web, entusiasta de Linux, y defensor de la privacidad.",
|
||||
};
|
||||
|
||||
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
||||
const allEsPosts = allPosts.map((post) => {
|
||||
const [lang, ...slug] = post.slug.split("/");
|
||||
const [lang, ...slug] = post.slug.split("/");
|
||||
|
||||
if (lang === "es")
|
||||
return {
|
||||
...post,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
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,
|
||||
"portfolio",
|
||||
({ data }) => data.draft !== true,
|
||||
);
|
||||
const allEnProjects = allProjects.map((project) => {
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
|
||||
if (lang === "es")
|
||||
return {
|
||||
...project,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
if (lang === "es")
|
||||
return {
|
||||
...project,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
});
|
||||
sortContentByDate(allEnProjects);
|
||||
const last3Projects = allEnProjects.slice(0, 3);
|
||||
@ -40,75 +46,68 @@ 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."
|
||||
>
|
||||
<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 {...pageData}>
|
||||
<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"
|
||||
>Más proyectos</LinkButton
|
||||
>
|
||||
</section>
|
||||
</div>
|
||||
</Layout>
|
||||
|
@ -4,6 +4,7 @@ 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<"videos">;
|
||||
@ -12,7 +13,7 @@ interface Props {
|
||||
export async function getStaticPaths() {
|
||||
const allProjects = await getCollection(
|
||||
"videos",
|
||||
({ data }) => data.draft !== true
|
||||
({ data }) => data.draft !== true,
|
||||
);
|
||||
|
||||
return allProjects.map((project) => ({
|
||||
@ -23,6 +24,8 @@ export async function getStaticPaths() {
|
||||
|
||||
const { project } = Astro.props;
|
||||
const { Content } = await project.render();
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
---
|
||||
|
||||
<Layout title={project.data.title} description={project.data.description}>
|
||||
@ -32,7 +35,7 @@ const { Content } = await project.render();
|
||||
<hr />
|
||||
<p>
|
||||
<strong>Posted: </strong>
|
||||
{project.data.date && formatDate(new Date(project.data.date))}
|
||||
{project.data.date && formatDate(new Date(project.data.date), lang)}
|
||||
</p>
|
||||
</article>
|
||||
</Layout>
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
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";
|
||||
@ -11,9 +12,11 @@ const pageData = {
|
||||
|
||||
const allVideos = await getCollection(
|
||||
"videos",
|
||||
({ data }) => data.draft !== true
|
||||
({ data }) => data.draft !== true,
|
||||
);
|
||||
sortContentByDate(allVideos);
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
---
|
||||
|
||||
<Layout {...pageData}>
|
||||
@ -26,6 +29,7 @@ sortContentByDate(allVideos);
|
||||
allVideos.map((video: any) => (
|
||||
<li>
|
||||
<PostItem
|
||||
lang={lang}
|
||||
type="es/videos"
|
||||
slug={video.slug}
|
||||
date={video.data.date!}
|
||||
|
@ -6,33 +6,39 @@ import PostItem from "@/components/post-item";
|
||||
import { sortContentByDate } from "@/utils/sorts";
|
||||
import { getLangFromUrl } from "@/i18n/utils";
|
||||
|
||||
const pageData = {
|
||||
title: "juancmandev",
|
||||
description:
|
||||
"Welcome to my domain, stranger. I am juancmandev; Web Developer, Linux enthusiast, and privacy defender.",
|
||||
};
|
||||
|
||||
const allPosts = await getCollection("blog", ({ data }) => data.draft !== true);
|
||||
const allEnPosts = allPosts.map((post) => {
|
||||
const [lang, ...slug] = post.slug.split("/");
|
||||
const [lang, ...slug] = post.slug.split("/");
|
||||
|
||||
if (lang !== "es")
|
||||
return {
|
||||
...post,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
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,
|
||||
);
|
||||
const allEnProjects = allProjects.map((project) => {
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
|
||||
if (lang !== "es")
|
||||
return {
|
||||
...project,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
if (lang !== "es")
|
||||
return {
|
||||
...project,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
});
|
||||
sortContentByDate(allEnProjects);
|
||||
const last3Projects = allEnProjects.slice(0, 3);
|
||||
@ -40,70 +46,63 @@ 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."
|
||||
>
|
||||
<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 {...pageData}>
|
||||
<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>
|
||||
|
@ -6,23 +6,23 @@ 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,
|
||||
);
|
||||
const allEnProjects = allProjects.map((project) => {
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
const [lang, ...slug] = project.slug.split("/");
|
||||
|
||||
if (lang === "en")
|
||||
return {
|
||||
...project,
|
||||
slug: slug,
|
||||
};
|
||||
else null;
|
||||
if (lang === "en")
|
||||
return {
|
||||
...project,
|
||||
slug: slug.toString(),
|
||||
};
|
||||
else null;
|
||||
});
|
||||
sortContentByDate(allEnProjects);
|
||||
|
||||
@ -30,26 +30,26 @@ 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">
|
||||
{
|
||||
allEnProjects.map(
|
||||
(project) =>
|
||||
project && (
|
||||
<li>
|
||||
<PostItem
|
||||
lang={lang}
|
||||
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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user