Documentación · Empezar
Hoja de referencia rápida
Las órdenes, la estructura de un proyecto, los campos, las funciones de las plantillas y los atajos, en una sola página.
Versión 0.16
Lo que vas a necesitar cada día, sin explicaciones largas. Cada apartado termina con el enlace al detalle en el formato.
Las órdenes¶
| Orden | Qué hace |
|---|---|
php ehundu.phar compilar [carpeta] |
Compila el proyecto en su carpeta salida/. Sin carpeta, la actual. |
php ehundu.phar servir [carpeta] |
Lo previsualiza en http://127.0.0.1:8000/ y rehace solo lo que cambia. |
php ehundu.phar desplegar [carpeta] |
Lo compila y lo sube al destino de sitio.yml. |
--puerto=8000, --borradores, --completo |
Opciones de servir: el puerto, enseñar también los borradores, rehacerlo todo en cada cambio. |
--simular, --todo |
Opciones de desplegar: decir qué haría sin hacerlo, o subirlo todo aunque no haya cambiado. |
--ayuda, --version |
La ayuda y la versión. |
Con Composer, vendor/bin/ehundu en lugar de php ehundu.phar.
Un proyecto¶
mi-sitio/
sitio.yml configuración: nombre y url son obligatorios
contenido/ páginas (.md y .twig) y ficheros que se copian tal cual
_datos.yml datos que heredan las páginas de la carpeta
datos/ datos globales: datos.<nombre> en las plantillas
plantillas/ layouts; pagina.twig es el de por defecto
parciales/ fragmentos con {% include %}; parciales/atajos/ para los atajos
publico/ se copia a la raíz del sitio (CSS, imágenes, favicon)
.secretos.yml contraseñas del despliegue; no se versiona
salida/ .ehundu/ los genera el motor; no se versionan
Detalle: estructura del proyecto.
sitio.yml¶
| Clave | Para qué |
|---|---|
nombre, url |
Obligatorios. La url es el dominio, sin ruta: https://www.ejemplo.com. |
idioma, idiomas |
El idioma del sitio, o la lista si son varios (es por defecto). |
zonaHoraria |
Europe/Madrid. Con ella se leen y se escriben las fechas. |
feed |
Pide un feed.xml: feed: { coleccion: blog }. |
encabezados |
Da un id, y si quieres un enlace permanente, a los encabezados del Markdown. |
imagenes |
Los anchos y formatos de las variantes de imagen, para el srcset. |
enlacesExternos |
Cómo salen los enlaces a otros dominios que escribes en Markdown. |
generador |
generador: no quita la etiqueta generator de las páginas. |
despliegue |
Adónde se publica (más abajo). |
Detalle: sitio.yml.
El front matter de una página¶
Lo que escribes entre las dos líneas de guiones al principio de un .md. Estos campos tienen un significado especial; cualquier otro llega a la plantilla tal cual.
| Campo | Para qué |
|---|---|
titulo, subtitulo, descripcion |
El título, la entradilla y la descripción para buscadores. |
fecha |
Un día, 2026-10-15. Ordena las colecciones y sale en el feed. |
url |
La dirección de la página, o un patrón. Si falta, sale de la ruta del fichero. false: no genera fichero. |
plantilla |
El layout, sin carpeta ni extensión. false: sin layout. |
etiquetas |
Las colecciones a las que pertenece: [blog, novedades]. |
listada |
no: se publica, pero no sale en colecciones ni en el sitemap. |
css, js |
Ficheros de publico/ que necesita esta página. |
imagen, imagenAlt, icono |
Imagen principal, su texto alternativo e icono SVG. |
orden |
Un número, para ordenar a mano dentro de una colección. |
borrador |
sí: no se publica. |
publicar |
No se publica antes de esa fecha. |
publicarEnSuFecha |
sí: no se publica antes de su fecha. Va en el _datos.yml de un blog. |
pdf |
sí: la página sale también en PDF. |
agrupar, paginar |
Una página por cada valor de un campo, o una lista partida en páginas (más abajo). |
Los campos de sí o no admiten sí, no, true y false, pero solo los de esta tabla: en un campo tuyo, sí y no son texto, y para un verdadero o un falso se escribe true o false (más en Plantillas y atajos). Los nombres ingleses de Eleventy y Lume (title, date, tags, layout, permalink) valen como alias. Detalle: campos reservados.
Direcciones¶
contenido/servicios/diseno.md → /servicios/diseno/
contenido/servicios/index.md → /servicios/
contenido/404.md con url: /404.html → /404.html
Un patrón usa campos de la propia página y el filtro slug:
url: "/blog/{{ titulo|slug }}/"
url: "/{{ nombreDeFichero }}/"
Detalle: URL.
Datos y herencia¶
Un fichero de datos/ está en las plantillas con su nombre: datos/cliente.yml es datos.cliente. Un _datos.yml dentro de una carpeta de contenido/ lo heredan todas sus páginas; gana el valor más cercano al fichero, salvo etiquetas, css y js, que se suman.
# contenido/blog/_datos.yml
plantilla: articulo
etiquetas: [blog]
url: "/blog/{{ titulo|slug }}/"
Detalle: datos.
Plantillas¶
Las plantillas son Twig. Se nombran con su ruta desde la raíz del proyecto.
{% extends 'plantillas/base.twig' %}
{% include 'parciales/cabecera.twig' %}
{% block cuerpo %}{{ pagina.contenido }}{% endblock %}
Tres variables: sitio (lo de sitio.yml), datos (los ficheros de datos/) y pagina (los campos de la página, más pagina.url, pagina.contenido, pagina.idioma, pagina.traducciones y pagina.encabezados).
{{ coleccion('blog') }} {# las páginas con esa etiqueta, de la más antigua a la más reciente #}
{{ lista|orden('fecha desc') }} {# ordena por uno o varios campos: 'orden, titulo' #}
{{ lista|limite(6) }} {# las seis primeras #}
{{ lista|invertir }} {# da la vuelta a la lista #}
{{ lista|sin(pagina) }} {# quita una página, normalmente la actual #}
{{ lista|donde('etiquetas', 'x') }} {# las que tienen ese valor en ese campo #}
{{ lista|anterior(pagina) }} {# la página anterior, o siguiente(pagina) #}
{{ titulo|slug }} {# un texto convertido en un tramo de dirección #}
{{ pagina.fecha|fecha('j F Y') }} {# una fecha con los meses en el idioma de la página #}
{{ campo|markdown }} {# un texto con formato, convertido a HTML #}
{{ svg('img/logo.svg') }} {# incrusta un SVG de publico/ #}
{{ dimensiones('img/foto.jpg') }} {# da el ancho y el alto de una imagen #}
{{ activo('/blog/') }} {# ¿estoy en esa página o dentro de ella? #}
{{ version('css/estilo.css') }} {# la dirección con una huella, para que se guarde en la caché #}
{{ css('css/base.css') }} {# declara CSS; {{ css() }} lo escribe todo donde lo pongas #}
{{ js('js/app.js') }} {# lo mismo con JavaScript; también css_fichero() y js_fichero() #}
Detalle: plantillas y colecciones.
Markdown y atajos¶
Markdown corriente, más tablas, notas al pie, tachado y enlaces automáticos. Un enlace a otro dominio se abre en otra pestaña. Los atajos son lo que el Markdown no tiene, sin lógica en el texto:
| Atajo | Qué da |
|---|---|
[imagen fichero="img/foto.jpg" alt="…" pie="…"] |
Una figura con su pie y sus medidas. |
[video url="https://www.youtube.com/watch?v=…" titulo="…"] |
Un vídeo de YouTube o Vimeo, o uno de publico/ con fichero. |
[archivo fichero="docs/tarifas.pdf" texto="Tarifas"] |
Un enlace con el tipo y el peso del fichero. |
[dato clave="cliente.nombre"] |
Un valor de datos/. |
Los atajos que defines tú pueden envolver texto, con la apertura ([aviso tipo="importante"]) y el cierre ([/aviso]) cada uno en su línea. Para cambiar el HTML de un atajo, o crear uno, escribe parciales/atajos/<nombre>.twig. Detalle: Markdown y atajos.
Una página por cada valor, y listas partidas¶
# contenido/etiqueta.md: una página por cada etiqueta de los artículos
agrupar:
coleccion: blog
campo: etiquetas
excluir: [blog]
url: "/etiqueta/{{ grupo|slug }}/"
# contenido/blog/index.md: el listado, de diez en diez
paginar:
coleccion: blog
porPagina: 10
orden: fecha desc
En la plantilla, pagina.paginas son las páginas del grupo o del trozo, y pagina.paginacion trae actual, total, entradas, anterior, siguiente y enlaces. Detalle: agrupar y paginar.
Varios idiomas¶
# sitio.yml: el primero es el predeterminado
idiomas:
- codigo: es
nombre: Castellano
- codigo: eu
nombre: Euskara
El idioma va en el nombre del fichero: contacto.md está en castellano y contacto.eu.md, en euskera. Los datos siguen la misma regla (menus.eu.yml). Las plantillas tienen pagina.traducciones y sitio.idiomas para escribir el selector de idioma. Detalle: multiidioma.
Borradores y publicación programada¶
borrador: sí no publica la página. publicar: 2026-12-01 la publica ese día, y publicarEnSuFecha: sí hace que ninguna página de la carpeta salga antes de su fecha. Es un sitio estático: sale cuando se vuelve a compilar después de esa fecha. Con servir --borradores lo ves todo.
Despliegue¶
| Destino | Campos de despliegue |
|---|---|
carpeta |
ruta: una carpeta de tu máquina, fuera del proyecto. |
ftp |
servidor, usuario, ruta, y puerto o cifrado: no si hace falta. |
sftp |
servidor, usuario, ruta y huella (la de la clave del servidor). |
s3 |
servidor, region, cubo, usuario y ruta. |
Los secretos van en .secretos.yml, nunca en sitio.yml: clave (o clavePrivada, la ruta de un fichero de clave) y frase. Ehundu apunta lo que sube en un fichero .ehundu.json del destino, y solo borra lo que subió él. Detalle: el despliegue.