HUGO v163

Como implementei um site multilíngue em Hugo com um arquivo por artigo, sem prefixo para o idioma padrão e recursos junto ao conteúdo.

Depois de vários experimentos, finalmente simplifiquei a estrutura do site para que seja realmente fácil de manter. Agora, todo o conteúdo multilíngue vive em um único arquivo .md por artigo, os recursos (imagens, PDFs) ficam junto ao artigo, e o idioma padrão —espanhol— é servido sem prefixo na URL.

Organização dos artigos

Chega de pastas por ano. Cada artigo é um arquivo .md colocado diretamente em content/blog/, ou uma pasta com um index.md e seus recursos. Por exemplo:

content/blog/
├── 20250601_antena_moxon.md        # artigo sem imagens
└── 20250701_restauracao_bc348/     # artigo com fotos e documentos
    ├── index.md
    ├── fotos/
    │   ├── antes.jpg
    │   └── depois.jpg
    └── doc/
        └── esquema.pdf

Se o artigo não tiver imagens, um arquivo .md basta. Se precisar de anexos, cria-se uma pasta com o slug do artigo e coloca-se os arquivos lá dentro.

Multilíngue sem atrito

O Hugo gerencia idiomas, mas a abordagem tradicional obrigava a duplicar conteúdo em pastas por idioma. Neste site:

  • O idioma padrão é o espanhol, servido na raiz (/post/).
  • Os outros idiomas são servidos com prefixo: /en/post/ e /pt-br/post/.
  • Todo o conteúdo traduzido fica no mesmo arquivo .md como campos content_es, content_en, content_pt-br do front matter. Títulos, descrições e leads também podem ser definidos por idioma.

Exemplo de front matter:

content_es: |
  Este es el artículo en español.

content_en: |
  This is the article in English.

content_pt-br: |
  Este é o artigo em português.

Os templates simplesmente exibem o campo correspondente ao idioma ativo. Se uma tradução não existir, o conteúdo em espanhol é usado como fallback.

Adeus aos data files

Em uma versão anterior, usei arquivos YAML externos em /data/ para armazenar as traduções. Mostrou-se trabalhoso: dois arquivos por artigo, buscas adicionais, e os data files não aparecem nos resultados de busca do Hugo. Voltei a colocar tudo dentro do .md: um artigo, um arquivo, todos os idiomas.

Recursos junto ao artigo

Eliminei static/post-images/. Agora, as imagens e documentos de cada artigo ficam em uma subpasta (fotos/, doc/, etc.) dentro da pasta do artigo. Vantagens:

  • Os recursos viajam com o artigo (fácil mover, renomear ou excluir).
  • Caminhos relativos no Markdown são mais simples: ![antes](fotos/antes.jpg).
  • Imagens de diferentes artigos não se misturam em um único diretório gigante.

Template único para renderização

Um renderizador comum lê o .Page (seja uma página simples ou um _index.md de seção), extrai o campo de conteúdo para o idioma atual e o passa por markdownify. Os resumos também pegam o lead traduzido ou os primeiros parágrafos do conteúdo correspondente.

Resultado

Com esse esquema:

  • Publicar um artigo novo é criar um arquivo e escrever.
  • Adicionar imagens é colocá-las em uma subpasta dentro do artigo.
  • Adicionar um idioma é copiar e traduzir um bloco YAML dentro do mesmo arquivo.
  • URLs permanecem limpas e canônicas: /meu-post/, /en/meu-post/, /pt-br/meu-post/.

Uma estrutura enxuta e autossuficiente, sem dependências externas, fácil de manter e escalar.