
⚙️ Grav: ajustes y fragmentos de código de uso frecuente (Markdown, Twig, editor Atom)
Cuando ha trabajado con Grav CMS durante varios años, acumula un conjunto de fragmentos que viajan de proyecto en proyecto. Frontmatter YAML, plantillas Twig, configuraciones de resaltado de sintaxis, patrones regex de Atom: excavar en la documentación o en un repositorio antiguo cada vez es una pérdida de tiempo. Especialmente cuando Grav corre en un VPS y necesita recordar cómo instalar correctamente el controlador sqlite para PHP 8.3 o comentar SetHandler después de una actualización de Apache.
Esta hoja de referencia es una destilación de la práctica real: encabezado predeterminado, configuraciones de Markdown para páginas, fragmentos Twig en el cuerpo de la entrada, regex de Atom para el posprocesamiento de exportaciones.md y comandos de servidor Ubuntu. Todo en un solo lugar, con explicaciones del qué y el porqué.
💡 Resumen rápido:
- Configure el frontmatter YAML de Grav con todos los campos: taxonomía, page-toc, highlight, process, page-addon personalizado
- Establezca la lógica Markdown en los encabezados de página: título, descripción, fecha, taxonomías, plantilla
- Añada código Twig al cuerpo: tabla de contenidos automática mediante
toc(), galería Unitegallery - Procese exportaciones de Writage.md en Atom: reemplazo de media/ en rutas, paso de clases para carga diferida
- Configure el entorno del servidor: SQLite, Memcached, PHP 8.3 en Ubuntu 24.04, edición de php*.conf para Virtualmin
Encabezado predeterminado de Grav para todas las páginas del sitio
El frontmatter YAML básico de una página Grav incluye campos que el CMS lee durante el renderizado. A continuación se muestra una plantilla funcional que cubre la mayoría de las tareas típicas: desde taxonomías hasta indicadores personalizados de page-addon.
1 title: '' 2 date: '2026-06-14 10:00' 3 published: true 4 media_order: poster.jpg 5 metadata: 6 description: '' 7 taxonomy: 8 category: 9 - WordPress 10 tag: 11 - WordPress - Plugins 12 - WordPress - Admin 13 page-toc: 14 active: true 15 template: blog_item 16 highlight: 17 enabled: true 18 lines: true 19 page-addon: 20 ifarmelazy: true
page-toc.active: true activa el plugin Page Toc (GitHub), que construye una tabla de contenidos a partir de H1-H6 directamente en la página. template: blog_item establece explícitamente la plantilla de página hija del blog para que Grav no la determine heurísticamente en cada renderizado.
El bloque page-addon es una sección personalizada para indicadores definidos por el usuario. Aquí ifarmelazy: true habilita la carga diferida para iframes: en el archivo user/themes/g5_helium/custom/templates/partials/blog_item.html.twig se dispara una condición, cargando el script iframe.ly.
1 {% if attribute(page.header, 'page-addon').ifarmelazy %} 2 <script async charset="utf-8" src="//cdn.iframe.ly/embed.js"></script> 3 {% endif %} 4
Para insertar el iframe en sí (por ejemplo, un video de YouTube), utilice esta estructura:
1 <iframe allowfullscreen 2 data-iframely-url="https://www.youtube.com/embed/54WI1XSilb4" 3 scrolling="no" 4 style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;"> 5 </iframe>
Configuraciones de Markdown para encabezados de páginas de entrada
Esta sección cubre los campos especificados en el encabezado de cada entrada individual.
Título y descripción
1 title: 'Grav + Gantry 5 — an overview of useful extensions and resources' 2 metadata: 3 description: 'A collection of Grav extensions for Gantry 5 that speed up work with content and templates.'
La descripción va dentro de <meta name="description"> y es importante para los fragmentos de resultados de búsqueda.
Fecha de creación y Auto Date
1 date: '2026-06-14 10:00'
Para que la fecha se establezca automáticamente al crear una página, instale el plugin Auto Date, github.com/getgrav/grav-plugin-auto-date. Este inserta la fecha y hora actuales si el campo date no se completa manualmente.
Taxonomías
Para una sola categoría y una sola etiqueta, sintaxis plana:
1 taxonomy: 2 category: WEB 3 tag: Markdown
Para múltiples valores, utilice el formato de lista:
1 taxonomy: 2 category: 3 - Grav 4 tag: 5 - Grav - Gantry 5 6 - Grav - Plugins
Índice de página y plantilla
El índice de página genera una tabla de contenidos a partir de los encabezados dentro del cuerpo de la página. Además del indicador page-toc.active: true en el encabezado, puede añadir código Twig directamente a la plantilla del tema (consulte la sección de Twig más abajo).
template: blog_item se especifica manualmente para que Grav utilice de forma fiable la plantilla de entrada de blog, ya que el CMS a veces falla en la detección automática para páginas nuevas.
Preprocesadores Markdown y Twig
1 process: 2 markdown: true 3 twig: true 4 twig_first: true
twig_first: true significa que Grav procesará primero el motor de plantillas Twig y luego Markdown. El orden es crítico si el cuerpo de la página contiene lógica Twig que genera marcado Markdown.
Resaltado de sintaxis (Highlight)
Depende del plugin Highlight, github.com/getgrav/grav-plugin-highlight.
1 highlight: 2 enabled: true 3 lines: true
lines: true añade numeración de líneas en los bloques de código resaltados.
Configuración de Twig para el cuerpo de la página
Tabla de contenidos automática mediante toc()
El índice de página puede funcionar no solo desde el encabezado, sino también mediante inserción directa en la plantilla del tema. En el archivo user/themes/g5_helium/custom/templates/partials/blog_item.html.twig, añada:
1 {# PAGE TOC START #} 2 {# 3 page-toc: 4 active: true 5 #} 6 {% if attribute(page.header, 'page-toc').active %} 7 {% set table_of_contents = toc(page.content) %} 8 {% if table_of_contents is not empty %} 9 Table of contents: 10 {{ table_of_contents|raw }} 11 {% endif %} 12 13 {% endif %} 14 {# PAGE TOC END #} 15
La función Twig toc(page.content) analiza los encabezados dentro de page.content y devuelve un árbol estructurado. La condición verifica el indicador page-toc.active del encabezado, lo que le permite activar y desactivar la tabla de contenidos para páginas individuales sin modificar la plantilla.
Galería de imágenes mediante Unitegallery
El plugin Unitegallery, github.com/variar/grav-plugin-unitegallery, añade una galería a Grav basada en la biblioteca JS Unitegallery con varios temas de visualización.
Tras la instalación a través del panel de administración o GPM (Gestor de Paquetes de Grav), se añade una sola línea al cuerpo de la página:
1 {{ unite_gallery(page.media.images) | raw }} 2
Renderiza todas las imágenes subidas a la colección multimedia de la página como una galería.
Búsqueda y reemplazo en Atom para exportaciones de Writage.md
Al exportar entradas de WordPress a Markdown mediante Writage, las rutas de las imágenes contienen el prefijo media/, y habilitar la carga diferida requiere las clases figure-img e img-fluid. Editar manualmente cada URL no tiene sentido; Atom con expresiones regulares lo hace en un segundo.
El plugin Lazy Image gestiona la carga diferida, github.com/unsaturated/grav-plugin-lazy-image.
Buscar (expresión regular):
1 (![.*]()(media/)(.*)())
Reemplazar con variante lightbox (plugin FeatherLight):
1 $1$3)
Reemplazar solo con carga diferida:
1 $1$3?classes=figure-img,img-fluid)
Tras el reemplazo, la imagen recibe un parámetro de consulta classes que Lazy Image detecta.
Trabajar con miniaturas
Grav puede manipular imágenes dinámicamente: redimensionar, recortar, cachear. Una miniatura de página se establece mediante sintaxis Markdown con parámetros de consulta:
1 
Más sobre las capacidades multimedia en la documentación oficial: learn.getgrav.org/content/media.
Configuración de servidor Ubuntu 24.04 para Grav
Grav en un VPS requiere PHP, SQLite (para la base de datos interna de plugins) y, preferiblemente, Memcached (para el caché de páginas). A continuación se muestran los comandos actuales para Ubuntu 24.04 LTS y PHP 8.3.
Instalar PDO SQLite en PHP 8.3
1 sudo apt-get update 2 sudo apt-get install php8.3-sqlite 3 sudo systemctl restart apache2
Grav utiliza SQLite para almacenar registros, caché de plugins y tareas internas de contabilidad. Sin el controlador, el panel de administración fallará con un error de conexión a la base de datos.
Instalar Memcached
Instrucciones actuales: tecadmin.net/install-memcached-with-php-on-ubuntu/.
1 sudo apt-get update 2 sudo apt-get install memcached 3 4 sudo add-apt-repository ppa:ondrej/php 5 sudo apt-get update 6 sudo apt-get install -y php php-dev php-pear libapache2-mod-php 7 8 sudo apt-get install -y php-memcached 9 10 sudo systemctl restart apache2
Los archivos PHP no se ejecutan tras un cambio de versión (Virtualmin/Webmin)
Tras cambiar de PHP 7.x a 8.3, Apache puede servir los archivos .php como texto en lugar de ejecutarlos, un comportamiento conocido al cambiar de módulos. El problema está en las directivas SetHandler dentro de la configuración del módulo PHP.
1 sudo nano /etc/apache2/mods-enabled/php8.3.conf
Comente estas líneas:
1 # SetHandler application/x-httpd-php 2 # SetHandler application/x-httpd-php-source
Archivo php8.3.conf final después de las modificaciones:
1 <filesmatch ".+\.ph(ar|p|tml)$"> 2 # SetHandler application/x-httpd-php 3 </filesmatch> 4 <filesmatch ".+\.phps$"> 5 # SetHandler application/x-httpd-php-source 6 # Deny access to raw php sources by default 7 # To re-enable it's recommended to enable access to the files 8 # only in specific virtual host or directory 9 Require all denied 10 </filesmatch> 11 12 # Deny access to files without filename (e.g. '.php') 13 <filesmatch "^\.ph(ar|p|ps|tml)$"> 14 Require all denied 15 </filesmatch> 16 17 # Running PHP scripts in user directories is disabled by default 18 # 19 # To re-enable PHP in user directories comment the following lines 20 # (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it 21 # prevents .htaccess files from disabling it. 22 <ifmodule mod_userdir.c=""> 23 <directory /home/*/public_html> 24 php_admin_flag engine Off 25 </directory> 26 </ifmodule>
Después de editar, reinicie Apache:
1 sudo systemctl restart apache2
Vídeo: qué es Grav CMS y por dónde empezar
Una breve introducción a Grav para quienes oyen hablar por primera vez de un CMS de archivos planos: qué hay bajo el capó, cómo se estructura el contenido y por qué funcionar sin una base de datos puede ser más rápido.
⁉️🤔 Preguntas frecuentes
¿Grav requiere una base de datos?
No, Grav es un CMS de archivos planos. Todo el contenido, la configuración, las taxonomías y los metadatos se almacenan en archivos de texto (Markdown y YAML). SQLite se usa de forma opcional para necesidades internas: caché de plugins, registros, colas. PostgreSQL y MySQL no son requeridos oficialmente. En la práctica, esto significa que hacer una copia de seguridad de un sitio es simplemente copiar la carpeta
/user.
¿Es obligatorio el plugin Page Toc para la tabla de contenidos?
Se puede reemplazar con código Twig directo usando
toc(page.content)en la plantilla del tema. Pero el plugin es más conveniente para activar o desactivar rápidamente mediante una bandera en el frontmatter YAML de una página específica. Si su sitio tiene más de 50 páginas, gestionarlo a través del encabezado es más práctico que ramificar en la plantilla.
¿En qué se diferencia Highlight de Prism.js o Highlight.js?
Highlight es el plugin oficial de Grav que integra highlight.js directamente en el proceso de renderizado. Entiende las banderas
enabledylinesdel encabezado YAML y no requiere la inclusión manual de JS/CSS; GPM se encarga de todo. Prism.js necesitaría incluirse manualmente en el tema.
¿Sigue siendo relevante Grav en 2026 comparado con WordPress?
Para ciertos escenarios, sí. Grav gana para sitios de tarjeta de presentación estáticos, portafolios, documentación y páginas de aterrizaje donde no se necesita lógica de usuario compleja ni comercio electrónico. La arquitectura de archivos planos proporciona una respuesta instantánea sin base de datos, y el control de versiones del contenido funciona a través de Git. Pero para un blog con miles de publicaciones, una biblioteca multimedia y archivos dinámicos, WordPress es más práctico debido a su ecosistema de plugins.
¿Qué debo hacer si el panel de administración de Grav deja de funcionar después de una actualización de PHP?
Tres causas típicas: (1)
php8.x-sqliteno está instalado, y Grav falla silenciosamente sin el controlador de base de datos; (2)SetHandlerno está comentado enphp8.x.confal usar Virtualmin, y Apache sirve.phpcomo texto; (3) los permisos en las carpetascache/,logs/ybackup/dentro de/userse han restablecido, por lo que debe ejecutarchown -R www-data:www-data user/.
Hoja de referencia lista para usar: qué copiar en su proyecto
Seis archivos y plugins que inician un proyecto Grav típico en un VPS: encabezado con taxonomías y page-toc, tabla de contenidos Twig en la plantilla, preprocesador Markdown, Highlight, Unitegallery y regex Atom para exportaciones de posprocesamiento. Añada la configuración del servidor de la sección Ubuntu 24.04 y tendrá un entorno completamente listo en media hora. Guarde esta página en sus marcadores; actualizamos los fragmentos para las versiones actuales de Grav y PHP.



