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_baseurl en _config.yml (actualmente https://lab.marconoris.com).
  • Cualquier enlace Markdown o atributo HTML href/src que 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: layout correcto (post/page/project…), title, date, lang (es/ca/en/it…). Sin title no aparece en listados; sin lang el pager asume es.
  • Slugs/URLs: no necesitas tocarlos; el hook genera slug latinizados y permalinks por colección. Usa slug/permalink solo si quieres forzar algo distinto.
  • H1 y contenido: el primer # se extrae al layout. Si quieres dejar el H1 en el cuerpo, añade keep_h1: true y el layout no pintará un H1 extra.
  • Paginación/pagers: el include pagination.html muestra anterior/siguiente dentro de la misma collection y lang. Si no ves pager, comprueba lang.
  • Orden en colecciones:
    • Projects: se ordenan por fecha (descendente). Si quieres posicionar manualmente, usa order y/o ajusta date.
    • Resto de colecciones: si tienen order, se ordenan por order (ascendente) y, a igualdad, por fecha descendente. Si no hay order, solo por fecha.
  • 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: false en el front matter.
  • Build limpio: si cambias permalinks/slugs, borra _site y .jekyll-cache y ejecuta bundle 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: true aparece en la home (se mezclan site.pages y todas las colecciones, ordenado por date descendente).
  • Título principal: el primer elemento destacado se usa como h1 de la portada, enlazado al documento.
  • Jerarquía interna: si el contenido del destacado trae un h1, en home se demota a h2 para evitar múltiples h1.
  • Separadores: cada destacado se separa con <hr class="home-featured-separator"> (estilado en _sass/_layout.scss).
  • Colapsar colecciones: hay un bloque collections_state comentado en _config.yml; por defecto todas quedan cerradas. Lista en open las que quieras abrir de inicio:

    collections_state:
      open:
        - posts
        - versiculi
    

    puedes 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:). Con layout: project se renderiza automáticamente (a menos que uses gallery_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.webp
    

    o 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 acepta id, gallery_style (grid, masonry, collage, carousel), y gallery (lista de imágenes con src; opcionales: thumb, caption, width, height para 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ñadir gallery_captions: para sobrescribir captions por archivo. Si quieres el mismo caption para todas las auto, usa gallery_caption_all: "Mi caption".
  • Render: por defecto (gallery_render: auto) el layout recorre galleries (o gallery/gallery_path sueltas) y pinta la galería antes del contenido. Si quieres colocarlas en un punto concreto del texto, pon gallery_render: manual e 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 pasa skip_pswp_container=true en 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: false en el bloque o en el include: `

`.

  • Columnas por breakpoint (grid y masonry): usa gallery_columns (móvil/base), gallery_columns_md (≥640px) y gallery_columns_lg (≥1024px). Ejemplo:

    gallery_columns: 1
    gallery_columns_md: 2
    gallery_columns_lg: 4
    

    Si 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 masonry las 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). collage usa filas fijas con spans; carousel centra y permite scroll horizontal con controles. Puedes mezclar gallery manual con gallery_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ún lang). Busca el proyecto en site.proyectos por translation_key y prioriza el mismo lang; 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, ul y ol como 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 (los p que envuelven button no 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 en series/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}