Esta guía documenta el flujo editorial, el theme y la operación del sitio para futuras sesiones de trabajo sobre textosypretextos.
zolanode/npmuvhunspell+ diccionarioes_AR(para el checker ortográfico)prekopre-commit(opcional, para correr el hook antes de cada commit)
npm install
npm run devnpm run devrecompila assets, reconstruye datos derivados y levantazola servesin drafts.npm run dev:draftshace lo mismo pero incluye borradores.npm run buildreconstruye assets,data/site_index.jsony generapublic/.npm run previewlevanta una preview local con Wrangler sobre el build.
Zola no trae un comando nativo para scaffold de contenido individual. En este repo usar:
uv run scripts/new_article.py blog "Título del artículo"
uv run scripts/new_article.py fotos "Título de la foto" --author "Martín Gaitán"
uv run scripts/new_article.py videos "Título del video" --tags "Cine, Música"Eso genera un Markdown con front matter TOML compacto alineado al sitio.
blog/: núcleo del sitio. Textos propios, crónicas, cuentos, poemas, apuntes y series.fotos/: entradas fotográficas. Si la imagen es central, cuidarhero_image,hero_alty caption.videos/: textos con embed o referencia audiovisual.de-otros/: materiales ajenos; revisar bien autoría real.personal/: archivo menor, usar sólo si el contenido no encaja en las anteriores.
No crear listados manuales en:
autores/: estas páginas conservan título, bio, foto y género; no deben listar artículos.etiquetas/: estas páginas conservan título y metadata editorial mínima; no deben listar artículos.buscar.md: página funcional del buscador.
Las listas de artículos por autor, etiqueta y subsección se derivan desde los artículos con:
uv run scripts/build_zola_index.pyEl build lo corre automáticamente antes de zola build.
Campos clave del front matter:
titleslugdateauthorstagsdescription— resumen corto para listados y metadatos sociales
Campos opcionales:
-
draft = true, sólo en borradores. -
[extra].hero_image -
[extra].hero_alt -
[extra].subtitle -
[extra].deck— epígrafe del artículo; soporta markdown. Un blockquote dentro del deck se muestra como epígrafe alineado a la derecha. El último párrafo del blockquote se interpreta como atribución:deck = """ > La línea del poema o cita. > > — Nombre del autor o fuente """
Alternativamente, usar el shortcode
epigrafeen el body cuando el epígrafe es multilineal o no encaja en el campo deck:{% epigrafe() %} Verso o cita. **— Fuente o autor** {% end %}Los blockquotes markdown al comienzo del body también se renderizan como epígrafes automáticamente.
No volver a agregar a los artículos metadata heredada o derivable como
legacy_id, legacy_url, section_slug, section_title, summary, visits,
popularite, comment_count, author_links, tag_links ni comentarios
estáticos en el front matter.
- No sobreactuar el tagueo: preferir pocas etiquetas buenas.
- En
blog, la primera etiqueta suele funcionar además como subcategoría visible. - Las etiquetas se tratan como case-insensitive: si sólo cambia la mayúscula, debe ser el mismo tag.
- Para textos de terceros, cuidar que no quede Martín como autor visible si corresponde otro autor principal.
Herramienta existente para sugerir/normalizar etiquetas:
uv run scripts/infer_tags.pyImágenes:
- Guardar assets en
static/media/si son nuevos. - Usar
hero_imagepara miniaturas y portada. - Si una imagen necesita caption editorial, incluirla en el body como
figure; no mostrar nombres de archivo salvo que funcionen como dato documental.
Videos:
- Preferir embeds actuales de YouTube.
- Verificar siempre que el embed publique correctamente en Pages.
Audio/archivos:
- Reusar los shortcodes de
templates/shortcodes/.
- Para bloques de diálogo con una intervención por línea, usar la macro
dialogoen vez de<br>manuales:
{% dialogo() %}
— Primera intervención
— Segunda intervención
{% end %}- Para detectar y corregir casos simples con
--, usar:
uv run scripts/fix_dialogues.py --apply content/fotos/cronica-de-un-intento-de-homenaje.md- Sin
--apply, el script corre en modo dry-run e informa candidatos y casos ambiguos para revisión manual.
- Para poemas o textos con cortes de verso que haya que preservar, usar el shortcode
poetry:
{% poetry() %}
Primer verso
Segundo verso
Tercer verso
{% end %}- No usar
<br>manuales en contenido nuevo si el bloque completo puede resolverse conpoetry.
# revisar el corpus completo
uv run scripts/check_spelling.py
# revisar archivos puntuales
uv run scripts/check_spelling.py content/blog/foo.md
# listar las palabras desconocidas más frecuentes (útil para sembrar la allow-list)
uv run scripts/check_spelling.py --list-unknown --top 100El script usa hunspell -d es_AR y descarta frontmatter, code blocks, URLs,
emails, shortcodes y HTML antes de tokenizar. Las palabras válidas que el
diccionario no reconoce (nombres propios, marcas, voseo, extranjerismos,
lunfardo) viven en scripts/spell_allow.txt.
.pre-commit-config.yaml registra el hook spell-check-es. Para activarlo
una vez:
prek install # o `pre-commit install`A partir de ahí, cada git commit revisa los .md modificados bajo
content/. Si aparecen palabras desconocidas legítimas, agregalas a
scripts/spell_allow.txt (una por línea, sin acento ni mayúscula obligatoria
porque la comparación es case-insensitive).
uv run scripts/export_spip_to_zola.py
uv run scripts/infer_tags.pyUsar esto sólo si hace falta regenerar desde el dump original. Si el cambio es puntual y editorial, editar el Markdown fuente ya exportado.
El theme sigue un sistema editorial inspirado en WIRED. La referencia base local es:
Origen del sistema:
- https://getdesign.md/wired/design-md
- comando de origen:
npx getdesign@latest add wired
- Tipografía expresiva serif para títulos y serif legible para cuerpo.
- UI y metadata en sans/mono con mayúsculas espaciadas.
- Blanco/negro como base; el azul sólo como acento puntual.
- Bordes rectos, sin sombras, sin glassmorphism, sin “cards SaaS”.
- El sitio debe sentirse editorial, no técnico.
templates/base.html: estructura global, header, nav y footer.templates/index.html: home.templates/article.html: artículos.templates/section.html: listados de sección.templates/partials/macros.html: cards/listados reutilizables.src/styles/site.css: estilos del theme.src/scripts/site.js: comportamiento del cliente.
npm run build
npm run deployEl deploy productivo usa Cloudflare Pages y el workflow de GitHub Actions al mergear en main.
Comandos útiles:
npx wrangler pages dev public
npx wrangler pages deploy public --project-name textosypretextos
npx wrangler d1 execute textosypretextos-comments --remote --file=migrations/001_init.sqlLa API vive en functions/api/comments.js y persiste en D1.
Los comentarios históricos exportados desde SPIP viven en data/comments.json.
No se guardan en el front matter de cada artículo. Si se modifica esa data,
reconstruir el índice derivado con:
uv run scripts/build_zola_index.pyModeración rápida:
npx wrangler d1 execute textosypretextos-comments --remote --command "SELECT id, article_slug, author, status FROM comments ORDER BY created_at DESC LIMIT 20;"
npx wrangler d1 execute textosypretextos-comments --remote --command "UPDATE comments SET status='spam' WHERE id=123;"CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_IDCOMMENT_SALT
Antes de arrancar cualquier trabajo nuevo, asegurarse de estar en la versión más reciente de main, salvo indicación contraria:
git checkout main && git pull origin mainCrear la rama de trabajo a partir de ese punto.
Abrir siempre el PR con gh pr create y esperar revisión y aprobación explícita antes de mergear. No ejecutar gh pr merge por iniciativa propia.
- crear primero issue/s con
ghenmgaitan/textosypretextos - usar bodies pragmáticos y concretos, no texto inflado
- recién después implementar en una rama de trabajo
- dejar comentarios breves en el issue cuando haya avance real
- cerrar o vincular el issue en el commit/PR correspondiente
Excepción:
- si el pedido ya dice “implementá el issue #N” o remite con claridad a un issue existente, no crear otro issue duplicado
Usar siempre --body-file para evitar que el shell interpole backticks u otras
expansiones en el cuerpo del issue:
cat > /tmp/issue_body.md << 'EOF'
Descripción con `backticks` sin problema.
EOF
gh issue create --title "Título" --body-file /tmp/issue_body.md