Criando posts com Makefile
Bem, como automatizar a criação de novos posts? Percebi aqui que criar um novo post estava tendo um custo mental que eu não gostaria de ter.
Então, qual a receita que eu tinha para criar um post? Com exceção de seu conteúdo, claro… e como automatizar isso?
O processo de criação de um post
Normalmente, o post acaba sendo criado seguindo os seguintes passos:
- copiar um
draft
anterior e renomear o arquivo gerado - apagar seu conteúdo
- mudar informações de título e tags no frontmatter
Agora, por que isso? Basicamente, percebi que o meu intuito era apenas:
- ter um arquivo
.md
dentro do diretório de rascunhos,_drafts
- ter um frontmatter padrão para trabalhar e customizar
E só.
Customizações no frontmatter
Meu frontmatter ainda é bem simples. Ele é composto de 4 campos padrões e um outro me customizado:
layout
: sempre épost
quando faço uma postagemtitle
: este muda de um post para outroauthor
: sempre eutags
: depende do postbase-assets
: sempre no format/assets/RDX/
, se tiver assets, videbase-assets
Aqui, o base-assets
as vezes não tem no post (como, por exemplo, neste post). Mas, independente da
situação, se tiver o base-assets
bem definido, seria mais fácil removê-lo do que criar do zero.
Agora, como se define o RDX
? Simples, se o meu arquivo de post se chama new-post.md
, então
o radix seria simplesmente new-post
.
Portanto, o que de fato se customiza para a minha postagem?
- título
- tags
Todo o resto é definido previamente, inclusive o base-assets
baseado no nome do arquivo.
Usando make
Podemos usar o Makefile
para criar um novo post. Como fazer isso? Simples, criar uma regra
para _drafts/%.md
. Em cima dessa regra eu consigo tranquilamente chamar um script de criação
de post.
O melhor de tudo é que, como não tem dependência nessa regra, ela detecta quando um arquivo já existe, assim evitando choque de criação de arquivos.
Exemplo de comando para criar este post:
make _drafts/new-post.md
E pronto, as regras de criação do alvo são disparadas.
Personalizando o script
Basicamente, precisamos apenas saber qual o nome do arquivo que será gerado, o título do blog post e as tags.
Em um mundo ideal, tags anteriores seriam todas lidas (sejam de posts, sejam de rascunho) e teria uma interface gráfica para ajudar na seleção. Mas por hora estou fazendo apenas um shell rápido, isto está fora de cogitação e portanto o usuário deverá dar o input pelo teclado memso. Fica para um próximo momento.
Como o script poderá ser invocado pelo Makefile
, um jeito bem prático de permitir que ele passe
a informação adiante é que o nome do arquivo seja um argumento de chamada da CLI. Portanto, coloquei
para que, caso exista algum argumento na linha de comando, ele seja o nome do arquivo. Novamente isto
daqui não foi ótimo porque deveria ter sempre a opção do help
. Mas a ideia aqui é mais um script
pequeno quase descartável para me ajudar a automatizar alguns poucos processos.
Seguindo o exemplo do publish-draft
, vou forçar
a que o usuário passe o caminho do novo post, incluindo um abort
caso não encontre argumento
na linha de comando:
if [ $# != 1 ]; then
echo "Forneça um (e apenas um) draft para criar" >&2
exit 1
fi
OUTFILE="$1"
# normalizar OUTFILE
if [ "${OUTFILE}" = "${OUTFILE#_drafts/}" ]; then
OUTFILE="_drafts/$OUTFILE"
fi
Tendo isso já tranquilizado, preciso ainda ler as duas informações de fato customizáveis. Então,
por que não usar o read
?
read -p "Qual o título? " TITLE
read -p "Tags? " TAGS
Pronto, vamos gerar o frontmatter? Bem, ainda falta o RDX para o base-assets
. Ele é basicamente o
elemento aberto em _drafts/%.md
. Portanto, posso pegar o que está entre a barra e o ponto.
Existem diversas alternativas, no caso para manter uma única linha e não invocar regex eu fiz
uma expansão de variável cortando o final .md
seguido de um corte ignorando o diretório:
RADIX=`echo ${OUTFILE%.md} | cut -d '/' -f 2`
Pronto, agora só falta o frontmatter mesmo. Nada como um heredoc
, não é?
cat << EOL
---
layout: post
title: "$TITLE"
author: "Jefferson Quesado"
tags: $TAGS
base-assets: "/assets/${RADIX}/"
---
EOL
Muito bem, mas podemos ser ainda melhor se já redirecionarmos a saída para OUTFILE
:
cat > "$OUTFILE" << EOL
---
layout: post
title: "$TITLE"
author: "Jefferson Quesado"
tags: $TAGS
base-assets: "/assets/${RADIX}/"
---
EOL
Regra de criação no Makefile
Basicamente, precisa estar dentro de _drafts/
e terminar com .md
. Não tem muito segredo
não. Não deve ter dependência. A regra de criação é simplesmente chamar o bin/new-post.sh
passando como argumento o target do Makefile.
Então, como representar isso?
O Makefile permite deixar zonas “abertas” usando o %
. Esse identificador também é bastante
útil no caso de ter um arquivo fonte que gere o algo, e ambos tem uma raiz em comum. Nestas
situações, usamos o %
tanto no alvo como também nas dependências desse algo.
A regra de criação é simplesmente bin/new-post.sh "$@"
, onde $@
no caso do Makefile significa
o algo que foi chamado.
_drafts/%.md:
bin/new-post.sh "$@"