Este repo es privado y existe solo para documentar cómo mantener el sitio público (GitHub Pages) sin mezclar documentación interna.
index.html: home del portafolio. Solo carga CSS/JS y renderiza todo con JavaScript.css/:styles.css: estilos principales del sitioreading.css: estilos para lectura de artículos (también aplica al home en algunas secciones)
js/:content.js: “base de datos” local (proyectos, videos, textos ES/EN, etc.) enwindow.CONTENTapp.js: render + interacción del home (tema, modo, idioma, filtros, contacto)article.js: render dearticulo.html(carga Markdown, lo convierte a HTML)
posts/:index.json: índice/lista de artículos (se usa en el home)articulos/*.md: contenido real de artículos en Markdown por idioma- patrón:
posts/articulos/<slug>.es.mdyposts/articulos/<slug>.en.md
- patrón:
img/: imágenes del sitio (ej:img/project/*.webp)
index.htmlcarga:js/content.js→ definewindow.CONTENTjs/app.js→ leewindow.CONTENT, intenta sobrescribirCONTENT.articlesconposts/index.json, y renderiza todo dentro de#app
articulo.htmlcargajs/article.js→ lee?slug=...&lang=...→ descarga el.mdcorrespondiente enposts/articulos/→ lo renderiza.
Un artículo tiene 2 partes:
- A) El índice (
posts/index.json) para que aparezca en el listado del home - B) El contenido (
posts/articulos/<slug>.<lang>.md)
- Abre
posts/index.json. - Agrega un objeto al inicio del array (para que salga primero como “último artículo”).
- Campos recomendados:
slug: identificador único (sin espacios). Ej:"mi-nuevo-articulo"date:"YYYY-MM-DD"tags: array de stringstype:"data"o"dev"o"mix"(consistencia visual)available:["es"]o["es","en"]title:{ "es": "...", "en": "..." }excerpt:{ "es": "...", "en": "..." }
Ejemplo:
{
"slug": "mi-nuevo-articulo",
"date": "2026-04-25",
"tags": ["Datos", "Python"],
"type": "data",
"available": ["es", "en"],
"title": { "es": "Título ES", "en": "Title EN" },
"excerpt": { "es": "Resumen ES", "en": "Excerpt EN" }
}- Crea el archivo:
- Español:
posts/articulos/mi-nuevo-articulo.es.md - Inglés (opcional):
posts/articulos/mi-nuevo-articulo.en.md
- Español:
- Estructura recomendada: front-matter + contenido.
Plantilla mínima:
---
title: Título del artículo
excerpt: Una frase corta (opcional)
readingTime: 6 min
---
## Subtítulo
Texto…
- Lista
- Lista
Notas:
- El parser de Markdown de
js/article.jssoporta lo que usamos: títulos#..####, listas, blockquote, links, negrita, itálica,inline codey bloquescode.
Abre:
articulo.html?slug=mi-nuevo-articulo&lang=esarticulo.html?slug=mi-nuevo-articulo&lang=en(si existe EN)
Los proyectos viven en js/content.js dentro de window.CONTENT.projects.
Cada proyecto recomendado:
id: string únicotype:"data" | "dev" | "mix"size:"sm" | "md" | "lg"(cambia el tamaño de la tarjeta)img: ruta tipo"img/project/mi-proyecto.webp"onulltitle:{es,en}desc:{es,en}tools:["Python","SQL",...]
Pasos:
- Sube la imagen (si aplica) a
img/project/(ideal:.webp). - Agrega el objeto al array
projects. - Revisa en el sitio y usa filtros (Todos/Datos/Dev/Mixto).
Los videos viven en js/content.js dentro de window.CONTENT.videos.
Campos típicos:
id: ID de YouTube (ej:"dQw4w9WgXcQ")external:{ channel, url }(si quieres atribución/canal)duration: string (puede ser"—")date:"YYYY-MM-DD"type:"data" | "dev" | "mix"title:{es,en}description:{es,en}
Pasos:
- Agrega un objeto al inicio del array
videospara que sea el “último video”. - Verifica que el thumbnail carga: el home usa
https://i.ytimg.com/vi/<id>/hqdefault.jpg.
Los textos UI (menú, títulos, descripciones) están en:
js/content.js→window.CONTENT.copy.esywindow.CONTENT.copy.en
Pasos:
- Edita el string en ES y su equivalente EN.
- Prueba cambiando el idioma con el selector “ES/EN” del header.
Carpeta: contact-worker/
Sirve para recibir mensajes del formulario del sitio sin exponer tu email:
- El frontend hace
POSTal Worker (URL definida enindex.htmlcomowindow.CONTACT_WORKER_URL). - El Worker crea un Issue en un repo privado (inbox).
Variables secretas del Worker (Cloudflare):
GH_TOKEN,GH_OWNER,GH_REPO,ALLOW_ORIGIN
Regla de oro:
- Nunca poner tokens en el repo público.
- Existe
index.htmlen la raíz. - Rutas correctas:
css/styles.css,css/reading.cssjs/app.js,js/content.js,js/article.js
- Artículos:
posts/index.jsonválido (JSON bien formado)- Archivos
.mdexisten para cadaslug
- No se suben archivos sensibles:
- ZIPs personales, backups,
.env, tokens
- ZIPs personales, backups,
- Cambia archivos (artículos/proyectos/videos).
- Prueba local.
- Commit + push al repo público.
- GitHub Pages despliega automáticamente.