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.
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 🙂.
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.
É 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).
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.