Libellus
Enlaces de la bóveda de Obsidian
- Los enlaces relativos que salen de este repo (p. ej.
../../../Lecturas/...) se reescriben automáticamente durante el build. - Configura el host de publicación con
obsidian_publish_baseurlen_config.yml(actualmentehttps://lab.marconoris.com). - Cualquier enlace Markdown o atributo HTML
href/srcque empiece por../se reescribe hacia ese host, para que los assets exportados de la bóveda sigan funcionando en la web.
Cómo mantener el sitio
Checklist rápido para que todo funcione bien:
- Front matter mínimo:
layoutcorrecto (post/page/project…),title,date,lang(es/ca/en/it…). Sintitleno aparece en listados; sinlangel pager asumees. - Slugs/URLs: no necesitas tocarlos; el hook genera
sluglatinizados y permalinks por colección. Usaslug/permalinksolo si quieres forzar algo distinto. - H1 y contenido: el primer
#se extrae al layout. Si quieres dejar el H1 en el cuerpo, añadekeep_h1: truey el layout no pintará un H1 extra. - Paginación/pagers: el include
pagination.htmlmuestra anterior/siguiente dentro de la mismacollectionylang. Si no ves pager, compruebalang. - Orden en colecciones:
- Projects: se ordenan por fecha (descendente). Si quieres posicionar manualmente, usa
ordery/o ajustadate. - Resto de colecciones: si tienen
order, se ordenan pororder(ascendente) y, a igualdad, por fecha descendente. Si no hayorder, solo por fecha.
- Projects: se ordenan por fecha (descendente). Si quieres posicionar manualmente, usa
- Callouts: usa sintaxis
> [!tipo] Título(tip, success, warning, danger, quote, cite, question, note, links, abstract, summary, texts…). Mira/callouts-demo/para ejemplos. - Autolink de URLs: cualquier http/https suelto se enlaza automáticamente en el post-render. Si necesitas desactivar en una página/post, pon
autolink_urls: falseen el front matter. - Build limpio: si cambias permalinks/slugs, borra
_sitey.jekyll-cachey ejecutabundle exec jekyll build(sin incremental) para ver los cambios.
Embeds de vídeo (YouTube/Vimeo) y allowlist
El plugin _plugins/video_markdown_embed.rb convierte URLs de YouTube/Vimeo en iframes responsivos cuando:
- Pegas una URL “sola” en una línea (ej.
https://vimeo.com/974390692). - Usas sintaxis de imagen Markdown apuntando a la URL del vídeo: `<div class="video-embed video-embed--vimeo">
</div> (el texto se usa como title` del iframe).
Cómo funciona la allowlist
Para evitar pasar parámetros arbitrarios al embed, el plugin:
- Lee el querystring de la URL original (lo que va tras
?). - Conserva solo las claves permitidas por plataforma (
ALLOWED_QUERY_PARAMS), normalizando el nombre a minúsculas. - Descarta cualquier otro parámetro.
Allowlist actual:
- YouTube:
autoplay,controls,loop,mute,playsinline,start,end - Vimeo:
autoplay,loop,muted,autopause,playsinline,background,dnt,title,byline,portrait,badge
Además, para Vimeo el plugin añade por defecto title=0&byline=0&portrait=0&badge=0 (puedes sobrescribirlos si los pasas en la URL y están en la allowlist).
Otros iframes responsivos (mapas, álbumes, etc.)
Si necesitas embeds que no sean 16:9 (Lightroom, Mapbox, Sketchfab…), envuélvelos en .embed-frame y marca el ratio con --embed-ratio (fallback 4/3):
<div class="embed-frame" style="--embed-ratio: 4 / 3">
<iframe src="https://…"></iframe>
</div>
El wrapper elimina el margen del iframe, hereda el radio de borde y mantiene la relación de aspecto que definas.
Para colocar varios iframes uno al lado del otro, usa .embed-grid como contenedor:
<div class="embed-grid">
<div class="embed-frame" style="--embed-ratio: 4 / 3">
<iframe src="https://…"></iframe>
</div>
<div class="embed-frame" style="--embed-ratio: 4 / 3">
<iframe src="https://…"></iframe>
</div>
</div>
Portadas con video de fondo
El layout cover (ver portada.md) admite video de fondo desde Vimeo o YouTube. Usa cover_video o video_cover (también vale cover_vimeo para compatibilidad) con la URL completa:
layout: cover
title: ...
cover_video: https://vimeo.com/123456789 # o https://youtu.be/abc123
# Opcional: cover (imagen) como fallback estático
El layout ajusta parámetros para autoplay/loop/mute y oculta los controles. No hace falta width/height; el iframe se adapta a la sección hero.
Frontmatter para Jekyll
Lo mínimo que necesita cada tipo de documento para que todo funcione sin sorpresas:
- layout: el adecuado para la colección (post, page, project, etc.).
- title: obligatorio (sin título no sale en listados ni en Home/collections).
- date: para ordenar (posts y colecciones); si falta, caen a orden 0 o usan updated.
- lang: consistente (es/ca/en/it…). El pager filtra por lang y si falta asume es.
Opcional según necesidad:
- slug/permalink: los genera el hook a partir de title, así que solo hace falta si quieres forzar algo distinto.
- year: en projects para ordenar por año antes que por fecha.
- order: en projects para ordenar dentro del mismo año.
- publish: false para ocultar.
- keep_h1: true si quieres conservar el H1 en el cuerpo.
- home_featured: true para fijar publicaciones en la home.
Portada / home
- Contenido destacado: cualquier página o documento de colecciones con
home_featured: trueaparece en la home (se mezclansite.pagesy todas las colecciones, ordenado pordatedescendente). - Título principal: el primer elemento destacado se usa como
h1de la portada, enlazado al documento. - Jerarquía interna: si el contenido del destacado trae un
h1, en home se demota ah2para evitar múltiplesh1. - Separadores: cada destacado se separa con
<hr class="home-featured-separator">(estilado en_sass/_layout.scss). -
Colapsar colecciones: hay un bloque
collections_statecomentado en_config.yml; por defecto todas quedan cerradas. Lista enopenlas que quieras abrir de inicio:collections_state: open: - posts - versiculipuedes listar las colecciones a ocultar sin borrarlas. Úsalo si decides implementar lógica de cierre en los listados/pagers.
Galerías (PhotoSwipe)
Guía rápida para usar las galerías del layout project y sus opciones:
-
Galería única “suelta” (lo básico): si solo necesitas una galería, puedes definirla directamente en el documento (sin
galleries:). Conlayout: projectse renderiza automáticamente (a menos que usesgallery_render: manual).gallery_style: grid # opcional (default: grid) gallery: - src: /images/projects/mi-proyecto/01.webp caption: "Pie opcional" - src: /images/projects/mi-proyecto/02.webpo bien auto desde carpeta:
gallery_style: masonry # opcional gallery_path: /images/projects/mi-proyecto/ # importante: con barra final gallery_caption_all: "Mi caption" # opcional # gallery_captions: # opcional (mapa filename -> caption) # 01.webp: "Pie 1" # 02.webp: "Pie 2" -
Múltiples galerías (recomendado si quieres títulos/secciones): define
galleries:como lista de bloques. Cada bloque aceptaid,gallery_style(grid,masonry,collage,carousel), ygallery(lista de imágenes consrc; opcionales:thumb,caption,width,heightpara el zoom del lightbox):galleries: - id: uno gallery_style: masonry gallery: - src: ../images/foo/bar.webp thumb: ../images/foo/bar-thumb.webp caption: "Título o pie" width: 1800 height: 1200 - Auto desde carpeta: en lugar de listar imágenes, usa
gallery_path: /images/projects/mi-proyecto/(incluye la barra final) para cargar todos los ficheros de esa carpeta (ordenados por nombre). Puedes añadirgallery_captions:para sobrescribir captions por archivo. Si quieres el mismo caption para todas las auto, usagallery_caption_all: "Mi caption". - Render: por defecto (
gallery_render: auto) el layout recorregalleries(ogallery/gallery_pathsueltas) y pinta la galería antes del contenido. Si quieres colocarlas en un punto concreto del texto, pongallery_render: manuale inserta con `
` (o sin id si usas gallery: suelta).
- Lightbox:
- Por bloque (default): cada bloque lleva su propio
data-pswp-gallery, el lightbox solo recorre esa galería. -
Global por página: envuelve varias galerías en un contenedor con
data-pswp-gallery="algo"y pasaskip_pswp_container=trueen cada include, para que compartan el mismo lightbox:<div data-pswp-gallery="project-foo"> {% include project-gallery.html id="uno" skip_pswp_container=true %} {% include project-gallery.html id="dos" skip_pswp_container=true %} </div> - Desactivar lightbox: pon
lightbox: falseen el bloque o en el include: `
- Por bloque (default): cada bloque lleva su propio
`.
-
Columnas por breakpoint (grid y masonry): usa
gallery_columns(móvil/base),gallery_columns_md(≥640px) ygallery_columns_lg(≥1024px). Ejemplo:gallery_columns: 1 gallery_columns_md: 2 gallery_columns_lg: 4Si no defines nada, se usan los valores por defecto del CSS (
grid:auto-fit;masonry: 1/2/3 columnas en móvil/≥640/≥1024). -
Notas de estilo: en
masonrylas imágenes no se recortan; si solo hay 1–2 imágenes se ajustan las columnas para ocupar el ancho (a menos que fijes columnas).collageusa filas fijas con spans;carouselcentra y permite scroll horizontal con controles. Puedes mezclargallerymanual congallery_path: las manuales se renderizan primero y luego las auto.
Referenciar un proyecto desde páginas/posts
- Añade en el front matter
project_ref: <translation_key-del-proyecto>(ej.project_ref: lugares-remotos). - En los metadatos se mostrará
AÑO · Proyecto <link>(etiqueta traducida segúnlang). Busca el proyecto ensite.proyectosportranslation_keyy prioriza el mismolang; si no existe, usa el primero disponible.
Márgenes de texto en proyectos (override desde Markdown)
En páginas con layout project, el CSS aplica en desktop (≥768px) un margen lateral a los bloques de texto dentro de .project-content:
- Se aplica por defecto a
p,ulyolcomo hijos directos de.project-content. - Los párrafos que contienen contenido “media/interactive” (por ejemplo
img,iframe) se excluyen por defecto para evitar layouts raros (lospque envuelvenbuttonno se excluyen).
Si necesitas control fino desde Markdown (kramdown), puedes añadir clases a un bloque:
- Forzar el estilo “texto con márgenes” (aunque sea un bloque especial):
{:.project-text}(también usable enseries/page) - Quitar márgenes (ancho completo):
{:.project-text--full}
Ejemplos:
Este párrafo irá con margen lateral en desktop.
{:.project-text}
- Esta lista irá a ancho completo
- (sin margen lateral)
{: .project-text--full}