translate a better way for consuming content post

This commit is contained in:
Juan Carlos Manzanero Domínguez 2024-10-07 19:55:57 -06:00
parent ad33d51489
commit 9ba7c8416d
9 changed files with 359 additions and 236 deletions

View File

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

View File

@ -1,16 +1,19 @@
---
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))}{" "}
{formatDate(new Date(props.published), lang)}{" "}
</span>
<span class="text-sm font-thin">
{new Date(props.published).toLocaleTimeString()}
@ -21,8 +24,7 @@ const content = marked.parse(props.content);
props &&
props.expand.tags &&
props?.expand.tags.map(
(tag: any) =>
tag && <span class="text-sm">#{tag.name} </span>,
(tag: any) => tag && <span class="text-sm">#{tag.name} </span>,
)
}
</section>

View File

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

View File

@ -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
![Periódicos](@/assets/blog/a-better-way-for-consuming-content/banner.webp) _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/)

View File

@ -6,6 +6,12 @@ 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("/");
@ -40,10 +46,7 @@ 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."
>
<Layout {...pageData}>
<div class="prose prose-invert">
<h1 class="text-primary">Bienvenido a mi dominio, extraño.</h1>
<p>
@ -54,9 +57,9 @@ const lang = getLangFromUrl(Astro.url);
>
</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.
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>
@ -78,10 +81,8 @@ const lang = getLangFromUrl(Astro.url);
)
}
</ul>
<LinkButton
variant="secondary"
href="/blog"
className="no-underline">Más posts</LinkButton
<LinkButton variant="secondary" href="/blog" className="no-underline"
>Más posts</LinkButton
>
</section>
<section>
@ -104,10 +105,8 @@ const lang = getLangFromUrl(Astro.url);
)
}
</ul>
<LinkButton
variant="secondary"
href="/portfolio"
className="no-underline">More projects</LinkButton
<LinkButton variant="secondary" href="/portfolio" className="no-underline"
>Más proyectos</LinkButton
>
</section>
</div>

View File

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

View File

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

View File

@ -6,6 +6,12 @@ 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("/");
@ -40,10 +46,7 @@ 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."
>
<Layout {...pageData}>
<div class="prose prose-invert">
<h1 class="text-primary">Welcome to my domain, stranger.</h1>
<p>
@ -52,9 +55,9 @@ const lang = getLangFromUrl(Astro.url);
>, <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.
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>
@ -73,10 +76,8 @@ const lang = getLangFromUrl(Astro.url);
))
}
</ul>
<LinkButton
variant="secondary"
href="/blog"
className="no-underline">More posts</LinkButton
<LinkButton variant="secondary" href="/blog" className="no-underline"
>More posts</LinkButton
>
</section>
<section>
@ -99,10 +100,8 @@ const lang = getLangFromUrl(Astro.url);
)
}
</ul>
<LinkButton
variant="secondary"
href="/portfolio"
className="no-underline">More projects</LinkButton
<LinkButton variant="secondary" href="/portfolio" className="no-underline"
>More projects</LinkButton
>
</section>
</div>

View File

@ -20,7 +20,7 @@ const allEnProjects = allProjects.map((project) => {
if (lang === "en")
return {
...project,
slug: slug,
slug: slug.toString(),
};
else null;
});