Skip to content

Tudo para WordPress, desenvolvimento web — e não só

⚙️ Grav: definições e trechos de código usados com frequência (Markdown, Twig, editor Atom)

⚙️ Grav: definições e trechos de código usados com frequência (Markdown, Twig, editor Atom)

Quando já se trabalha com o Grav CMS há vários anos, acumula-se um conjunto de snippets que transitam de projeto em projeto. Frontmatter YAML, templates Twig, configurações de syntax highlighting, padrões regex do Atom: andar a vasculhar a documentação ou um repositório antigo de cada vez é perder tempo. Sobretudo quando o Grav está a correr num VPS e é preciso lembrar como instalar corretamente o driver sqlite para PHP 8.3 ou comentar o SetHandler depois de uma atualização do Apache.

Esta cheat sheet é uma destilação da prática real: cabeçalho padrão, definições de Markdown para páginas, snippets Twig no corpo do post, regex do Atom para pós-processamento de exportações.md e comandos de servidor Ubuntu. Tudo num só sítio, com explicações do quê e porquê.

💡 Visão geral rápida:

  • Configurar o frontmatter YAML do Grav com todos os campos: taxonomy, page-toc, highlight, process, page-addon personalizado
  • Definir a lógica de Markdown nos cabeçalhos de página: title, description, date, taxonomies, template
  • Adicionar código Twig ao corpo: tabela de conteúdos automática via toc(), galeria Unitegallery
  • Processar exportações.md do Writage no Atom: substituir media/ nos caminhos, passar classes para lazy load
  • Configurar o ambiente de servidor: SQLite, Memcached, PHP 8.3 no Ubuntu 24.04, editar php*.conf para o Virtualmin

Cabeçalho padrão do Grav para todas as páginas do site

O frontmatter YAML básico de uma página Grav inclui campos que o CMS lê durante o rendering. Abaixo está um modelo funcional que cobre as tarefas mais típicas: de taxonomias a flags personalizadas 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 ativa o plugin Page Toc (GitHub), que constrói uma tabela de conteúdos a partir de H1-H6 diretamente na página. template: blog_item define explicitamente o template de página filha de blog para que o Grav não o determine heuristicamente em cada renderização.

O bloco page-addon é uma secção personalizada para flags definidas pelo utilizador. Aqui ifarmelazy: true ativa o lazy loading para iframes: no ficheiro user/themes/g5_helium/custom/templates/partials/blog_item.html.twig uma condição é acionada, carregando o 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 inserir o próprio iframe (por exemplo, um vídeo do YouTube), utilize esta estrutura:

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>

Definições de Markdown para cabeçalhos de páginas de posts

Esta secção cobre os campos especificados no cabeçalho de cada post individual.

Título e descrição

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.'

A descrição vai para <meta name="description"> e é importante para os snippets dos resultados de pesquisa.

Data de criação e Auto Date

1date: '2026-06-14 10:00'

Para que a data seja definida automaticamente ao criar uma página, instale o plugin Auto Date, github.com/getgrav/grav-plugin-auto-date. Este insere a data e hora atuais se o campo date não for preenchido manualmente.

Taxonomias

Para uma única categoria e uma única tag, sintaxe plana:

1taxonomy:
2 category: WEB
3 tag: Markdown

Para múltiplos valores, utilize o formato de lista:

1taxonomy:
2 category:
3 - Grav
4 tag:
5 - Grav - Gantry 5
6 - Grav - Plugins

Índice da página e template

O Índice da página gera uma tabela de conteúdos a partir dos cabeçalhos dentro do corpo da página. Além da flag page-toc.active: true no cabeçalho, pode adicionar código Twig diretamente no template do tema (ver a secção Twig abaixo).

template: blog_item é especificado manualmente para que o Grav utilize de forma fiável o template de artigo de blog, uma vez que o CMS por vezes falha na deteção automática para páginas novas.

Pré-processadores Markdown e Twig

1process:
2 markdown: true
3 twig: true
4twig_first: true

twig_first: true significa que o Grav irá primeiro processar o motor de templates Twig e, em seguida, o Markdown. A ordem é crítica se o corpo da página contiver lógica Twig que gere markup Markdown.

Destaque de sintaxe (Highlight)

Depende do plugin Highlight, github.com/getgrav/grav-plugin-highlight.

1highlight:
2 enabled: true
3 lines: true

lines: true adiciona numeração de linhas nos blocos de código destacados.

Configurações Twig para o corpo da página

Tabela de conteúdos automática via toc()

O Índice da página pode funcionar não só a partir do cabeçalho, mas também através de inserção direta no template do tema. No ficheiro user/themes/g5_helium/custom/templates/partials/blog_item.html.twig, adicione:

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

A função Twig toc(page.content) analisa os cabeçalhos dentro de page.content e devolve uma árvore estruturada. A condição verifica a flag page-toc.active do cabeçalho, permitindo-lhe ativar e desativar a tabela de conteúdos para páginas individuais sem mexer no template.

Galeria de imagens via Unitegallery

O plugin Unitegallery, github.com/variar/grav-plugin-unitegallery, adiciona uma galeria ao Grav baseada na biblioteca JS Unitegallery com vários temas de visualização.

Após a instalação através do painel de administração ou do GPM (Grav Package Manager), uma única linha é adicionada ao corpo da página:

1{{ unite_gallery(page.media.images) | raw }}
2

Isto renderiza todas as imagens carregadas para a coleção de media da página como uma galeria.

Pesquisa e substituição no Atom para exportações do Writage.md

