Ir al contenido
Código en GitHub (se abre en una pestaña nueva)

Documentación · Empezar

Tu primer sitio

Instala Ehundu, crea un sitio con un menú y un blog, míralo en el navegador y publícalo.

Versión 0.16

En este recorrido instalas Ehundu y construyes un sitio pequeño con una portada, una página, un menú y un blog. Es lo justo para entender cómo se piensa un proyecto. Te llevará unos veinte minutos.

Antes de empezar

Necesitas PHP 8.4 o superior con la extensión mbstring. Comprueba tu versión:

php --version

Si dice 8.4 o más, y php -m incluye mbstring, ya puedes seguir.

1. Instala Ehundu

Ehundu es un solo fichero, ehundu.phar. Descárgalo de la última versión y déjalo donde quieras:

curl -L -o ehundu.phar https://github.com/ehundu/ehundu/releases/latest/download/ehundu.phar
php ehundu.phar --version

Debería decirte Ehundu y el número de la versión. En Windows, en lugar de curl puedes usar el navegador o Invoke-WebRequest. Si prefieres Composer, composer require ehundu/ehundu lo instala y la orden es vendor/bin/ehundu.

En lo que sigue escribo php ehundu.phar. Si lo has instalado con Composer, cámbialo por vendor/bin/ehundu.

2. Crea el proyecto

Un proyecto es una carpeta. Crea una y entra en ella:

mkdir mi-sitio
cd mi-sitio

Lo único obligatorio es un fichero sitio.yml con el nombre del sitio y la dirección del dominio donde vivirá, sin ruta:

nombre: Mi primer sitio
url: https://ejemplo.com

3. Escribe una página y su plantilla

Las páginas viven en la carpeta contenido/. Se escriben en Markdown, con unos datos al principio entre dos líneas de guiones (se llama «front matter»). Crea contenido/index.md:

---
titulo: Hola, mundo
---
Esta es mi primera página con Ehundu.

Cada página necesita una plantilla que la envuelva en HTML. Se escriben en Twig, y la que se usa por defecto es plantillas/pagina.twig. Crea ese fichero:

<!doctype html>
<html lang="{{ pagina.idioma }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{ pagina.titulo }} · {{ sitio.nombre }}</title>
</head>
<body>
  <h1>{{ pagina.titulo }}</h1>
  {{ pagina.contenido }}
</body>
</html>

pagina es la página que se está construyendo: ahí están su título, su texto ya convertido a HTML (pagina.contenido) y cualquier otro dato del front matter. sitio es lo que escribiste en sitio.yml.

4. Míralo

php ehundu.phar servir

Ehundu compila el sitio y te dice dónde verlo: http://127.0.0.1:8000/. Ábrelo en el navegador. Deja la orden en marcha: cada vez que guardes un cambio rehace solo lo que hace falta, y basta con recargar la página. Con Ctrl+C se para.

Cuando quieras el sitio terminado, compílalo:

php ehundu.phar compilar

Aparece una carpeta salida/ con HTML normal y corriente, lista para subir a cualquier servidor.

5. Otra página y un menú

Cada fichero de contenido/ es una página, y su dirección sale de su nombre. Crea contenido/sobre-mi.md, que será /sobre-mi/:

---
titulo: Sobre mí
---
Me llamo Ana y esta es **mi web**.

Para que se pueda llegar a ella, un menú. Los datos que se repiten en varias páginas van en la carpeta datos/, uno por fichero. Crea datos/menu.yml:

- texto: Inicio
  enlace: /
- texto: Sobre mí
  enlace: /sobre-mi/
- texto: Blog
  enlace: /blog/

Y los trozos de HTML que se reutilizan van en parciales/. Crea parciales/menu.twig:

<nav>
  <ul>
    {% for entrada in datos.menu %}
    <li><a href="{{ entrada.enlace }}"{% if activo(entrada.enlace) %} aria-current="page"{% endif %}>{{ entrada.texto }}</a></li>
    {% endfor %}
  </ul>
</nav>

datos.menu es el contenido de datos/menu.yml, y activo() dice si estás en esa página. Falta el parcial en las plantillas. Para no repetir la estructura en cada una, pasa lo común a plantillas/base.twig:

<!doctype html>
<html lang="{{ pagina.idioma }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{ pagina.titulo }} · {{ sitio.nombre }}</title>
</head>
<body>
  {% include 'parciales/menu.twig' %}
  <main>
    {% block cuerpo %}{% endblock %}
  </main>
</body>
</html>

Y deja plantillas/pagina.twig en lo que es propio de una página:

{% extends 'plantillas/base.twig' %}

{% block cuerpo %}
  <h1>{{ pagina.titulo }}</h1>
  {{ pagina.contenido }}
{% endblock %}

Con la previsualización en marcha, recarga: ya hay menú en las dos páginas.

6. Un blog

Crea una carpeta contenido/blog/ con un fichero _datos.yml. Todo lo que pongas ahí lo heredan las páginas de la carpeta:

etiquetas: [blog]
url: "/blog/{{ titulo|slug }}/"

Así, cada página de blog/ pertenece a la colección blog, y su dirección sale de su título («Mi primera entrada» pasa a ser /blog/mi-primera-entrada/). Escribe dos entradas, con una fecha cada una. Por ejemplo, contenido/blog/primera-entrada.md:

---
titulo: Mi primera entrada
fecha: 2026-10-15
---
Hoy empiezo un blog.

Y contenido/blog/otra-mas.md, con otro título y otra fecha. Ahora la página que las lista, contenido/blog/index.md. Lleva su propia dirección y usa otra plantilla, lista:

---
titulo: Blog
plantilla: lista
url: /blog/
---

Y la plantilla plantillas/lista.twig recorre la colección:

{% extends 'plantillas/base.twig' %}

{% block cuerpo %}
  <h1>{{ pagina.titulo }}</h1>
  <ul>
    {% for entrada in coleccion('blog')|sin(pagina)|orden('fecha desc') %}
    <li><a href="{{ entrada.url }}">{{ entrada.titulo }}</a>, {{ entrada.fecha|fecha }}</li>
    {% endfor %}
  </ul>
{% endblock %}

coleccion('blog') son las páginas con esa etiqueta. sin(pagina) quita la propia lista, que por estar en la carpeta también la lleva. orden('fecha desc') pone la más reciente primero, y fecha escribe el día en tu idioma: «20 de octubre de 2026».

7. Publícalo

Dile a Ehundu adónde subir el sitio. Añade a sitio.yml la sección despliegue (aquí, por SFTP):

despliegue:
  destino: sftp
  servidor: sftp.ejemplo.com
  usuario: ana
  ruta: /home/ana/www

La contraseña no va nunca en sitio.yml, que se comparte y se versiona. Va en un fichero .secretos.yml, en la raíz del proyecto, entre comillas simples:

despliegue:
  clave: 'la-contraseña'

Antes de subir nada, mira qué haría:

php ehundu.phar desplegar --simular

La primera vez, con SFTP, se detiene y te da la huella del servidor para que la compruebes con quien lo administra y la anotes en sitio.yml (huella:). Cuando todo cuadre:

php ehundu.phar desplegar

Compila el sitio y sube solo lo nuevo o lo que ha cambiado. Si usas Git, no versiones ni salida/ ni .ehundu/ ni .secretos.yml. También puedes publicar en una carpeta, por FTP o en un cubo S3: cambia el destino.

Y ahora, ¿qué?