Skip to content

Todo para WordPress, el desarrollo web — y mucho más

⚙️ Grav: ajustes y fragmentos de código de uso frecuente (Markdown, Twig, editor Atom)

⚙️ 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.

1title: ''
2date: '2026-06-14 10:00'
3published: true
4media_order: poster.jpg
5metadata:
6 description: ''
7taxonomy:
8 category:
9 - WordPress
10 tag:
11 - WordPress - Plugins
12 - WordPress - Admin
13page-toc:
14 active: true
15template: blog_item
16highlight:
17 enabled: true
18 lines: true
19page-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

1title: 'Grav + Gantry 5 — an overview of useful extensions and resources'
2metadata:
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

1date: '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:

1taxonomy:
2 category: WEB
3 tag: Markdown

Para múltiples valores, utilice el formato de lista:

1taxonomy:
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

1process:
2 markdown: true
3 twig: true
4twig_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.

1highlight:
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{#
3page-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![ALT Image](https://learn.getgrav.org/20/content/media)

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

1sudo apt-get update
2sudo apt-get install php8.3-sqlite
3sudo 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/.

1sudo apt-get update
2sudo apt-get install memcached
3
4sudo add-apt-repository ppa:ondrej/php
5sudo apt-get update
6sudo apt-get install -y php php-dev php-pear libapache2-mod-php
7
8sudo apt-get install -y php-memcached
9
10sudo 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.

1sudo 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&lt;filesmatch &quot;.+\.ph(ar|p|tml)$&quot;&gt;
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&lt;filesmatch &quot;^\.ph(ar|p|ps|tml)$&quot;&gt;
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:

1sudo 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 enabled y lines del 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-sqlite no está instalado, y Grav falla silenciosamente sin el controlador de base de datos; (2) SetHandler no está comentado en php8.x.conf al usar Virtualmin, y Apache sirve .php como texto; (3) los permisos en las carpetas cache/, logs/ y backup/ dentro de /user se han restablecido, por lo que debe ejecutar chown -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.