Deixando links internos no pelican triviais

Traduções: en
20/01/2022

Uma funcionalidade interessante do Pelican, o gerador de site estático que eu uso para esse blog, é a sintaxe de expansão de links internos usando {}. Ela está documentada aqui. Alguns exemplos são {filename}, {static} e {author}. O propósito da sintaxe é ter apelidos mais curtos e fáceis na hora de linkar com conteúdo interno no blog. Por exemplo, {filename} pode ser usado para linkar com outros arquivos, como artigos.

A ideia é boa, mas para o meu uso ela não é o suficiente. Onde eu preciso realmente de expansão de links internos no meu blog é para imagens, artigos e código.

Imagens

A ideia para imagens é bem simples. Eu escrevo meus artigos em rst, e é assim que uma imagem é incluída nesse formato:

.. image:: caminho/ate/imagem.jpg

O jeito que eu estruturo os arquivos no meu blog (que você pode ver no repositório do blog), é que dentro da pasta content onde todo conteúdo fica, os fontes dos artigos podem ser encontrados dentro de articles/<ano>/, e as imagens podem ser encontradas em images/<id_artigo>/, onde <id_artigo> é a string que identifica o artigo no qual a imagem aparece (ele é a propriedade trans_id do artigo, derivada do nome do arquivo e usada para associar traduções de um mesmo artigo, mas eu estou chamando de id_artigo aqui já que faz mais sentido nesse contexto).

Dada essa estrutura, se eu usar um caminho relativo do artigo até uma de suas imagens, ele teria que ser algo como ../../images/<id_artigo>/nome_da_imagem.jpg. A expansão {static} pode ser usada para simplificá-lo um pouco: {static}/images/<id_artigo>/nome_da_imagem.jpg. Mas dá para fazer melhor 🙂.

Seria muito melhor se esse caminho pudesse ser bastante encurtado. Todas as imagens estão dentro da pasta images/, então isso deveria estar implícito. Quer saber, já que já estamos aqui mesmo, por que não fazer a parte <id_artigo>/ ser derivada do id do artigo atual. Isso deixaria o link perfeito, já que apenas sobraria o nome da imagem, que é a parte dele que é única.

O primeiro passo para implementar essa lógica customizada foi adicionar o plugin linker no pelican. Ele permite que você implemente suas próprias expansões de links {} através de classes em python.

E o segundo passo foi implementar a expansão {image} através desse commit. Esse é o commit onde eu atualizei todos os links de imagem para usar {image}. Sinta o prazer! Ficou muito mais enxuto 🙂.

Artigos

Linkar com outros artigos é um pouco mais complicado, mas não tanto. A ideia é, às vezes eu quero referenciar outro artigo que eu escrevi anteriormente no blog. Usando a expansão {filename}, não fica tão ruim:

Eu mostrei isso `em um artigo anterior`__.

.. __: {filename}08-task-context-br.rst

Mas com certeza poderia ser melhor. A expansão {filename} é relativa ao arquivo atual, então se eu estou referenciando um artigo do mesmo ano, fica igual nesse exemplo mesmo, mas referenciar um de outro ano requer um ../<ano>/ adicional no caminho. Além disso, eu não deveria precisar escrever o nome do arquivo inteiro. Idealmente eu só deveria precisar escrever o que é único ao artigo, ou seja, o seu id_artigo. Sim, até o sufixo da língua (-en ou -br) pode ser omitido, já que eu posso derivá-lo da língua do artigo atual.

Até agora tudo bem, isso poderia ser feito com um pouco mais de lógica além do que eu fiz para o {image}. Mas já que eu já estou melhorando as coisas, eu gostaria de aproveitar essa chance para padronizar melhor o texto que eu uso nesses links. Tudo bem, usar um texto como "em um artigo anterior" se encaixa bem com o texto à sua volta, mas não fica imediatamente óbvio que o link é para um outro artigo no meu blog.

Então a ideia é ter uma expansão de link que não só mapeia para o caminho correto do artigo, mas também automaticamente muda seu texto para conter o título do artigo. Um toque final é que eu quero que esse texto leve em consideração a língua do artigo: se está em português, o formato deve ser 'artigo "Título do artigo"' e se está em inglês, '"Título do artigo" post'.

Atualizar o texto do link não é algo que o plugin linker consegue fazer por padrão, então eu primeiro precisei estendê-lo para permitir isso nesse commit. Com o mecanismo base feito, eu de fato implementei a nova expansão {article} nesse commit.

Todo esse trabalho vale a pena, já que agora eu posso te mostrar como o resultado ficou te apontando para o primeiro artigo que eu escrevi nesse blog usando um simples {article}tasklist: artigo "Criando listas de filmes e jogos usando Taskwarrior"

Claro que eu também atualizei todas as referências a artigos no blog para usar essa nova e excelente expansão nesse commit.

Código

É aqui que complica... Bem, como você deve saber, é bem comum os artigos do meu blog, por serem técnicos, terem blocos de código no meio do texto. Eu incluo esses códigos usando a diretiva rst include e passando para ela o caminho de um arquivo separado que contém o código.

O problema é, diferentemente da diretiva rst image e os links rst cujos alvos aparecem no HTML final, o que torna bem simples editá-los dentro do pelican, a diretiva include e seu caminho são processados pelo leitor rst em um estágio anterior. Isso significa que os métodos normais para mudar um link no pelican não podem ser usados aqui (como o plugin linker).

Eu poderia colocar o código direto no fonte do artigo ao invés de usar a diretiva include e evitar todo esse problema, mas quando o código tem mais do que algumas linhas, eu sinto que isso poluiria muito o arquivo fonte do artigo.

Bem, se você já leu o artigo "Customizações do blog" você deve lembrar que eu já tenho um leitor rst customizado. Então para implementar uma expansão de link para código, eu precisava extender esse leitor para substituir qualquer ocorrência de {code} dentro de uma diretiva include pelo caminho do arquivo de código. Foi isso que eu fiz nesse commit, copiando o código do leitor rst do pelican e fazendo algumas mudanças.

Vale a pena dizer que esse tipo de customização que estou fazendo (e já estava fazendo) de sobrescrever o leitor rst não é bem estável. Se houverem mudanças no leitor rst do pelican, eu posso ter que parar de atualizar o pelican ou reimplementar as mudanças deles no meu leitor customizado. Mas já que não tinha um jeito menos intrusivo de implementar essa funcionalidade, eu resolvi correr esse risco.

Apesar das mudanças não muito atraentes, no fim tudo vale a pena quando você vê a melhora nos arquivos fontes dos artigos. Esse é o commit onde eu atualizei eles para usar a nova expansão {code}. Duvido que você diga que não valeu a pena (por favor não diga).

Conclusão

E aqui estamos. Deu um certo trabalho, mas depois dessas mudanças, nunca foi tão fácil de fazer links internos no meu blog! Tudo que deixa mais fácil de escrever artigos para o blog vale muito a pena para mim.