Ao exportar artigos do WordPress para Markdown via Writage, os caminhos das imagens contêm o prefixo media/, e ativar o lazy loading requer as classes figure-img e img-fluid. Editar manualmente cada URL é inútil; o Atom com expressões regulares faz isso num segundo.

O plugin Lazy Image trata do lazy loading, github.com/unsaturated/grav-plugin-lazy-image.

Localizar (expressão regular):

1(![.*]()(media/)(.*)())

Substituir pela variante lightbox (plugin FeatherLight):

1$1$3)

Substituir apenas por lazy loading:

1$1$3?classes=figure-img,img-fluid)

Após a substituição, a imagem recebe um parâmetro de consulta classes que o Lazy Image deteta.

Trabalhar com miniaturas

O Grav consegue manipular imagens dinamicamente: redimensionar, recortar, armazenar em cache. Uma miniatura de página define-se através de sintaxe Markdown com parâmetros de consulta:

1![ALT Image](https://learn.getgrav.org/20/content/media)

Mais informações sobre as capacidades de media na documentação oficial: learn.getgrav.org/content/media.

Configuração de servidor Ubuntu 24.04 para Grav

O Grav num VPS requer PHP, SQLite (para a base de dados interna dos plugins) e, de preferência, Memcached (para cache de páginas). Seguem-se os comandos atuais para Ubuntu 24.04 LTS e PHP 8.3.

Instalar PDO SQLite no PHP 8.3

1sudo apt-get update
2sudo apt-get install php8.3-sqlite
3sudo systemctl restart apache2

O SQLite é usado pelo Grav para armazenar registos, cache de plugins e gestão interna. Sem o driver, o painel de administração falha com um erro de ligação à base de dados.

Instalar o Memcached

Instruções atuais: 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

Ficheiros PHP não são executados após mudança de versão (Virtualmin/Webmin)

Depois de mudar de PHP 7.x para 8.3, o Apache pode servir ficheiros .php como texto em vez de os executar, um comportamento conhecido ao alterar módulos. O problema está nas diretivas SetHandler dentro da configuração do módulo PHP.

1sudo nano /etc/apache2/mods-enabled/php8.3.conf

Comente estas linhas:

1 # SetHandler application/x-httpd-php
2 # SetHandler application/x-httpd-php-source

Ficheiro php8.3.conf final após as edições:

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>

Depois de editar, reinicie o Apache:

1sudo systemctl restart apache2

Vídeo: o que é o Grav CMS e por onde começar

Uma breve introdução ao Grav para quem ouve falar de CMS flat-file pela primeira vez: o que está por baixo do capô, como o conteúdo é estruturado e porque é que funcionar sem uma base de dados pode ser mais rápido.

⁉️🤔 Perguntas frequentes

O Grav precisa de uma base de dados?

Não, o Grav é um CMS de ficheiros planos. Todo o conteúdo, configurações, taxonomias e metadados são armazenados em ficheiros de texto (Markdown e YAML). O SQLite é usado opcionalmente para necessidades internas: cache de plugins, registos, filas. O PostgreSQL e o MySQL não são oficialmente necessários. Na prática, isto significa que fazer uma cópia de segurança de um site é simplesmente copiar a pasta /user.

O plugin Page Toc é obrigatório para o índice de conteúdos?

Pode ser substituído por código Twig direto usando toc(page.content) no modelo do tema. Mas o plugin é mais conveniente para ativar/desativar rapidamente através de um sinalizador no frontmatter YAML de uma página específica. Se o seu site tiver mais de 50 páginas, gerir através do cabeçalho é mais prático do que ramificar no modelo.

Em que é que o Highlight difere do Prism.js ou do Highlight.js?

O Highlight é o plugin oficial do Grav que integra o highlight.js diretamente no pipeline de renderização. Ele entende os sinalizadores enabled e lines do cabeçalho YAML e não requer a inclusão manual de JS/CSS; o GPM trata de tudo. O Prism.js precisaria de ser incluído manualmente no tema.

O Grav ainda é relevante em 2026 comparado com o WordPress?

Para certos cenários, sim. O Grav ganha para sites estáticos de cartão de visita, portefólios, documentação e páginas de destino onde não são necessárias lógicas de utilizador complexas e comércio eletrónico. A arquitetura de ficheiros planos proporciona uma resposta instantânea sem base de dados, e o controlo de versões do conteúdo funciona através do Git. Mas para um blogue com milhares de publicações, uma biblioteca de media e arquivos dinâmicos, o WordPress é mais prático devido ao seu ecossistema de plugins.

O que devo fazer se o painel de administração do Grav deixar de funcionar após uma atualização do PHP?

Três causas típicas: (1) o php8.x-sqlite não está instalado e o Grav falha silenciosamente sem o driver da base de dados; (2) o SetHandler não está comentado no php8.x.conf ao usar o Virtualmin e o Apache serve .php como texto; (3) as permissões nas pastas cache/, logs/ e backup/ dentro de /user foram repostas, pelo que deve executar chown -R www-data:www-data user/.

Folha de dicas pronta: o que copiar para o seu projeto

Seis ficheiros e plugins que iniciam um projeto Grav típico num VPS: cabeçalho com taxonomias e page-toc, índice de conteúdos em Twig no modelo, pré-processador Markdown, Highlight, Unitegallery e regex Atom para exportações de pós-processamento. Adicione a configuração do servidor da secção Ubuntu 24.04 e terá um ambiente totalmente pronto em meia hora. Mantenha esta página nos favoritos; atualizamos os excertos para as versões atuais do Grav e do PHP.