diff --git a/.gitignore b/.gitignore
index e3a7954e..37686838 100644
--- a/.gitignore
+++ b/.gitignore
@@ -145,3 +145,8 @@ data/*
secrets
.playwright-mcp/
+.screenshots/
+screenshots/
+.superpowers/
+
+.claude/settings.local.json
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ee935177..5e739c10 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,10 +19,10 @@ repos:
- id: debug-statements
- repo: https://github.com/crate-ci/typos
- rev: v1
+ rev: v1.46.1
hooks:
- id: typos
- exclude: ^.*htmx\.min\..*\.js$
+ exclude: ^(.*htmx\.min\..*\.js|core/static/core/vendor/.*)$
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.25
@@ -34,23 +34,18 @@ repos:
rev: "1.9.0"
hooks:
- id: djade
- args: [--target-version, "5.1"]
+ args: [--target-version, "6.0"]
- repo: https://github.com/adamchainz/django-upgrade
rev: "1.30.0"
hooks:
- id: django-upgrade
-
- - repo: https://github.com/asottile/pyupgrade
- rev: v3.21.2
- hooks:
- - id: pyupgrade
- args: [--py313]
+ args: [--target-version, "6.0"]
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: 'v0.15.6'
+ rev: 'v0.15.12'
hooks:
- id: ruff-check
- args: ["--fix", "--target-version", "py313"]
+ args: ["--fix", "--target-version", "py314"]
- id: ruff-format
- args: ["--target-version", "py313"]
+ args: ["--target-version", "py314"]
diff --git a/blog/apps.py b/blog/apps.py
index 10038974..50c2d695 100644
--- a/blog/apps.py
+++ b/blog/apps.py
@@ -1,5 +1,31 @@
from django.apps import AppConfig
+from django.contrib.postgres.search import SearchVector
+from django.db import connections
+from django.db.models import Model
+from django.db.models.signals import post_save
+
+
+def update_search_vector(sender: type[Model], instance: Model, **kwargs: object) -> None:
+ """Keep the PostgreSQL search vector in sync after model saves."""
+ using = kwargs.get("using")
+ db_alias = using if isinstance(using, str) else "default"
+ if connections[db_alias].vendor != "postgresql":
+ return
+
+ sender._default_manager.using(db_alias).filter(pk=instance.pk).update(
+ search_vector=(
+ SearchVector("title", weight="A") + SearchVector("summary", weight="B") + SearchVector("text", weight="C")
+ )
+ )
class BlogConfig(AppConfig):
name = "blog"
+
+ def ready(self) -> None:
+ post_save.connect(
+ update_search_vector,
+ sender=self.get_model("Post"),
+ dispatch_uid="blog.post.update_search_vector",
+ weak=False,
+ )
diff --git a/blog/filters.py b/blog/filters.py
index f7fdbde3..82ca8b83 100644
--- a/blog/filters.py
+++ b/blog/filters.py
@@ -1,5 +1,5 @@
import django_filters
-from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
+from django.contrib.postgres.search import SearchQuery, SearchRank
from django.db.models import QuerySet
from blog.models import Post
@@ -17,11 +17,8 @@ def filter_search(self, queryset: QuerySet[Post], name: str, value: str) -> Quer
return queryset
search_query = SearchQuery(value)
- search_vector = (
- SearchVector("title", weight="A") + SearchVector("summary", weight="B") + SearchVector("text", weight="C")
- )
return (
- queryset.annotate(search=search_vector, rank=SearchRank(search_vector, search_query))
- .filter(search=search_query)
+ queryset.filter(search_vector=search_query)
+ .annotate(rank=SearchRank("search_vector", search_query))
.order_by("-rank")
)
diff --git a/blog/forms.py b/blog/forms.py
index 657760be..9fbd5f23 100644
--- a/blog/forms.py
+++ b/blog/forms.py
@@ -6,17 +6,16 @@
from django import forms
from django.conf import settings
from django.core.mail import send_mail
-from django.utils.safestring import mark_safe
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from blog.services.captcha import verify_captcha
log = logging.getLogger(__name__)
-msg = mark_safe(f"{_('Message')}")
-email_label = mark_safe(f"{_('Email')}")
-name_label = mark_safe(f"{_('Name')}")
-captcha_label = mark_safe(f"{_('What color is the red rabbit?')}")
+
+class InvalidCaptchaValidationError(forms.ValidationError):
+ def __init__(self) -> None:
+ super().__init__("invalid captcha")
class EmailForm(forms.Form):
@@ -54,25 +53,26 @@ class AdvanceSearchForm(forms.Form):
class ContactForm(forms.Form):
- name = forms.CharField(label=name_label)
- email = forms.EmailField(label=email_label)
- message = forms.CharField(label=msg, widget=forms.Textarea)
- captcha = forms.CharField(label=captcha_label)
+ name = forms.CharField(label=_("Name"))
+ email = forms.EmailField(label=_("Email"))
+ message = forms.CharField(label=_("Message"), widget=forms.Textarea)
+ captcha = forms.CharField(label=_("What color is the red rabbit?"))
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.helper = FormHelper()
+ self.helper.form_tag = False
self.helper.layout = Layout(
- Field("name", css_class="mt-1 p-2 w-full rounded-md text-gray-800"),
- Field("email", css_class="mt-1 p-2 w-full rounded-md text-gray-800"),
- Field("message", css_class="mt-1 p-2 w-full resize rounded-md text-gray-800", rows=6),
- Field("captcha", css_class="mt-1 p-2 w-full rounded-md text-gray-800"),
- Submit("submit", _("Send"), css_class="px-4 py-2 bg-purple-500 rounded hover:bg-pink-300"),
+ Field("name"),
+ Field("email"),
+ Field("message", rows=6),
+ Field("captcha"),
+ Submit("submit", _("Send")),
)
def clean_captcha(self) -> str:
# Get the cleaned value (after built-in validation checks)
captcha = self.cleaned_data.get("captcha", "")
if not verify_captcha(captcha):
- raise forms.ValidationError("invalid captcha")
+ raise InvalidCaptchaValidationError()
return captcha
diff --git a/blog/locale/es/LC_MESSAGES/django.po b/blog/locale/es/LC_MESSAGES/django.po
index f3679483..c65dee3e 100644
--- a/blog/locale/es/LC_MESSAGES/django.po
+++ b/blog/locale/es/LC_MESSAGES/django.po
@@ -3,12 +3,11 @@
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
#
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-09-11 23:15+0200\n"
+"POT-Creation-Date: 2026-04-03 13:15+0200\n"
"PO-Revision-Date: 2023-08-25 11:25-0300\n"
"Last-Translator: Eduardo Enriquez \n"
"Language-Team: LANGUAGE \n"
@@ -19,530 +18,380 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Translated-Using: django-rosetta 0.9.9\n"
-#: blog/forms.py:14
-msgid "Message"
-msgstr "Mensaje"
+#: blog/forms.py:51
+msgid "Name"
+msgstr "Nombre"
-#: blog/forms.py:15
+#: blog/forms.py:52 blog/templates/blog/contact.html:30
msgid "Email"
msgstr "Correo"
-#: blog/forms.py:16
-msgid "Name"
-msgstr "Nombre"
+#: blog/forms.py:53
+msgid "Message"
+msgstr "Mensaje"
-#: blog/forms.py:17
+#: blog/forms.py:54
msgid "What color is the red rabbit?"
msgstr "De que color es el conejo rojo?"
-#: blog/forms.py:68
+#: blog/forms.py:65 blog/templates/blog/contact.html:74
msgid "Send"
msgstr "Enviar"
-#: blog/models.py:16
+#: blog/models.py:12
msgid "word"
msgstr "palabra"
-#: blog/models.py:17 blog/models.py:47
+#: blog/models.py:13 blog/models.py:42
msgid "slug"
msgstr "slug"
-#: blog/models.py:21
+#: blog/models.py:17
msgid "tag"
msgstr "etiqueta"
-#: blog/models.py:22
+#: blog/models.py:18
msgid "tags"
msgstr "etiquetas"
-#: blog/models.py:44
+#: blog/models.py:39
msgid "title"
msgstr "titulo"
-#: blog/models.py:45
+#: blog/models.py:40
msgid "summary"
msgstr "resumen"
-#: blog/models.py:51
+#: blog/models.py:46
msgid "Body text"
msgstr "Cuerpo del texto"
-#: blog/templates/blog/_about.html:4
-msgid "About me"
-msgstr "Acerca de mi"
-
-#: blog/templates/blog/_about.html:9
-msgid "Hello World! My name is Eduardo and I'm a developer 💻."
-msgstr "¡Hola Mundo! Mi nombre es Eduardo y soy un developer 💻."
+#: blog/templates/blog/about.html:19
+msgid "Problem Solver"
+msgstr "Resuelve Problemas"
-#: blog/templates/blog/_about.html:10
-#, python-format
-msgid ""
-"I've been working ⛏️ with Python 🐍 for the last %(years)s years, most of the "
-"time working as a backend developer with Django."
-msgstr ""
-"He estado trabajando ⛏️ con Python 🐍 durante los últimos %(years)s años, "
-"mayormente como desarrollador backend con Django."
+#: blog/templates/blog/about.html:20
+msgid "Teacher"
+msgstr "Docente"
-#: blog/templates/blog/_about.html:11
-msgid "Currently living in"
-msgstr "Actualmente vivo en"
+#: blog/templates/blog/about.html:21
+msgid "Curious"
+msgstr "Curioso"
-#: blog/templates/blog/_about.html:11
-msgid "Buenos Aires"
-msgstr "Buenos Aires"
+#: blog/templates/blog/about.html:22
+msgid "Hands On"
+msgstr "Hands On"
-#: blog/templates/blog/_about.html:11
-msgid "München"
-msgstr "Munich"
+#: blog/templates/blog/about.html:23
+msgid "Reader"
+msgstr "Lector"
-#: blog/templates/blog/_about.html:11
-msgid "Amsterdam"
-msgstr "Ámsterdam"
+#: blog/templates/blog/about.html:24 blog/templates/blog/about.html:89
+msgid "Philosophy"
+msgstr "Filosofía"
-#: blog/templates/blog/_about.html:11
-msgid "while working from home."
-msgstr "mientras trabajo desde mi casa."
+#: blog/templates/blog/about.html:33
+#, python-format
+msgid "Hi, my name is Eduardo. I'm from Buenos Aires, I'm %(age)s years old, and I currently live in Amsterdam — I moved to the Netherlands in 2020, so it's been about %(years_in_nl)s years now. I work as a Team Lead at FareHarbor, in a role that combines parts of an engineering manager and a tech lead. Besides that, I really enjoy teaching and helping people grow in the IT world."
+msgstr "Hola, mi nombre es Eduardo. Soy de Buenos Aires, tengo %(age)s años y vivo en Amsterdam — me mudé a los Países Bajos en 2020, así que ya van unos %(years_in_nl)s años. Actualmente trabajo como Team Lead en FareHarbor, en un rol que combina un poco de engineering manager y tech lead. Pero además de eso, me gusta enseñar y ayudar a otras personas a desarrollarse en el mundo IT."
-#: blog/templates/blog/_about.html:18
-msgid "Click to read the long version..."
-msgstr "Clic para leer la versión extendida..."
+#: blog/templates/blog/about.html:38
+msgid "My path into software wasn't the usual one. I didn't formally study computer science beyond what I learned in high school. That doesn't mean I didn't spend countless hours, days, and months learning on my own. In fact, studying philosophy and earning my degree in that field played an important role in shaping how I think and approach problems."
+msgstr "Mi historia no es la habitual. No estudié software de manera formal, más allá de lo que aprendí en la escuela secundaria. Eso no significa que no le haya dedicado horas, días y meses de estudio autodidacta. De hecho, creo que haber estudiado y graduarme en Filosofía fue clave para formarme intelectualmente y aprender a pensar mejor los problemas."
-#: blog/templates/blog/_about.html:42
-msgid "A bit more about me 😉, so here it goes:"
-msgstr "Un poco más sobre mi 😉, así que aquí va:"
+#: blog/templates/blog/about.html:43
+msgid "I've been working continuously in the software industry since late 2010. Over the years I've worked across many roles, technologies, and environments, but Python 🐍 has been the technology that's stayed with me the longest."
+msgstr "Trabajo de manera continua en la industria del software desde fines de 2010. Pasé por muchos roles, tecnologías y contextos distintos, pero Python 🐍 fue la tecnología que más me acompañó en el camino."
-#: blog/templates/blog/_about.html:44
-msgid "I'm Eduardo Enriquez, aka eduzen."
-msgstr "Soy Eduardo Enriquez, alias eduzen."
+#: blog/templates/blog/about.html:48
+msgid "I enjoy open source, teamwork, and solving interesting problems. I like reading, and I'm a naturally curious person. I think that's a good summary of who I am."
+msgstr "Me gusta el código abierto, el trabajo en equipo y resolver problemas interesantes. Me gusta leer y soy una persona curiosa. Creo que ese es un buen resumen de mí."
-#: blog/templates/blog/_about.html:45
+#: blog/templates/blog/about.html:53
#, python-format
-msgid ""
-"I've been working in the IT industry for quite a long time, %(years)s years "
-"and counting,mostly as a backend developer 💻."
-msgstr ""
-"He estado trabajando en la industria IT durante bastante tiempo, %(years)s "
-"años y contando, principalmente como desarrollador backend 💻."
+msgid "If you'd like to connect, feel free to send me an email and we can continue the conversation there."
+msgstr "Si tenés ganas de charlar, podés mandarme un mail y seguimos por ahí."
-#: blog/templates/blog/_about.html:46
-msgid "But I also have some experience working as a team leader."
-msgstr ""
-"Pero también tengo algo de experiencia trabajando como líder técnico de "
-"equipos."
+#: blog/templates/blog/about.html:85
+msgid "Beyond code"
+msgstr "Más allá del código"
-#: blog/templates/blog/_about.html:47
-msgid ""
-"Python 🐍, Django 🟩, and Flask are the main technologies 🧪 that I've been "
-"working with."
-msgstr ""
-" Python 🐍, Django 🟩 y Flask 🧪 son las principales tecnologías con las que "
-"trabajo."
+#: blog/templates/blog/about.html:91
+msgid "Some people find it weird that I have a bachelor's degree in philosophy from the University of Buenos Aires 🇦🇷. But I think that rational thinking is something that my profession and studies share."
+msgstr "Algunas personas encuentran extraño que tenga una licenciatura en filosofía de la Universidad de Buenos Aires 🇦🇷. Pero creo que el pensamiento racional es alguna de las cosas que comparten mi profesión y mis estudios."
-#: blog/templates/blog/_about.html:48
-msgid ""
-"Naturally, I have some experience 💡 with other things like Javascript, "
-"Docker 🐳, Redis 🟥, RabbitMQ 🐰, Celery 🌿, and Linux 🐧."
-msgstr ""
-"Naturalmente, tengo algo de experiencia 💡 con otras cosas como Javascript, "
-"Docker 🐳, Redis 🟥, RabbitMQ 🐰, Celery 🌿 y Linux 🐧."
+#: blog/templates/blog/about.html:92
+msgid "In general, philosophy has shaped my analytical thinking and fostered my curiosity. Some of my favorite philosophers are Nietzsche, Descartes, and Foucault."
+msgstr "En general, la filosofía ha moldeado mi pensamiento analítico y fomentado mi curiosidad. Algunos de mis filósofos favoritos son Nietzsche, Descartes y Foucault."
-#: blog/templates/blog/_about.html:51
-msgid "You can check my code at "
-msgstr "Puedes revisar mi código en "
+#: blog/templates/blog/about.html:97
+msgid "Teaching"
+msgstr "Enseñanza"
-#: blog/templates/blog/_about.html:52
-msgid "There you can find some bots like the one that I have for Telegram,"
-msgstr "Ahí puedes encontrar algunos bots como el que tengo para Telegram,"
+#: blog/templates/blog/about.html:99
+msgid "Last but not least, I'm passionate about teaching 👨🏽🏫. I think my background in philosophy has helped me to be a better teacher."
+msgstr "Por último, pero no menos importante, soy un apasionado de la enseñanza 👨🏽🏫. Creo que mi formación en filosofía me ha ayudado a ser un mejor profesor."
-#: blog/templates/blog/_about.html:54
-msgid "(you can talk to it following this link:"
-msgstr "(puedes hablar con él siguiendo este enlace:"
+#: blog/templates/blog/about.html:100
+msgid "I've been teaching in the past, and I'm looking forward to doing it more often in the IT field."
+msgstr "He estado enseñando en el pasado y espero hacerlo más a menudo en el campo de la tecnología."
-#: blog/templates/blog/_about.html:56
-msgid "Or you can find the source code of this website at"
-msgstr "O puedes encontrar el código fuente de este sitio web en"
+#: blog/templates/blog/about.html:105
+msgid "Interests"
+msgstr "Intereses"
-#: blog/templates/blog/_about.html:62
+#: blog/templates/blog/about.html:107
#, python-format
-msgid ""
-"Besides computers, I like good music, books, philosophy, movies, series, and "
-"good food. I started trying some mechanical keyboards (right now using a Leo "
-"pold 75 %%)! But I have also a Keychron K12."
-msgstr ""
-"Además de las computadoras, me gusta la buena música, los libros, la "
-"filosofía, las películas, las series y la buena comida. Comencé a probar "
-"algunos teclados mecánicos (¡ahora uso un Leo pold 75 %%)! Pero también "
-"tengo un Keychron K12."
+msgid "Besides computers, I like good music, books, philosophy, movies, series, and good food. I started trying some mechanical keyboards (right now using a Leo pold 75 %%)! But I have also a Keychron K12."
+msgstr "Además de las computadoras, me gusta la buena música, los libros, la filosofía, las películas, las series y la buena comida. Comencé a probar algunos teclados mecánicos (¡ahora uso un Leo pold 75 %%)! Pero también tengo un Keychron K12."
-#: blog/templates/blog/_about.html:65
-msgid ""
-"Some people find it weird that I have a bachelor's degree in philosophy from "
-"the University of Buenos Aires 🇦🇷. But I think that rational thinking is "
-"something that my profession and studies share."
-msgstr ""
-"Algunas personas encuentran extraño que tenga una licenciatura en filosofía "
-"de la Universidad de Buenos Aires 🇦🇷. Pero creo que el pensamiento racional "
-"es alguna de las cosas que comparten mi profesión y mis estudios."
-
-#: blog/templates/blog/_about.html:66
-msgid ""
-"In general, philosophy has shaped my analytical thinking and fostered my "
-"curiosity. Some of my favorite philosophers are Nietzsche, Descartes, and "
-"Foucault."
-msgstr ""
-"En general, la filosofía ha moldeado mi pensamiento analítico y fomentado mi "
-"curiosidad. Algunos de mis filósofos favoritos son Nietzsche, Descartes y "
-"Foucault."
-
-#: blog/templates/blog/_about.html:67
-msgid ""
-"Writers... many; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke, and "
-"many more..."
-msgstr ""
-"Escritores... muchos; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke "
-"y muchos más..."
-
-#: blog/templates/blog/_about.html:70
-msgid ""
-"Last but not least, I'm passionate about teaching 👨🏽🏫. I think my background "
-"in philosophy has helped me to be a better teacher."
-msgstr ""
-"Por último, pero no menos importante, soy un apasionado de la enseñanza 👨🏽🏫. "
-"Creo que mi formación en filosofía me ha ayudado a ser un mejor profesor."
-
-#: blog/templates/blog/_about.html:71
-msgid ""
-"I've been teaching in the past, and I'm looking forward to doing it more "
-"often in the IT field."
-msgstr ""
-"He estado enseñando en el pasado y espero hacerlo más a menudo en el campo "
-"de la tecnología."
-
-#: blog/templates/blog/_about.html:76
-msgid "If you want to contact me, you can do it through this "
-msgstr "Si quieres contactarme, puedes hacerlo a través de este "
+#: blog/templates/blog/about.html:108
+msgid "Writers... many; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke, and many more..."
+msgstr "Escritores... muchos; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke y muchos más..."
-#: blog/templates/blog/_about.html:82
-msgid "form"
-msgstr "formulario"
-
-#: blog/templates/blog/_about.html:84
-msgid "or through my "
-msgstr "o a través de mi "
-
-#: blog/templates/blog/_about.html:84
-msgid "LinkedIn."
-msgstr "LinkedIn."
+#: blog/templates/blog/about.html:122 blog/templates/blog/classes.html:139
+#: blog/templates/blog/mentoring.html:141
+msgid "Get in touch"
+msgstr "Contacto"
-#: blog/templates/blog/_classes.html:4
-#: blog/templates/blog/utils/nav_links.html:38
-#: blog/templates/blog/utils/nav_links_mobile.html:39
+#: blog/templates/blog/classes.html:13
msgid "Classes"
msgstr "Clases"
-#: blog/templates/blog/_classes.html:11
-msgid ""
-"Hello! Thank you for your interest 😊. My name is Eduardo and I'm a teacher. "
-"Learn more about me on my 'About' page: "
-msgstr ""
-"Hola! Gracias por tu interés 😊. Mi nombre es Eduardo y soy docente. Más "
-"sobre mi en mi página 'Acerca de mi':"
+#: blog/templates/blog/classes.html:20
+msgid "Unit Tests"
+msgstr "Tests Unitarios"
-#: blog/templates/blog/_classes.html:17 blog/templates/blog/_classes.html:38
-#: blog/templates/blog/_consultancy.html:50 blog/templates/blog/error.html:16
-msgid "here"
-msgstr "aquí"
+#: blog/templates/blog/classes.html:21
+msgid "Clean Code"
+msgstr "Código Limpio"
-#: blog/templates/blog/_classes.html:21
-msgid ""
-"My goal as a teacher is not just to impart knowledge, but to inspire and "
-"guide you in a way that you can lose me (and be independent) in your "
-"learning journey."
-msgstr ""
-"Mi objetivo como profesor no es solo impartir conocimiento, sino inspirar y "
-"guiarte de namera tal que puedas perderme (y ser independiente) en tu viaje "
-"de aprendizaje."
+#: blog/templates/blog/classes.html:23
+msgid "And more..."
+msgstr "Y más..."
-#: blog/templates/blog/_classes.html:24
-msgid ""
-"We can learn about: Python, or about web frameworks like Django, Flask, or "
-"FastAPI. We can also explore other topics like: object-oriented programming, "
-"unit tests, clean code or the one that you need."
-msgstr ""
-"Podemos aprender sobre: Python, o sobre frameworks web como Django, Flask o "
-"FastAPI. También podemos explorar otros temas como: programación orientada a "
-"objetos, pruebas unitarias, código limpio o el que necesites."
+#: blog/templates/blog/classes.html:30
+msgid "Hello! Thank you for your interest 😊. My name is Eduardo and I'm a teacher. Learn more about me on my 'About' page: "
+msgstr "Hola! Gracias por tu interés 😊. Mi nombre es Eduardo y soy docente. Más sobre mi en mi página 'Acerca de mi':"
-#: blog/templates/blog/_classes.html:27
-msgid ""
-"It's not easy to learn new things. It's hard also to find the motivation and "
-"the resources that are good for you. In these modern times, what we have is "
-"data 🗃️, data 🗃️ and data 🗃️, available everywhere."
-msgstr ""
-"No es fácil aprender cosas nuevas. También es difícil encontrar la "
-"motivación y los recursos que sean buenos para ti. En estos tiempos "
-"modernos, lo que tenemos es datos 🗃️, datos 🗃️ y más datos 🗃️, disponibles en "
-"todas partes."
+#: blog/templates/blog/classes.html:35 blog/templates/blog/classes.html:130
+#: blog/templates/blog/consultancy.html:62 blog/templates/blog/error.html:27
+msgid "here"
+msgstr "aquí"
-#: blog/templates/blog/_classes.html:28
-msgid ""
-"However, discerning the quality of this data can be challenging. That's "
-"where a guide or companion comes in handy 😉."
-msgstr ""
-"Sin embargo, discernir la calidad de estos datos puede ser un desafío. Ahí "
-"es donde un guía o compañero resulta útil 😉."
+#: blog/templates/blog/classes.html:38
+msgid "My goal as a teacher is not just to impart knowledge, but to inspire and guide you in a way that you can lose me (and be independent) in your learning journey."
+msgstr "Mi objetivo como profesor no es solo impartir conocimiento, sino inspirar y guiarte de namera tal que puedas perderme (y ser independiente) en tu viaje de aprendizaje."
-#: blog/templates/blog/_classes.html:29
-msgid ""
-"So I can help you to organize and curate the data and tell you what to use "
-"or not."
-msgstr ""
-"Así que puedo ayudarte a organizar y curar los datos y decirte qué usar o "
-"qué no."
+#: blog/templates/blog/classes.html:41
+msgid "We can learn about: Python, or about web frameworks like Django, Flask, or FastAPI. We can also explore other topics like: object-oriented programming, unit tests, clean code or the one that you need."
+msgstr "Podemos aprender sobre: Python, o sobre frameworks web como Django, Flask o FastAPI. También podemos explorar otros temas como: programación orientada a objetos, pruebas unitarias, código limpio o el que necesites."
-#: blog/templates/blog/_classes.html:32
-msgid "Reach out to me "
-msgstr "Contáctame"
+#: blog/templates/blog/classes.html:44
+msgid "It's not easy to learn new things. It's hard also to find the motivation and the resources that are good for you. In these modern times, what we have is data 🗃️, data 🗃️ and data 🗃️, available everywhere."
+msgstr "No es fácil aprender cosas nuevas. También es difícil encontrar la motivación y los recursos que sean buenos para ti. En estos tiempos modernos, lo que tenemos es datos 🗃️, datos 🗃️ y más datos 🗃️, disponibles en todas partes."
-#: blog/templates/blog/_classes.html:40
-msgid "or drop me an email at "
-msgstr "o envíame un correo a "
+#: blog/templates/blog/classes.html:45
+msgid "However, discerning the quality of this data can be challenging. That's where a guide or companion comes in handy 😉."
+msgstr "Sin embargo, discernir la calidad de estos datos puede ser un desafío. Ahí es donde un guía o compañero resulta útil 😉."
-#: blog/templates/blog/_classes.html:40
-msgid " and let's chat!"
-msgstr " y hablemos!"
+#: blog/templates/blog/classes.html:46
+msgid "So I can help you to organize and curate the data and tell you what to use or not."
+msgstr "Así que puedo ayudarte a organizar y curar los datos y decirte qué usar o qué no."
-#: blog/templates/blog/_classes.html:43
-msgid ""
-"If you're in the Netherlands 🇳🇱, let's schedule a coffee ☕ and chat 💬 about "
-"your learning objectives. If you're based elsewhere in the world 🌍, not to "
-"worry!"
-msgstr ""
-"Si estás en Holanda 🇳🇱, vamos por un café ☕ y hablemos 💬 sobre tus planes y "
-"objectivos. Si estás en otro lugar del mundo 🌍, no te preocupes!"
+#: blog/templates/blog/classes.html:49
+msgid "If you're in the Netherlands 🇳🇱, let's schedule a coffee ☕ and chat 💬 about your learning objectives. If you're based elsewhere in the world 🌍, not to worry!"
+msgstr "Si estás en Holanda 🇳🇱, vamos por un café ☕ y hablemos 💬 sobre tus planes y objectivos. Si estás en otro lugar del mundo 🌍, no te preocupes!"
-#: blog/templates/blog/_classes.html:44
-msgid ""
-"We can set up a Zoom or Meet call to discuss how I can assist you in your "
-"coding adventure."
-msgstr ""
-"Podemos organizar una call por Zoom o Meet para discutir cómo puedo "
-"asistirte en tu aventura de programación."
+#: blog/templates/blog/classes.html:50
+msgid "We can set up a Zoom or Meet call to discuss how I can assist you in your coding adventure."
+msgstr "Podemos organizar una call por Zoom o Meet para discutir cómo puedo asistirte en tu aventura de programación."
-#: blog/templates/blog/_classes.html:52
+#: blog/templates/blog/classes.html:56
msgid "Online Resources to Learn Python:"
msgstr "Recursos en línea para aprender Python:"
-#: blog/templates/blog/_classes.html:55
+#: blog/templates/blog/classes.html:58
msgid "Impossible not to recommend ChatGPT: "
msgstr "Imposible no recomendar ChatGPT: "
-#: blog/templates/blog/_classes.html:56
-msgid ""
-"I think it's one of the most important resources from our modern times. It's "
-"a great companion that could answer almost everything that you need in this "
-"field."
-msgstr ""
-"Creo que es uno de los recursos más importantes de nuestros tiempos "
-"modernos. Es un gran compañero que podría responder casi todo lo que "
-"necesitas en este campo."
+#: blog/templates/blog/classes.html:59
+msgid "I think it's one of the most important resources from our modern times. It's a great companion that could answer almost everything that you need in this field."
+msgstr "Creo que es uno de los recursos más importantes de nuestros tiempos modernos. Es un gran compañero que podría responder casi todo lo que necesitas en este campo."
-#: blog/templates/blog/_classes.html:57
-msgid ""
-"Certainly it's not infallible, it has its caveats and you need to learn how "
-"to use it. But it's worthy. I'm using it every day. "
-msgstr ""
-"Ciertamente no es infalible, tiene sus matices y necesitas aprender cómo "
-"usarlo. Pero vale la pena. Lo uso todos los días."
+#: blog/templates/blog/classes.html:60
+msgid "Certainly it's not infallible, it has its caveats and you need to learn how to use it. But it's worthy. I'm using it every day. "
+msgstr "Ciertamente no es infalible, tiene sus matices y necesitas aprender cómo usarlo. Pero vale la pena. Lo uso todos los días."
-#: blog/templates/blog/_classes.html:60
+#: blog/templates/blog/classes.html:63
msgid "I also recommend the following resources:"
msgstr "También recomiendo los siguientes recursos:"
-#: blog/templates/blog/_classes.html:65
+#: blog/templates/blog/classes.html:68
msgid "Python: official tutorial"
msgstr "Python: tutorial oficial"
-#: blog/templates/blog/_classes.html:70
-msgid ""
-"Django girls tutorial: broad tutorial including basic internet and python "
-"concepts"
-msgstr ""
-"Django girls tutorial: tutorial amplio que incluye conceptos básicos de "
-"internet y python"
+#: blog/templates/blog/classes.html:72
+msgid "Django girls tutorial: broad tutorial including basic internet and python concepts"
+msgstr "Django girls tutorial: tutorial amplio que incluye conceptos básicos de internet y python"
-#: blog/templates/blog/_classes.html:75
+#: blog/templates/blog/classes.html:76
msgid "Codecademy: free course for learning the basics of Python 3"
-msgstr ""
-"Codecademy: curso gratuito para aprender los conceptos básicos de Python 3"
+msgstr "Codecademy: curso gratuito para aprender los conceptos básicos de Python 3"
-#: blog/templates/blog/_classes.html:80
+#: blog/templates/blog/classes.html:83
msgid "Some recommended books:"
msgstr "Algunos libros recomendados:"
-#: blog/templates/blog/_classes.html:84
+#: blog/templates/blog/classes.html:86 blog/templates/blog/mentoring.html:114
msgid "Beginners"
msgstr "Principiantes"
-#: blog/templates/blog/_classes.html:92
+#: blog/templates/blog/classes.html:103
msgid "Medium/Advance"
msgstr "Medio/Avanzado"
-#: blog/templates/blog/_consultancy.html:4
+#: blog/templates/blog/classes.html:125
+msgid "Reach out to me "
+msgstr "Contáctame"
+
+#: blog/templates/blog/classes.html:131
+msgid "or drop me an email at "
+msgstr "o envíame un correo a "
+
+#: blog/templates/blog/classes.html:131
+msgid " and let's chat!"
+msgstr " y hablemos!"
+
+#: blog/templates/blog/consultancy.html:11
msgid "Consultancy Services"
msgstr "Servicios de Consultoria"
-#: blog/templates/blog/_consultancy.html:9
-msgid ""
-"Crafting tech magic 🧙🏼♀️ for individuals 🧍🏻♀️ and businesses 🏭, with a "
-"sprinkle of fun and a dollop of expertise."
-msgstr ""
-"Creando magia tecnológica 🧙🏼♀️ para individuos 🧍🏻♀️ y empresas 🏭, con un toque "
-"de diversión y una pizca de experiencia."
+#: blog/templates/blog/consultancy.html:15
+msgid "Crafting tech magic 🧙🏼♀️ for individuals 🧍🏻♀️ and businesses 🏭, with a sprinkle of fun and a dollop of expertise."
+msgstr "Creando magia tecnológica 🧙🏼♀️ para individuos 🧍🏻♀️ y empresas 🏭, con un toque de diversión y una pizca de experiencia."
-#: blog/templates/blog/_consultancy.html:10
+#: blog/templates/blog/consultancy.html:16
msgid "Let's code something delightful!"
msgstr "Codeemos algo flashero!"
-#: blog/templates/blog/_consultancy.html:11
-msgid ""
-"With over 10 years in the industry 👴🏿, I offer useful insights and expertise "
-"for daily challenges."
-msgstr ""
-"Con más de 10 años en la industria 👴🏿, ofrezco información útil y "
-"experiencia para los desafíos diarios."
+#: blog/templates/blog/consultancy.html:17
+msgid "With over 10 years in the industry 👴🏿, I offer useful insights and expertise for daily challenges."
+msgstr "Con más de 10 años en la industria 👴🏿, ofrezco información útil y experiencia para los desafíos diarios."
-#: blog/templates/blog/_consultancy.html:12
+#: blog/templates/blog/consultancy.html:18
msgid "Remote 💻 or in-person 🪑, I'm here to assist."
msgstr "Remoto 💻 o en persona 🪑, estoy acá para ayudarte."
-#: blog/templates/blog/_consultancy.html:13
+#: blog/templates/blog/consultancy.html:19
msgid "Interested in my professional journey?"
msgstr "¿Interesado en mi trayectoria profesional?"
-#: blog/templates/blog/_consultancy.html:14
+#: blog/templates/blog/consultancy.html:20
msgid "Check out my"
msgstr "Revisa mi"
-#: blog/templates/blog/_consultancy.html:14
+#: blog/templates/blog/consultancy.html:20
msgid "LinkedIn profile"
msgstr "profile de LinkedIn."
-#: blog/templates/blog/_consultancy.html:18
+#: blog/templates/blog/consultancy.html:27
msgid "Services"
msgstr "Servicios"
-#: blog/templates/blog/_consultancy.html:22
+#: blog/templates/blog/consultancy.html:31
msgid "For the Rising Tech Stars: Individuals"
msgstr "Para las estrellas tecnológicas en ascenso"
-#: blog/templates/blog/_consultancy.html:24
-msgid ""
-"Personalized training 🏋🏼♂️, classes 👨🏽🏫, and tutoring 🤓 to help you blossom "
-"into an autonomous developer."
-msgstr ""
-"Capacitación personalizada 🏋🏼♂️, clases 👨🏽🏫 y tutoría 🤓 para ayudarte a "
-"convertirte en un desarrollador autónomo."
+#: blog/templates/blog/consultancy.html:33
+msgid "Personalized training 🏋🏼♂️, classes 👨🏽🏫, and tutoring 🤓 to help you blossom into an autonomous developer."
+msgstr "Capacitación personalizada 🏋🏼♂️, clases 👨🏽🏫 y tutoría 🤓 para ayudarte a convertirte en un desarrollador autónomo."
-#: blog/templates/blog/_consultancy.html:25
+#: blog/templates/blog/consultancy.html:34
msgid "Stuck on a bug 🐛? I've got your back, literally!"
msgstr "¿Atrapado en un bug 🐛? Acá estamos para debuggearlo juntos!"
-#: blog/templates/blog/_consultancy.html:30
+#: blog/templates/blog/consultancy.html:39
msgid "For the Business: Companies"
msgstr "Para las empresas"
-#: blog/templates/blog/_consultancy.html:32
-msgid ""
-"Crafting day-to-day solutions, providing stellar training (unittesting, "
-"robust code writing, you name it!), fixing Django/Python 🐍 performance "
-"issues, evaluating legacy code 🔖, or upgrading versions ⬆️."
-msgstr ""
-"Elaborando soluciones cotidianas, brindando capacitación estelar "
-"(unittesting, escritura de código robusto, ¡lo que necesites!), solucionando "
-"problemas de performanceen Django/Python 🐍, evaluando código legacy "
-"(heredado) 🔖, o actualizando versiones ⬆️."
+#: blog/templates/blog/consultancy.html:41
+msgid "Crafting day-to-day solutions, providing stellar training (unittesting, robust code writing, you name it!), fixing Django/Python 🐍 performance issues, evaluating legacy code 🔖, or upgrading versions ⬆️."
+msgstr "Elaborando soluciones cotidianas, brindando capacitación estelar (unittesting, escritura de código robusto, ¡lo que necesites!), solucionando problemas de performanceen Django/Python 🐍, evaluando código legacy (heredado) 🔖, o actualizando versiones ⬆️."
-#: blog/templates/blog/_consultancy.html:33
+#: blog/templates/blog/consultancy.html:42
msgid "If it's tech, I'm your guy!"
msgstr "Si es tecnología, soy yo!"
-#: blog/templates/blog/_consultancy.html:41
-msgid "Experience & Skills"
-msgstr "Experiencia & Habilidades"
+#: blog/templates/blog/consultancy.html:52
+msgid "Experience & Skills"
+msgstr "Experiencia & Habilidades"
-#: blog/templates/blog/_consultancy.html:44
-msgid "Years of Mischief & Mastery"
-msgstr "Años de Travesuras & Maestría"
+#: blog/templates/blog/consultancy.html:56
+msgid "Years of Mischief & Mastery"
+msgstr "Años de Travesuras & Maestría"
-#: blog/templates/blog/_consultancy.html:46
-msgid ""
-"Code wizardry 🧙🏼♂️, business acumen 👨🏻💼, and maybe a few harmless pranks "
-"along the way. Dive into my tech journey!"
-msgstr ""
-"Magia de código 🧙🏼♂️, perspicacia empresarial 👨🏻💼 y quizás algunas bromas "
-"inofensivas en el camino. ¡Sumérgete en mi trayectoria tecnológica!"
+#: blog/templates/blog/consultancy.html:58
+msgid "Code wizardry 🧙🏼♂️, business acumen 👨🏻💼, and maybe a few harmless pranks along the way. Dive into my tech journey!"
+msgstr "Magia de código 🧙🏼♂️, perspicacia empresarial 👨🏻💼 y quizás algunas bromas inofensivas en el camino. ¡Sumérgete en mi trayectoria tecnológica!"
-#: blog/templates/blog/_consultancy.html:49
+#: blog/templates/blog/consultancy.html:61
msgid "Read more about my experience on linkedin "
msgstr "Lee más sobre mí experiencia en linkedin "
-#: blog/templates/blog/_consultancy.html:54
+#: blog/templates/blog/consultancy.html:67
msgid "Techno-Sorcery"
msgstr "Hechicería Tecnológica"
-#: blog/templates/blog/_consultancy.html:56
-msgid ""
-"From Python 🐍 to Django, from debugging to spellbinding code – I've mastered "
-"the digital alchemy ⚗️."
-msgstr ""
-"Desde Python 🐍 a Django, desde depuración hasta código encantador: he "
-"dominado la alquimia digital ⚗️."
+#: blog/templates/blog/consultancy.html:69
+msgid "From Python 🐍 to Django, from debugging to spellbinding code – I've mastered the digital alchemy ⚗️."
+msgstr "Desde Python 🐍 a Django, desde depuración hasta código encantador: he dominado la alquimia digital ⚗️."
-#: blog/templates/blog/_consultancy.html:59
+#: blog/templates/blog/consultancy.html:72
msgid "Read more about me here: "
msgstr "Lee más sobre mí aquí:"
-#: blog/templates/blog/_consultancy.html:60
+#: blog/templates/blog/consultancy.html:77
msgid "about"
msgstr "acerca"
-#: blog/templates/blog/_consultancy.html:68
+#: blog/templates/blog/consultancy.html:87 blog/templates/blog/contact.html:11
msgid "Get in Touch"
msgstr "Ponte en Contacto"
-#: blog/templates/blog/_consultancy.html:70
-msgid ""
-"Ready to embark on a tech adventure or brew up a business solution? Let's "
-"talk!"
+#: blog/templates/blog/consultancy.html:88
+msgid "Let's talk"
msgstr ""
-"¿Listo para embarcarte en una aventura tecnológica o elaborar una solución "
-"empresarial? ¡Hablemos!"
-#: blog/templates/blog/_consultancy.html:78
+#: blog/templates/blog/consultancy.html:90
+msgid "Ready to embark on a tech adventure or brew up a business solution? Let's talk!"
+msgstr "¿Listo para embarcarte en una aventura tecnológica o elaborar una solución empresarial? ¡Hablemos!"
+
+#: blog/templates/blog/consultancy.html:98
msgid "Contact Me"
msgstr "Contactame"
-#: blog/templates/blog/_contact.html:4 blog/templates/blog/success.html:5
-#: blog/templates/blog/utils/nav_links.html:64
-#: blog/templates/blog/utils/nav_links_mobile.html:65
-msgid "Contact"
-msgstr "Contacto"
+#: blog/templates/blog/contact.html:14
+msgid "Have a project idea, a question, or just want to say hello? I'd love to hear from you. Fill out the form or reach me through any of the channels below."
+msgstr ""
+
+#: blog/templates/blog/contact.html:24
+msgid "Let's connect"
+msgstr ""
-#: blog/templates/blog/_contact.html:14
-msgid "Are you sure?"
-msgstr "Estas seguro?"
+#: blog/templates/blog/contact.html:61
+msgid "Based in Amsterdam, but always happy to collaborate across time zones."
+msgstr ""
-#: blog/templates/blog/error.html:7
+#: blog/templates/blog/error.html:13
msgid "Try again"
msgstr "Intente de nuevo"
-#: blog/templates/blog/error.html:11
-msgid "Ups... something went wrong. 🙃"
-msgstr "Ups... algo salio mal. 🙃"
+#: blog/templates/blog/error.html:17
+msgid "Ups... something went wrong."
+msgstr "Ups... algo salió mal."
-#: blog/templates/blog/error.html:14
+#: blog/templates/blog/error.html:21
msgid "Please try again later... or contact me"
msgstr "Por favor intente mas tarde... o contactame"
@@ -551,65 +400,190 @@ msgid "First"
msgstr "Primer"
#: blog/templates/blog/extras/paginator.html:6
-#: blog/templates/blog/posts/_related_posts.html:13
+#: blog/templates/blog/posts/related_posts.html:21
msgid "Previous"
msgstr "Anterior"
-#: blog/templates/blog/extras/paginator.html:19
-#: blog/templates/blog/posts/_related_posts.html:38
+#: blog/templates/blog/extras/paginator.html:21
+#: blog/templates/blog/posts/related_posts.html:50
msgid "Next"
msgstr "Siguiente"
-#: blog/templates/blog/extras/paginator.html:20
+#: blog/templates/blog/extras/paginator.html:22
msgid "Last"
msgstr "Ultimo"
-#: blog/templates/blog/home.html:17
-msgid "Software Engineer"
-msgstr "Software Engineer"
+#: blog/templates/blog/home.html:18
+msgid "Philosophy graduate turned software engineer."
+msgstr "Licenciado en filosofía devenido ingeniero de software."
+
+#: blog/templates/blog/home.html:26
+#, python-format
+msgid "For over a decade I've worked primarily with Python and JavaScript. Today I lead teams, but I still get my hands dirty with code. I enjoy thinking, teaching, and building things. If you have a project to work on together, a question, or just want to get in touch, you can reach me at %(email_link)s."
+msgstr "Desde hace más de una década trabajo principalmente con Python y Javascript. Hoy lidero equipos, pero sigo metiendo manos en el código. Me gusta pensar, enseñar y construir cosas. Si tenés algún proyecto para trabajar en conjunto, o simplemente una pregunta o ponerte en contacto podés escribirme a %(email_link)s."
+
+#: blog/templates/blog/mentoring.html:19
+msgid "Career Growth"
+msgstr "Crecimiento Profesional"
+
+#: blog/templates/blog/mentoring.html:20
+msgid "Goal Setting"
+msgstr "Definir Objetivos"
+
+#: blog/templates/blog/mentoring.html:21
+msgid "Your Pace"
+msgstr "Tu Ritmo"
+
+#: blog/templates/blog/mentoring.html:28
+msgid "Mentoring is not about giving you the answers. It's about helping you find them yourself, and building the confidence to keep finding them long after our sessions end."
+msgstr "Mentoría no es darte las respuestas. Es ayudarte a encontrarlas vos mismo, y construir la confianza para seguir encontrándolas mucho después de que terminen nuestras sesiones."
+
+#: blog/templates/blog/mentoring.html:31
+msgid "I studied philosophy before becoming a software engineer, and that shaped how I think about teaching. I believe in asking the right questions, understanding the 'why' behind things, and developing a way of thinking that goes beyond memorizing syntax."
+msgstr "Estudié filosofía antes de ser ingeniero de software, y eso formó mi manera de pensar sobre la enseñanza. Creo en hacer las preguntas correctas, entender el 'por qué' detrás de las cosas, y desarrollar una forma de pensar que va más allá de memorizar sintaxis."
+
+#: blog/templates/blog/mentoring.html:34
+msgid "Whether you're starting your first steps in programming, preparing for a career change, or looking to level up as a developer — I can be your guide. Not a guru, not a professor. A companion in your learning journey."
+msgstr "Ya sea que estés dando tus primeros pasos en programación, preparándote para un cambio de carrera, o buscando crecer como developer — puedo ser tu guía. No un gurú, no un profesor. Un compañero en tu camino de aprendizaje."
+
+#: blog/templates/blog/mentoring.html:40
+msgid "What we can work on"
+msgstr "En qué podemos trabajar"
+
+#: blog/templates/blog/mentoring.html:44
+msgid "Code Review"
+msgstr "Revisión de Código"
+
+#: blog/templates/blog/mentoring.html:46
+msgid "Bring your code and let's look at it together. I'll help you understand patterns, spot issues, and write cleaner, more maintainable software. We learn best from real code."
+msgstr "Traé tu código y mirémoslo juntos. Te voy a ayudar a entender patrones, detectar problemas y escribir software más limpio y mantenible. Se aprende mejor con código real."
+
+#: blog/templates/blog/mentoring.html:51
+msgid "Career Navigation"
+msgstr "Navegación de Carrera"
-#: blog/templates/blog/home.html:24 blog/templates/blog/utils/nav_links.html:25
-#: blog/templates/blog/utils/nav_links_mobile.html:26
-msgid "Consultancy"
-msgstr "Consultoria"
+#: blog/templates/blog/mentoring.html:53
+msgid "The tech industry can be overwhelming. Whether it's preparing for interviews, choosing the right path, or understanding what companies actually look for — I've been there and I can help."
+msgstr "La industria tech puede ser abrumadora. Ya sea prepararte para entrevistas, elegir el camino correcto o entender qué buscan realmente las empresas — estuve ahí y puedo ayudarte."
-#: blog/templates/blog/home.html:29
-msgid "Based in Amsterdam"
-msgstr "En Amsterdam"
+#: blog/templates/blog/mentoring.html:58
+msgid "Pair Programming"
+msgstr "Pair Programming"
-#: blog/templates/blog/home.html:29
-msgid "available"
-msgstr "pero disponible"
+#: blog/templates/blog/mentoring.html:60
+msgid "There's no better way to learn than building something together. We'll work on real problems side by side, and you'll pick up practices and habits that no tutorial can teach."
+msgstr "No hay mejor forma de aprender que construir algo juntos. Vamos a trabajar en problemas reales codo a codo, y vas a incorporar prácticas y hábitos que ningún tutorial puede enseñar."
-#: blog/templates/blog/home.html:31
-msgid "everywhere!"
-msgstr "en cualquier lugar!"
+#: blog/templates/blog/mentoring.html:65
+msgid "Learning Path"
+msgstr "Ruta de Aprendizaje"
-#: blog/templates/blog/posts/_detail.html:15
+#: blog/templates/blog/mentoring.html:67
+msgid "Feeling lost in the ocean of resources? I'll help you build a personalized roadmap based on where you are now and where you want to go. No generic advice — just what works for you."
+msgstr "¿Te sentís perdido en el océano de recursos? Te ayudo a construir una hoja de ruta personalizada basada en dónde estás ahora y a dónde querés llegar. Nada de consejos genéricos — solo lo que funciona para vos."
+
+#: blog/templates/blog/mentoring.html:75
+msgid "How it works"
+msgstr "Cómo funciona"
+
+#: blog/templates/blog/mentoring.html:80
+msgid "Intro call"
+msgstr "Llamada introductoria"
+
+#: blog/templates/blog/mentoring.html:81
+msgid "A free, informal chat where we get to know each other and talk about your goals. No commitment."
+msgstr "Una charla gratuita e informal donde nos conocemos y hablamos de tus objetivos. Sin compromiso."
+
+#: blog/templates/blog/mentoring.html:87
+msgid "Personalized plan"
+msgstr "Plan personalizado"
+
+#: blog/templates/blog/mentoring.html:88
+msgid "Based on our conversation, I'll put together a plan tailored to your level, interests, and available time."
+msgstr "Basándome en nuestra conversación, armo un plan adaptado a tu nivel, intereses y tiempo disponible."
+
+#: blog/templates/blog/mentoring.html:94
+msgid "Regular sessions"
+msgstr "Sesiones regulares"
+
+#: blog/templates/blog/mentoring.html:95
+msgid "Weekly or biweekly — whatever fits your rhythm. Remote via Zoom/Meet, or in person if you're in Amsterdam."
+msgstr "Semanales o quincenales — lo que se adapte a tu ritmo. Remoto por Zoom/Meet, o presencial si estás en Ámsterdam."
+
+#: blog/templates/blog/mentoring.html:101
+msgid "Async support"
+msgstr "Soporte asincrónico"
+
+#: blog/templates/blog/mentoring.html:102
+msgid "Questions between sessions? I'm available via chat. Sometimes a quick pointer saves hours of frustration."
+msgstr "¿Preguntas entre sesiones? Estoy disponible por chat. A veces una orientación rápida ahorra horas de frustración."
+
+#: blog/templates/blog/mentoring.html:110
+msgid "Who is this for"
+msgstr "Para quién es"
+
+#: blog/templates/blog/mentoring.html:115
+msgid "You're curious about programming and want to start on the right foot, with good habits from day one."
+msgstr "Tenés curiosidad por la programación y querés empezar con el pie derecho, con buenos hábitos desde el día uno."
+
+#: blog/templates/blog/mentoring.html:119
+msgid "Career Switchers"
+msgstr "Cambio de Carrera"
+
+#: blog/templates/blog/mentoring.html:120
+msgid "You're making the leap into tech from another field. I can help you navigate the transition with clarity."
+msgstr "Estás dando el salto a tech desde otro campo. Puedo ayudarte a navegar la transición con claridad."
+
+#: blog/templates/blog/mentoring.html:124
+msgid "Growing Developers"
+msgstr "Developers en Crecimiento"
+
+#: blog/templates/blog/mentoring.html:125
+msgid "You already code but want to get better — write cleaner code, understand architecture, prepare for senior roles."
+msgstr "Ya programás pero querés mejorar — escribir código más limpio, entender arquitectura, prepararte para roles senior."
+
+#: blog/templates/blog/mentoring.html:133
+msgid "Interested? Let's start with a conversation."
+msgstr "¿Te interesa? Empecemos con una conversación."
+
+#: blog/templates/blog/posts/detail.html:19
msgid "Back to Post List"
msgstr "Volver a la lista de Posts"
-#: blog/templates/blog/posts/_detail.html:28
+#: blog/templates/blog/posts/detail.html:28
msgid "Author"
msgstr "Autor"
-#: blog/templates/blog/posts/_list.html:9
+#: blog/templates/blog/posts/detail.html:42
+#: blog/templates/blog/posts/related_posts.html:4
+msgid "Related Posts"
+msgstr ""
+
+#: blog/templates/blog/posts/list.html:10
+msgid "Things I Think About"
+msgstr ""
+
+#: blog/templates/blog/posts/list.html:16
msgid "or just public notes"
msgstr "o simplemente notas públicas"
-#: blog/templates/blog/posts/_list.html:48
+#: blog/templates/blog/posts/list.html:37
msgid "We could not find what you are looking for..."
msgstr "No pudimos encontrar lo que buscas..."
-#: blog/templates/blog/posts/_list.html:49
+#: blog/templates/blog/posts/list.html:38
msgid "Maybe you can search another for thing?"
msgstr "Quizás puedas buscar otra cosa?"
-#: blog/templates/blog/posts/_list.html:50
+#: blog/templates/blog/posts/list.html:41
msgid "Search"
msgstr "Busqueda"
-#: blog/templates/blog/search.html:8
+#: blog/templates/blog/posts/related_posts.html:37
+msgid "Read more"
+msgstr ""
+
+#: blog/templates/blog/search.html:6
msgid "Advance Search"
msgstr "Busqueda avanzada"
@@ -621,33 +595,131 @@ msgstr "No hay ningun resultado 😞"
msgid "How-to-look"
msgstr "Por favor 🙏 realize de nuevo la búsqueda!"
-#: blog/templates/blog/success.html:8
-msgid "Thank you for your message"
-msgstr "Gracias por tu mensaje"
+#: blog/templates/blog/success.html:7
+msgid "Message Sent"
+msgstr "Mensaje Enviado"
#: blog/templates/blog/success.html:11
-msgid "We are going to reply you soon!"
-msgstr "Te responderemos pronto!"
-
-#: blog/templates/blog/utils/footer.html:7
-msgid "Made with 💜 by Eduardo Enriquez"
-msgstr "Hecho con 💜 por Eduardo Enriquez"
-
-#: blog/templates/blog/utils/head.html:9
-msgid "description"
-msgstr "descripcion"
-
-#: blog/templates/blog/utils/nav_links.html:12
-#: blog/templates/blog/utils/nav_links_mobile.html:13
-msgid "Blog"
-msgstr "Blog"
-
-#: blog/templates/blog/utils/nav_links.html:51
-#: blog/templates/blog/utils/nav_links_mobile.html:52
-msgid "About"
-msgstr "Acerca"
-
-#: blog/templates/blog/utils/nav_links.html:69
-#: blog/templates/blog/utils/nav_links_mobile.html:69
-msgid "Admin"
-msgstr "Admin"
+msgid "Thank you"
+msgstr ""
+
+#: blog/templates/blog/success.html:14
+msgid "Your message is on its way. I'll get back to you as soon as I can."
+msgstr ""
+
+#: blog/templates/blog/success.html:21
+msgid "Back to home"
+msgstr "Volver al inicio"
+
+#~ msgid "Hello World! My name is Eduardo and I'm a developer 💻."
+#~ msgstr "¡Hola Mundo! Mi nombre es Eduardo y soy un developer 💻."
+
+#, python-format
+#~ msgid "I've been working ⛏️ with Python 🐍 for the last %(years)s years, most of the time working as a backend developer with Django."
+#~ msgstr "He estado trabajando ⛏️ con Python 🐍 durante los últimos %(years)s años, mayormente como desarrollador backend con Django."
+
+#~ msgid "Currently living in"
+#~ msgstr "Actualmente vivo en"
+
+#~ msgid "Buenos Aires"
+#~ msgstr "Buenos Aires"
+
+#~ msgid "München"
+#~ msgstr "Munich"
+
+#~ msgid "Amsterdam"
+#~ msgstr "Ámsterdam"
+
+#~ msgid "while working from home."
+#~ msgstr "mientras trabajo desde mi casa."
+
+#~ msgid "I'm Eduardo Enriquez, aka eduzen."
+#~ msgstr "Soy Eduardo Enriquez, alias eduzen."
+
+#, python-format
+#~ msgid "I've been working in the IT industry for quite a long time, %(years)s years and counting, mostly as a backend developer 💻."
+#~ msgstr "He estado trabajando en la industria IT durante bastante tiempo, %(years)s años y contando, principalmente como desarrollador backend 💻."
+
+#~ msgid "But I also have some experience working as a team leader."
+#~ msgstr "Pero también tengo algo de experiencia trabajando como líder técnico de equipos."
+
+#~ msgid "Python 🐍, Django 🟩, and Flask are the main technologies 🧪 that I've been working with."
+#~ msgstr " Python 🐍, Django 🟩 y Flask 🧪 son las principales tecnologías con las que trabajo."
+
+#~ msgid "Naturally, I have some experience 💡 with other things like Javascript, Docker 🐳, Redis 🟥, RabbitMQ 🐰, Celery 🌿, and Linux 🐧."
+#~ msgstr "Naturalmente, tengo algo de experiencia 💡 con otras cosas como Javascript, Docker 🐳, Redis 🟥, RabbitMQ 🐰, Celery 🌿 y Linux 🐧."
+
+#~ msgid "You can check my code at "
+#~ msgstr "Puedes revisar mi código en "
+
+#~ msgid "There you can find some bots like the one that I have for Telegram,"
+#~ msgstr "Ahí puedes encontrar algunos bots como el que tengo para Telegram,"
+
+#~ msgid "(you can talk to it following this link:"
+#~ msgstr "(puedes hablar con él siguiendo este enlace:"
+
+#~ msgid "Or you can find the source code of this website at"
+#~ msgstr "O puedes encontrar el código fuente de este sitio web en"
+
+#~ msgid "If you want to contact me, you can do it through this "
+#~ msgstr "Si quieres contactarme, puedes hacerlo a través de este "
+
+#~ msgid "form"
+#~ msgstr "formulario"
+
+#~ msgid "or through my "
+#~ msgstr "o a través de mi "
+
+#~ msgid "LinkedIn."
+#~ msgstr "LinkedIn."
+
+#~ msgid "About me"
+#~ msgstr "Acerca de mi"
+
+#~ msgid "Click to read the long version..."
+#~ msgstr "Clic para leer la versión extendida..."
+
+#~ msgid "A bit more about me 😉, so here it goes:"
+#~ msgstr "Un poco más sobre mi 😉, así que aquí va:"
+
+#~ msgid "Contact"
+#~ msgstr "Contacto"
+
+#~ msgid "Are you sure?"
+#~ msgstr "Estas seguro?"
+
+#~ msgid "I studied philosophy at the University of Buenos Aires, where I wrote my thesis on Nietzsche, though computers had already been part of my life since attending a programming-oriented high school."
+#~ msgstr "Estudié filosofía en la Universidad de Buenos Aires, donde escribí mi tesis sobre Nietzsche. Las computadoras ya venían siendo parte de mi vida desde que fui a un secundario con orientación en programación."
+
+#~ msgid "Thank you for your message"
+#~ msgstr "Gracias por tu mensaje"
+
+#~ msgid "We are going to reply you soon!"
+#~ msgstr "Te responderemos pronto!"
+
+#~ msgid "Consultancy"
+#~ msgstr "Consultoria"
+
+#~ msgid "Based in Amsterdam"
+#~ msgstr "En Amsterdam"
+
+#~ msgid "available"
+#~ msgstr "pero disponible"
+
+#~ msgid "everywhere!"
+#~ msgstr "en cualquier lugar!"
+
+#~ msgid "Made with 💜 by Eduardo Enriquez"
+#~ msgstr "Hecho con 💜 por Eduardo Enriquez"
+
+#~ msgid "description"
+#~ msgstr "descripcion"
+
+#~ msgid "Blog"
+#~ msgstr "Blog"
+
+#~ msgid "About"
+#~ msgstr "Acerca"
+
+#~ msgid "Admin"
+#~ msgstr "Admin"
diff --git a/blog/migrations/0009_post_search_vector.py b/blog/migrations/0009_post_search_vector.py
new file mode 100644
index 00000000..8a3a11e4
--- /dev/null
+++ b/blog/migrations/0009_post_search_vector.py
@@ -0,0 +1,61 @@
+# Generated manually — adds SearchVectorField + GIN index for fast full-text search.
+# Both the GIN index creation and the back-fill are PostgreSQL-only and are
+# skipped silently on SQLite (used in the test suite).
+
+from django.apps.registry import Apps
+from django.contrib.postgres.search import SearchVector, SearchVectorField
+from django.db import migrations
+from django.db.backends.base.schema import BaseDatabaseSchemaEditor
+
+
+def add_gin_index(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ """Create the GIN index only on PostgreSQL — SQLite has no such index type."""
+ if schema_editor.connection.vendor != "postgresql":
+ return
+ schema_editor.execute("CREATE INDEX IF NOT EXISTS post_search_vector_gin_idx ON blog_post USING gin(search_vector)")
+
+
+def drop_gin_index(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ if schema_editor.connection.vendor != "postgresql":
+ return
+ schema_editor.execute("DROP INDEX IF EXISTS post_search_vector_gin_idx")
+
+
+def populate_search_vector(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ """Back-fill search_vector for all existing posts in a single UPDATE.
+
+ Skipped on non-PostgreSQL backends (e.g. SQLite in the test suite) because
+ ``to_tsvector`` is a PostgreSQL-only function.
+ """
+ if schema_editor.connection.vendor != "postgresql":
+ return
+
+ Post = apps.get_model("blog", "Post")
+ Post.objects.update(
+ search_vector=(
+ SearchVector("title", weight="A") + SearchVector("summary", weight="B") + SearchVector("text", weight="C")
+ )
+ )
+
+
+def noop(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ del apps, schema_editor
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("blog", "0008_post_post_published_date_idx_and_more"),
+ ]
+
+ operations = [
+ # 1. Add the nullable column — works on every backend.
+ migrations.AddField(
+ model_name="post",
+ name="search_vector",
+ field=SearchVectorField(blank=True, null=True),
+ ),
+ # 2. Create GIN index — PostgreSQL only; skipped on SQLite.
+ migrations.RunPython(add_gin_index, reverse_code=drop_gin_index),
+ # 3. Back-fill existing rows — PostgreSQL only; skipped on SQLite.
+ migrations.RunPython(populate_search_vector, reverse_code=noop),
+ ]
diff --git a/blog/models.py b/blog/models.py
index 0d801cce..56dc4bb2 100644
--- a/blog/models.py
+++ b/blog/models.py
@@ -1,4 +1,5 @@
from ckeditor_uploader.fields import RichTextUploadingField # type: ignore
+from django.contrib.postgres.search import SearchVectorField
from django.db import models
from django.db.models import Count
from django.urls import reverse
@@ -16,18 +17,17 @@ class Meta:
verbose_name = _("tag")
verbose_name_plural = _("tags")
- def __str__(self):
+ def __str__(self) -> str:
return self.slug or "-"
class PostQuerySet(models.QuerySet):
- def published(self):
+ def published(self) -> PostQuerySet:
return self.filter(published_date__isnull=False).prefetch_related("tags")
- def count_tags(self):
+ def count_tags(self) -> models.QuerySet:
return (
- self.published()
- .only("tags__slug")
+ self.filter(published_date__isnull=False)
.values("tags__slug")
.annotate(total=Count("tags__slug"))
.order_by("-total")
@@ -48,6 +48,8 @@ class Post(models.Model):
image = models.ImageField(upload_to="post-img/%Y/%m/%d", blank=True, null=True)
cropping = ImageRatioField("image", "260x120")
+ search_vector = SearchVectorField(null=True, blank=True)
+
objects = PostQuerySet.as_manager()
def publish(self) -> None:
@@ -56,12 +58,12 @@ def publish(self) -> None:
@property
def published(self) -> bool:
- return True if self.published_date else False
+ return bool(self.published_date)
def get_absolute_url(self) -> str:
return reverse("post_detail", args=[self.slug])
- def __str__(self):
+ def __str__(self) -> str:
return self.slug or "-"
class Meta:
@@ -75,4 +77,7 @@ class Meta:
models.Index(fields=["-created_date"], name="post_created_date_idx"),
# For filtering by author
models.Index(fields=["author"], name="post_author_idx"),
+ # NOTE: the GIN index on search_vector is created via RunPython in migration
+ # 0009 (PostgreSQL-only) and is intentionally not listed here so that
+ # makemigrations doesn't try to manage it via AddIndex on all backends.
]
diff --git a/blog/services/captcha.py b/blog/services/captcha.py
index 30b1a92d..19c4e4ce 100644
--- a/blog/services/captcha.py
+++ b/blog/services/captcha.py
@@ -13,6 +13,4 @@ def verify_captcha(user_answer: str) -> bool:
False otherwise.
"""
correct_answer = ("rojo", "red")
- if user_answer and user_answer.strip().lower() in correct_answer:
- return True
- return False
+ return bool(user_answer and user_answer.strip().lower() in correct_answer)
diff --git a/blog/services/chatgpt.py b/blog/services/chatgpt.py
index de9a1e6c..1505852e 100644
--- a/blog/services/chatgpt.py
+++ b/blog/services/chatgpt.py
@@ -39,7 +39,7 @@ def get_better_title(title: str) -> str:
"Constraints:\n"
" - The word 'title' doesn't need to appear.\n"
" - I need only one suggested title.\n"
- " - The max length is 200, ideally shorter (50–80).\n"
+ " - The max length is 200, ideally shorter (50-80).\n"
" - Please respect the language of the text.\n"
"If it is Spanish, respond in Spanish. If English, respond in English.\n"
f"Title: '{title}'"
@@ -85,9 +85,29 @@ def blog_post_suggestion(post: Post) -> dict[str, str]:
Generates a new title and summary for the given Post model instance
and returns them as a dictionary.
"""
- title = get_better_title(post.title)
- summary = get_better_summary(post.text)
- return {"title": title, "summary": summary}
+ current_agent = _get_agent()
+ prompt = (
+ "Given the language and context of the following blog post, provide both:\n"
+ "1) a captivating improved title, not too serious\n"
+ "2) a concise and intriguing summary\n"
+ "Constraints:\n"
+ "1) Respect the language of the text: if Spanish, respond in Spanish; if English, in English.\n"
+ "2) Return exactly one title and one summary.\n"
+ "3) The title should be shorter than 200 characters, ideally 50-80.\n"
+ "4) The summary should be shorter than 300 characters, ideally around 200.\n"
+ f"Current title: '{post.title}'\n"
+ f"Content: '{post.text}'"
+ )
+
+ logfire.debug(f"Asking pydantic-ai for an improved title and summary:\n{prompt}")
+ try:
+ response = current_agent.run_sync(prompt)
+ suggestions = {"title": response.output.title, "summary": response.output.summary}
+ logfire.debug(f"Improved suggestions: {suggestions}")
+ except Exception as e:
+ logfire.error(f"Error getting improved title and summary: {e}")
+ raise
+ return suggestions
def improve_blog_post(post: Post) -> None:
diff --git a/blog/services/telegram.py b/blog/services/telegram.py
index d5a8a86d..dfea7605 100644
--- a/blog/services/telegram.py
+++ b/blog/services/telegram.py
@@ -1,21 +1,37 @@
+import logging
+
import requests
from django.conf import settings
+logger = logging.getLogger(__name__)
+
TELEGRAM_TOKEN = settings.TELEGRAM_TOKEN # type: ignore
TELEGRAM_CHAT_ID = settings.TELEGRAM_CHAT_ID # type: ignore
BASE_URL = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}"
+# Placeholder tokens used when Telegram is not configured (e.g. tests, CI)
+_PLACEHOLDER_TOKENS = {"", "foo", "changeme", "somekey"}
+
+REQUEST_TIMEOUT_SECONDS = 10
+
+
+def _has_valid_telegram_token(token: str) -> bool:
+ return bool(token and token not in _PLACEHOLDER_TOKENS and ":" in token)
+
+
+def send_message(message: str) -> dict[str, object]:
+ if not _has_valid_telegram_token(TELEGRAM_TOKEN):
+ logger.warning("Telegram not configured (token=%r), skipping message", TELEGRAM_TOKEN)
+ return {"ok": True, "description": "skipped — Telegram not configured"}
-def send_message(message: str) -> dict[str, str]:
endpoint = f"{BASE_URL}/sendMessage"
payload = {"chat_id": TELEGRAM_CHAT_ID, "text": message}
- response = requests.post(endpoint, data=payload)
+ response = requests.post(endpoint, data=payload, timeout=REQUEST_TIMEOUT_SECONDS)
response.raise_for_status()
return response.json()
-def send_contact_message(name: str, email: str, message: str) -> dict:
- # Here, you can format the message or handle additional logic if needed
+def send_contact_message(name: str, email: str, message: str) -> dict[str, object]:
formatted_message = f"Message from website: Name: {name}, Email: {email}, Message: {message}"
return send_message(formatted_message)
diff --git a/blog/templates/blog/about.html b/blog/templates/blog/about.html
index 99eda758..be2dce94 100644
--- a/blog/templates/blog/about.html
+++ b/blog/templates/blog/about.html
@@ -1,116 +1,131 @@
{% extends 'core/utils/base.html' %}
-{% load partials %}
{% block content %}
{% partialdef about-content %}
{% load i18n static %}
-
- {% translate "About me" %}
-
+
-
-
- {% translate "Hello World! My name is Eduardo and I'm a developer 💻." %}
- {% blocktranslate with years=years_in_python %}I've been working ⛏️ with Python 🐍 for the last {{ years }} years, most of the time working as a backend developer with Django.{% endblocktranslate %}
- {% translate "Currently living in" %} {% translate "Buenos Aires" %}, {% translate "München" %}, {% translate "Amsterdam" %}, {% translate "while working from home." %} 🏠
-
+ {% blocktranslate trimmed with age=global_data.age years_in_nl=global_data.years_in_nl %}
+ Hi, my name is Eduardo. I'm from Buenos Aires, I'm {{ age }} years old, and I currently live in Amsterdam — I moved to the Netherlands in 2020, so it's been about {{ years_in_nl }} years now. I work as a Team Lead at FareHarbor, in a role that combines parts of an engineering manager and a tech lead. Besides that, I really enjoy teaching and helping people grow in the IT world.
+ {% endblocktranslate %}
+
+
+ {% blocktranslate trimmed %}
+ My path into software wasn't the usual one. I didn't formally study computer science beyond what I learned in high school. That doesn't mean I didn't spend countless hours, days, and months learning on my own. In fact, studying philosophy and earning my degree in that field played an important role in shaping how I think and approach problems.
+ {% endblocktranslate %}
+
+
+ {% blocktranslate trimmed %}
+ I've been working continuously in the software industry since late 2010. Over the years I've worked across many roles, technologies, and environments, but Python 🐍 has been the technology that's stayed with me the longest.
+ {% endblocktranslate %}
+
+
+ {% blocktranslate trimmed %}
+ I enjoy open source, teamwork, and solving interesting problems. I like reading, and I'm a naturally curious person. I think that's a good summary of who I am.
+ {% endblocktranslate %}
+
+
+ {% blocktranslate trimmed with email_url=global_data.email %}
+ If you'd like to connect, feel free to send me an email and we can continue the conversation there.
+ {% endblocktranslate %}
+
+
-
-
-
-
-
-
-
-
{% translate 'A bit more about me 😉, so here it goes:' %}
-
- {% translate "I'm Eduardo Enriquez, aka eduzen." %}
- {% blocktranslate with years=years_of_experience %}I've been working in the IT industry for quite a long time, {{ years }} years and counting,mostly as a backend developer 💻.{% endblocktranslate %}
- {% translate "But I also have some experience working as a team leader." %}
- {% translate "Python 🐍, Django 🟩, and Flask are the main technologies 🧪 that I've been working with." %}
- {% translate "Naturally, I have some experience 💡 with other things like Javascript, Docker 🐳, Redis 🟥, RabbitMQ 🐰, Celery 🌿, and Linux 🐧." %}
-
-
- {% translate "You can check my code at " %}{{ global_data.github }}.
- {% translate "There you can find some bots like the one that I have for Telegram," %}
- eduzen_bot 🤖
- {% translate "(you can talk to it following this link:" %}
- bot .
- {% translate "Or you can find the source code of this website at" %}
- https://github.com/eduzen/website.
-
-
-
-
- {% translate "Besides computers, I like good music, books, philosophy, movies, series, and good food. I started trying some mechanical keyboards (right now using a Leo pold 75 %)! But I have also a Keychron K12." %}
-
{% translate "Some people find it weird that I have a bachelor's degree in philosophy from the University of Buenos Aires 🇦🇷. But I think that rational thinking is something that my profession and studies share." %}
{% translate "In general, philosophy has shaped my analytical thinking and fostered my curiosity. Some of my favorite philosophers are Nietzsche, Descartes, and Foucault." %}
- {% translate "Writers... many; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke, and many more..." %}
-
+
+
+ 👨🏽🏫
+
{% translate "Teaching" %}
+
{% translate "Last but not least, I'm passionate about teaching 👨🏽🏫. I think my background in philosophy has helped me to be a better teacher." %}
{% translate "I've been teaching in the past, and I'm looking forward to doing it more often in the IT field." %}
+
+ ✨
+
{% translate "Interests" %}
+
+ {% translate "Besides computers, I like good music, books, philosophy, movies, series, and good food. I started trying some mechanical keyboards (right now using a Leo pold 75 %)! But I have also a Keychron K12." %}
+ {% translate "Writers... many; Jorge Luis Borges, Ursula K. Le Guin, Arthur C. Clarke, and many more..." %}
+
- {% translate "Hello! Thank you for your interest 😊. My name is Eduardo and I'm a teacher. Learn more about me on my 'About' page: " %}
-
- {% translate 'here' %}
-
-
-
- {% translate "My goal as a teacher is not just to impart knowledge, but to inspire and guide you in a way that you can lose me (and be independent) in your learning journey." %}
-
-
- {% translate "We can learn about: Python, or about web frameworks like Django, Flask, or FastAPI. We can also explore other topics like: object-oriented programming, unit tests, clean code or the one that you need." %}
-
-
- {% translate "It's not easy to learn new things. It's hard also to find the motivation and the resources that are good for you. In these modern times, what we have is data 🗃️, data 🗃️ and data 🗃️, available everywhere." %}
- {% translate "However, discerning the quality of this data can be challenging. That's where a guide or companion comes in handy 😉." %}
- {% translate "So I can help you to organize and curate the data and tell you what to use or not." %}
-
- {% translate "If you're in the Netherlands 🇳🇱, let's schedule a coffee ☕ and chat 💬 about your learning objectives. If you're based elsewhere in the world 🌍, not to worry!" %}
- {% translate "We can set up a Zoom or Meet call to discuss how I can assist you in your coding adventure." %}
-
- {% translate "Online Resources to Learn Python:" %}
-
-
- {% translate "Impossible not to recommend ChatGPT: " %}link
- {% translate "I think it's one of the most important resources from our modern times. It's a great companion that could answer almost everything that you need in this field." %}
- {% translate "Certainly it's not infallible, it has its caveats and you need to learn how to use it. But it's worthy. I'm using it every day. " %}
-
-
- {% translate "I also recommend the following resources:" %}
-
+ {% translate "Hello! Thank you for your interest 😊. My name is Eduardo and I'm a teacher. Learn more about me on my 'About' page: " %}
+ {% translate "here" %}
+
+
+ {% translate "My goal as a teacher is not just to impart knowledge, but to inspire and guide you in a way that you can lose me (and be independent) in your learning journey." %}
+
+
+ {% translate "We can learn about: Python, or about web frameworks like Django, Flask, or FastAPI. We can also explore other topics like: object-oriented programming, unit tests, clean code or the one that you need." %}
+
+
+ {% translate "It's not easy to learn new things. It's hard also to find the motivation and the resources that are good for you. In these modern times, what we have is data 🗃️, data 🗃️ and data 🗃️, available everywhere." %}
+ {% translate "However, discerning the quality of this data can be challenging. That's where a guide or companion comes in handy 😉." %}
+ {% translate "So I can help you to organize and curate the data and tell you what to use or not." %}
+
+
+ {% translate "If you're in the Netherlands 🇳🇱, let's schedule a coffee ☕ and chat 💬 about your learning objectives. If you're based elsewhere in the world 🌍, not to worry!" %}
+ {% translate "We can set up a Zoom or Meet call to discuss how I can assist you in your coding adventure." %}
+
+
+
+
+
+
{% translate "Online Resources to Learn Python:" %}
+
+ {% translate "Impossible not to recommend ChatGPT: " %}ChatGPT.
+ {% translate "I think it's one of the most important resources from our modern times. It's a great companion that could answer almost everything that you need in this field." %}
+ {% translate "Certainly it's not infallible, it has its caveats and you need to learn how to use it. But it's worthy. I'm using it every day. " %}
+
+
+ {% translate "I also recommend the following resources:" %}
+
+ {% translate "Reach out to me " %}
+ {% translate "here" %}
+ {% translate "or drop me an email at " %}me@eduzen.com.ar{% translate " and let's chat!" %}
+
+ {% translate "With over 10 years in the industry, I offer hands-on expertise for individuals and businesses tackling daily technical challenges." %}
+ {% translate "Remote or in-person, I'm here to help you ship better software." %}
+
- {% translate "Crafting tech magic 🧙🏼♀️ for individuals 🧍🏻♀️ and businesses 🏭, with a sprinkle of fun and a dollop of expertise." %}
- {% translate "Let's code something delightful!" %}
- {% translate "With over 10 years in the industry 👴🏿, I offer useful insights and expertise for daily challenges." %}
- {% translate "Remote 💻 or in-person 🪑, I'm here to assist." %}
- {% translate "Interested in my professional journey?" %}
- {% translate "Check out my" %} {% translate "LinkedIn profile" %}.
-
-
-
{% translate "Services" %}
-
-
-
-
{% translate 'For the Rising Tech Stars: Individuals' %}
-
- {% translate "Personalized training 🏋🏼♂️, classes 👨🏽🏫, and tutoring 🤓 to help you blossom into an autonomous developer." %}
- {% translate "Stuck on a bug 🐛? I've got your back, literally!" %}
+
+
{% translate "Services" %}
+
+
+ 🧑💻
+
{% translate "For Individuals" %}
+
+ {% translate "Personalized training, classes, and tutoring to help you grow into an autonomous developer." %}
+ {% translate "Stuck on a bug? I've got your back." %}
-
-
-
{% translate 'For the Business: Companies' %}
-
- {% translate "Crafting day-to-day solutions, providing stellar training (unittesting, robust code writing, you name it!), fixing Django/Python 🐍 performance issues, evaluating legacy code 🔖, or upgrading versions ⬆️." %}
- {% translate "If it's tech, I'm your guy!" %}
+
+ 🏢
+
{% translate "For Companies" %}
+
+ {% translate "Day-to-day solutions, team training (unit testing, robust code), Django/Python performance fixes, legacy code evaluation, and version upgrades." %}
-
-
-
{% translate "Experience & Skills" %}
-
-
-
{% translate "Years of Mischief & Mastery" %}
-
- {% translate "Code wizardry 🧙🏼♂️, business acumen 👨🏻💼, and maybe a few harmless pranks along the way. Dive into my tech journey!" %}
+
+
+
{% translate "How I can help" %}
+
+
+ 🐍
+
{% translate "Python & Django" %}
+
+ {% translate "From debugging to architecture, I've worked with Python for over a decade. Django, Flask, FastAPI — I can help you choose the right tool and use it well." %}
+ {% translate "Slow queries, high response times, or scaling bottlenecks? I'll profile your application, identify the root causes, and implement concrete improvements." %}
-
-
{% translate 'Techno-Sorcery' %}
-
- {% translate "From Python 🐍 to Django, from debugging to spellbinding code – I've mastered the digital alchemy ⚗️." %}
+
+ 🔍
+
{% translate "Code Review" %}
+
+ {% translate "A fresh pair of eyes on your codebase. I'll evaluate code quality, identify tech debt, and provide actionable recommendations for improvement." %}
+ {% translate "Workshops and hands-on sessions on testing, clean code, Python best practices, and modern development workflows for your team." %}
-
-
-
{% translate 'Get in Touch' %}
-
- {% translate "Ready to embark on a tech adventure or brew up a business solution? Let's talk!" %}
+
+
+
{% translate "Experience" %}
+
+
+ {% translate "Over the years I've worked across many roles, technologies, and environments — from startups to established companies, from solo projects to large engineering teams." %}
+
+ {% blocktranslate trimmed %}
+ Have a project idea, a question, or just want to say hello?
+ I'd love to hear from you. Fill out the form or reach me
+ through any of the channels below.
+ {% endblocktranslate %}
+
+ {% blocktranslate trimmed with email_link='dev@eduzen.com.ar'|safe %}
+ For over a decade I've worked primarily with Python and JavaScript.
+ Today I lead teams, but I still get my hands dirty with code.
+ I enjoy thinking, teaching, and building things.
+ If you have a project to work on together, a question,
+ or just want to get in touch, you can reach me at {{ email_link }}.
+ {% endblocktranslate %}
+
+ {% translate "Mentoring is not about giving you the answers. It's about helping you find them yourself, and building the confidence to keep finding them long after our sessions end." %}
+
+
+ {% translate "I studied philosophy before becoming a software engineer, and that shaped how I think about teaching. I believe in asking the right questions, understanding the 'why' behind things, and developing a way of thinking that goes beyond memorizing syntax." %}
+
+
+ {% translate "Whether you're starting your first steps in programming, preparing for a career change, or looking to level up as a developer — I can be your guide. Not a guru, not a professor. A companion in your learning journey." %}
+
+
+
+
+
+
{% translate "What we can work on" %}
+
+
+ 🔍
+
{% translate "Code Review" %}
+
+ {% translate "Bring your code and let's look at it together. I'll help you understand patterns, spot issues, and write cleaner, more maintainable software. We learn best from real code." %}
+
+
+
+ 🧭
+
{% translate "Career Navigation" %}
+
+ {% translate "The tech industry can be overwhelming. Whether it's preparing for interviews, choosing the right path, or understanding what companies actually look for — I've been there and I can help." %}
+
+
+
+ 👥
+
{% translate "Pair Programming" %}
+
+ {% translate "There's no better way to learn than building something together. We'll work on real problems side by side, and you'll pick up practices and habits that no tutorial can teach." %}
+
+
+
+ 🗺️
+
{% translate "Learning Path" %}
+
+ {% translate "Feeling lost in the ocean of resources? I'll help you build a personalized roadmap based on where you are now and where you want to go. No generic advice — just what works for you." %}
+
+
+
+
+
+
+
+
{% translate "How it works" %}
+
+
+ 1
+
+
{% translate "Intro call" %}
+
{% translate "A free, informal chat where we get to know each other and talk about your goals. No commitment." %}
+
+
+
+ 2
+
+
{% translate "Personalized plan" %}
+
{% translate "Based on our conversation, I'll put together a plan tailored to your level, interests, and available time." %}
+
+
+
+ 3
+
+
{% translate "Regular sessions" %}
+
{% translate "Weekly or biweekly — whatever fits your rhythm. Remote via Zoom/Meet, or in person if you're in Amsterdam." %}
+
+
+
+ 4
+
+
{% translate "Async support" %}
+
{% translate "Questions between sessions? I'm available via chat. Sometimes a quick pointer saves hours of frustration." %}
+
+
+
+
+
+
+
+
{% translate "Who is this for" %}
+
+
+ 🌱
+
{% translate "Beginners" %}
+
{% translate "You're curious about programming and want to start on the right foot, with good habits from day one." %}
+
+
+ 🔄
+
{% translate "Career Switchers" %}
+
{% translate "You're making the leap into tech from another field. I can help you navigate the transition with clarity." %}
+
+
+ 📈
+
{% translate "Growing Developers" %}
+
{% translate "You already code but want to get better — write cleaner code, understand architecture, prepare for senior roles." %}
+
+
+
+
+
+
+
+ {% translate "Interested? Let's start with a conversation." %}
+
Blog
{% if tag %}
- |
- {{ tag }}
+ | {{ tag }}
{% else %}
- {% translate 'or just public notes' %}
+ {% translate 'or just public notes' %}
{% endif %}
-
-{% for post in posts %}
-
- {% if post.image %}
-