Eu escolho você, Jekyll!
Como primeiríssmo post, falar da minha experiência implementando um blog com o Jekyll parece bastante justo. No entanto, como tantos outros já o fizeram, eu não vou tomar muito tempo detalhando o passo-a-passo de como fazer isso – uma vez que já tem um monte de conteúdo sobre o assunto por aí, e também porque eu sou um entusiasta do DRY (como um conceito mais amplo também). Vou apenas destacar alguns pontos que acho interessantes, principalmente sobre como tranformar o blog em multilíngue (na verdade, apenas bilíngue :P).
Em primeiro lugar, se você nunca ouviu falar do Jekyll – não esse da imagem de Jekyll and Hyde no topo, que eu coloquei de brinks –, ele é basicamente uma ferramenta que tranforma texto em um site estático (ou blog).
O Jekyll é construído como uma gem do Ruby, o que o torna fácil de instalar, principalmente se você já tem o ambiente Ruby instalado na sua máquina. Devido a essa facilidade de instalação e simplicidade, ele tem sido amplamente adotado por um crescente número de gentes que procuram por uma alternativa a outras famosas ferramentas (como o Wordpress, por exemplo). Eu sou uma dessas pessoas, e estou bastante satisfeito até agora. Seja feliz você também e venha para o maravilhoso mundo do Jekyll!
Integração com o GitHub
O primeiro atrativo do Jekyll pra mim foi saber da sua integração nativa com o GitHub Pages. Caso você não saiba, o GitHub tem um serviço de hospedagem na faixa para páginas pessoais ou de projetos. A única coisa que você precisa fazer é seguir algumas convenções – por exemplo, o nome do repositório e dos branches – e então você tem o seu site (ou blog) ‘digrátis’ de maneira bem simples. Acesse o link destacado acima e leia um pouco mais sobre (ou vá até a documentação do Jekyll sobre esse tópico).
Os temas
A primeira coisa que eu fiz quando decidi utilizar o Jekyll foi procurar por um tema do meu gosto lá no catálogo que tem no repositório. Eu vasculhei todos os temas na lista e escolhi o So Simple como ponto de partida. Neste caso, em particular, eu precisei apenas copiar o repositório do tema no GitHub e personalizá-lo de acordo com as minhas necessidades.
Eu alterei coisas como:
- cores dos títulos
- comportamento da imagem e logotipo do topo das páginas e posts
- menu de navegação principal
- adição de suporte bilíngue
Pra alcançar estes resultados, eu precisei apenas brincar com alguns arquivos e configurações importantes, alterando algumas partes do código (html, lógica e marcação nos templates, css). Eu recomendo fortemente que você dê uma olhada em algumas partes importantes da documentação do Jekyll antes de fazer estão alterações. Por exemplo, aprenda como o Jekyll gerencia configurações e sua estrutura de diretórios. Com isso em mente, abra um novo branch no repositório do tema que você escolheu e faça suas próprias personalizações (se você precisar, é claro).
A maior dificuldade que tive foi em entender a ferramenta de template utilizada pelo Jekyll, o Liquid da Shopify. O Liquid é bastante similar, pelo menos em sintaxe, ao Twig – the flexible, fast, and secure template engine for PHP – com o qual eu já era bastante familiar. No entanto, quando eu fui alterar algumas partes da lógica nos templates do blog, eu tive alguma dificuldade. Nada de exagerado, mas ainda assim alguma dificuldade.
Rumo ao blog bilíngue: uma meia-solução, mas suficiente
Quando decidi começar a blogar, um dos pré-requisitos que estabeleci pra mim mesmo foi que eu escreveria os posts tanto em português (já que sou brasileiro) e inglês. No entanto, quando comecei a pesquisar sobre como fazer isso, fiquei um pouco surpreso. O Jekyll não tem suporte nativo multilíngue. Sobre isso, aliás, concordo com algumas opiniões que acabei lendo à respeito: isso é algo bom no fim das contas. Simplicidade tem o seu preço e, no caso Jekyll, o preço é a falta de algumas funcionalidades que encontramos com maior facilidade em outras ferramentas.
Na verdade, existem alguns plugins que prometem fazer o trabalho sujo de maneira indolor pra você. No entanto, durante as minhas pesquisas de como realizar essa tarefa, eu acabei lendo alguns avisos sobre o uso dos plugins, com destaque para:
-
A parte do “indolor” não é tão verdade assim. Esses plugins multilíngues podem ter algumas partes ruins (de acordo com o que eu li), particularmente no que se refere ao uso de outros plugins em conjunto. Apesar de não estar utilizando outros plugins, fiquei receoso em utilizar estas ferramentas no meu blog;
-
A diretiva de safe mode do GitHub Pages tem alguma coisa contra o uso de plugins. Admito que não fui pesquisar muito a fundo sobre o assunto, mas me pareceu um “boa” parte ruim, mesmo que seja possível contornar isso.
Assim, principalmente depois de dar uma olhada no post do Sylvain Durand, eu tomei coragem e decidi fazer por conta própria o Jekyll aceitar mais de uma língua.
Minha meia-solução
Preciso confessar que não consegui aplicar de maneira estrita a solução do blog do Durand. Primeiramente, porque o passo-a-passo dele não funcionou muito bem pra mim (eu tive dificuldades com algumas partes) e, “segundamente”, porque a solução dele espera que os posts tenham sempre nomes diferentes (pelo menos foi isso que entendi) – um post não pode ter o mesmo título para duas línguas diferentes, mesmo quando um é tradução do outro. Essa pode não ser uma barreira de grande importância pra você, mas eu queria que meus posts pudessem ter o mesmo título para as duas línguas – mesmo que nunca precise disso :).
Por quê a minha solução é incompleta? Principalmente porque eu não implementei suporte multilíngue de verdade, apenas bilíngue. Segundo, mesmo sendo bilíngue, algumas partes estão sempre em inglês (por exemplo, o menu principal e as datas). Terceiro, o plugin de busca (aquele que vem junto com o Jekyll) não permite busca apenas por posts em inglês, ou em português. Apesar disso tudo:
-
Eu não pretendo escrever posts em outra língua que não seja inglês ou português. Eu já escolhi o inglês justamente por ser uma alternativa universal a minha língua materna. Além do mais, se eu decidir depois que preciso que seja multilíngue, ainda é possível fazer isso usando essa mesma solução. Precisaria apenas flexibilizar a lógica aplicada (ao invés de utilizar apenas if/else);
-
As partes que não são bilíngues não são tão importantes: o menu principal pode ser facilmente lido por quem fala português; as datas também;
-
Apesar de o plugin de busca não ser restrito por língua logicamente falando, ele é restrito naturalmente: na maioria das vezes os termos buscados estarão na língua de interesse do leitor; se não estiver, não me preocupo em exibir os posts em ambas as línguas como resultado das buscas.
Assim, apesar de ser uma meia-solução, eu acredito que seja uma meia-solução bastante justa. Além disso, não estou dizendo que a solução que apliquei aqui seja melhor que a do Durand ou de qualquer outra que tenha visto, mas é a que melhor funcionou pra atender minhas necessidades. Ela engloba as seguintes características:
- Um post pode existir em apenas uma língua ou em ambas;
- O título de ambas as traduções pode ser exatamente o mesmo (apesar de ser difícil acontecer);
- Um visitante pode navegar na versão em inglês ou português;
- Existe um botão pra trocar de um língua pra outra;
- Tudo isso funciona sem a necessidade de utilizar qualquer plugin de terceiro.
Leia o passo-a-passo abaixo e descubra como você pode fazer o que eu fiz.
Guia resumido rumo ao suporte bilíngue
Apesar de não ter conseguido aplicar exatamente a solução descrita pelo Durand, eu usei fortemente as ideias dele para conseguir levar o Jekyll pelo caminho que precisamos para que que tenha suporte a mais de uma língua. Basicamente, tive que seguir os passos abaixo:
1o. Utilizar subpastas
À fim de ser possível ter a mesma página (ou post) em ambas as línguas eu precisei criar um subdiretório para cada uma delas dentro da pasta já existente da página/post. Assim, minha estrutura de diretórios ficou algo como:
...
--_posts
--en
post_de_exemplo_em_ingles.md
--pt
post_de_exemplo_em_portugues.md
...
--about
--en
index.md
--pt
index.md
...
Como mostrado acima, o diretório _posts
agora tem duas subpastas: /en
e /pt
. O mesmo post_de_exemplo vai dentro de cada um deles como com seu próprio nome traduzido. Para páginas, tomando a página about
como exemplo, nós precisamos de um index.md
para cada uma das línguas também.
2o. Identificar páginas e posts
Já que o Jekyll não suporta isso nativamente, precisamos indicar para cada página e post em que língua está. Para isso, nós criamos um novo atributo lang
que é colocado no Front Matter dá página/post. Além disso, apenas para posts, precisamos incluí-lo em uma falsa categoria que representa a língua em que está. Isso é feito incluindo a língua como uma categoria no atributo categories
. Assim, temos o seguinte formato para o front matter do nosso post:
---
layout: post
title: "First Commit: Minha Experiência Implementando Um Blog Com Jekyll"
name: first_commit
lang: pt
categories: pt
// demais atributos
---
O atributo lang
será utilizado nos templates para fazer refrência à língua da página/post atual, enquanto a configuração de categoria serve apenas para que o Jekyll saiba como encontrar um post que comece com a abreviação da língua em que o mesmo se encontra (por exemplo, /pt/meu-post-em-portugues
).
Além da identificação da língua, nós criamos um outro atributo para relacionar um post as suas traduções. Conforme feito pelo Durand, eu chamei esse novo atributo de name
e o seu valor precisa ser único: todas as traduções de um post precisam compartilhar um nome em comum e único. Este nome pode ser o que você achar melhor, você precisa apenas garantir sua unicidade – nos passos abaixo você irá entender melhor essa necessidade.
3o. Categoria no permalink dos posts
Para que o Jekyll possa encontrar um post referenciado pela língua em que está escrito, conforme dito anteriormente, nós precisamos configurar o permalink dos posts para incluir categorias. Isso é feito alterando o atributo permalink
(geralmente configurado globalmente no arquivo _config.yml
):
# configuração do Jekyll
permalink: /:categories/:title/
4o. Filtrando posts por língua
Quando acessamos a página que lista os posts do blog, idealmente nós queremos exibir apenas os posts escritos na língua de interesse do leitor – a língua da página em que se encontra. Isso é feito alterando a lógica de listagem de posts e adicionando uma condição que verifica o atributo lang
de cada post. Na página que contém essa lógica – no caso desse blog, a página é posts
mesmo, e o código está em um arquivo de include utilizado tanto por /posts/en/index.md
quanto por /posts/pt/index.md
– nós precisamos fazer algo como:
# _includes/posts.html
{% assign posts = site.posts | where: 'lang', page.lang %}
<ul class="post-list">
{% for post in posts %}
<li><a href="{{ site.url }}{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
Perceba que, antes de iterar por todos os posts , nós atribuímos o conteúdo de site.posts
para uma nova variável posts
utilizando o valor de page.lang
(a língua da página atual) como filtro. Deste modo, apenas os posts escritos na mesma língua que a página atual serão listados.
Logo, uma solução similar pode ser utilizada sempre que for necessário filtrar o conteúdo de uma determinada página de acordo com a língua da mesma.
5o. Navegação
O menu principal de navegação precisa que seus links apontem para páginas na mesma língua que a página atual – lembre-se que eu decidi alterar apenas os links propriamente ditos, sendo que os nomes das páginas continuam sempre os mesmos, independentemente da língua da página atual. Primeiro, você precisa escolher um língua como sendo a principal. Como eu escolhi o inglês, eu precisei fazer o seguinte no arquivo _/data/navigation.yml
:
# _data/navigation.yml
- title: Home
url: /en/
- title: About
url: /about/en/
- title: Posts
url: /posts/en/
- title: Tags
url: /tags/en/
Dessa maneira, o blog fica com a versão em inglês de index.md
como padrão para cada página. Quando um visitante carregar um página, o seguinte fragmento de código decide para qual das suas línguas os links irão apontar:
# _includes/navigation.html
...
# dentro do laço que cria os links do menu principal
{% assign link_url = link.url | replace_first: 'en', page.lang %}
...
Note que a decisão é feita apenas substituindo a primeira ocorrência de en
– a abreviação de english – na URL do link pela abreviação da língua da página atual ao iterar todos os links definidos em _data/navigation.yml
. Uma vez que a língua padrão é o inglês, se a página atual estiver em inglês nada irá mudar; por outro lado, se a página estiver em português, todas as URLs serão alteradas de acordo.
6o. Alternando entre as línguas (ui!)
Este blog possui o inglês como língua padrão. Então, o que acontece quando alguém quer navegar na versão em em português? A resposta é que precisamos de uma maneira para que tal visitante possa alternar para a língua de sua preferência. Minha solução foi um botão no topo, à direita do blog, onde uma flag permite ao leitor fazer essa alternação conforme necessário. A solução é bastante direta – fazendo uso dos atributos lang
e name
que criamos para as páginas e posts anteriormente –, e o único truque é a diferenciação entre páginas comuns e páginas de posts. Considerando que essa é a parte mais importante da funcionalidade do suporte bilíngue, abaixo fiz a transcrição completa do código que usei para criar o tal botão:
# _includes/switch_lang.html
# aqui obtemos a língua para a qual irá alternar (a oposta à da página atual)
{% capture switch_lang %}{% if page.lang == 'en' %}pt{% else %}en{% endif %}{% endcapture %}
# diferenciamos o comportamento do botão de acordo com o layout da página
{% if page.layout == 'page' %}
{% assign switch_lang_url = page.dir | replace_first: page_lang, switch_lang %}
# este é um hack para garantir o funcionamento correto quando a página for acessada
# através da url principal do site, que não possui a abreviação da língua no final
{% if switch_lang_url == '/' and page.dir == '/' %}
{% assign switch_lang_url = '/pt' %}
{% endif %}
{% else %}
# aqui nós obtemos os posts cujo nome é o mesmo do post atual
{% assign same_name_posts = site.posts | where:'name', page.name %}
# nós atribuímos um valor para switch_url apenas se existir uma tradução para o post atual
{% if same_name_posts.size == 2 %}
{% for _post in same_name_posts %}
{% if _post.lang == switch_lang %}
{% capture switch_lang_url %}{{ _post.url }}{% endcapture %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
# se a página/post atual possui uma tradução, nós exibimos o botão de switch
{% if switch_lang_url %}
{% capture lang_label %}{% if page.lang == 'en' %}ver em português{% else %}read in english{% endif %}{% endcapture %}
<ul class="lang-switch">
<li>
<a href="{{ switch_lang_url }}">
<img src="{{ site.url }}/images/ico-lang_{{ switch_lang }}.png"> {{ lang_label }}
</a>
</li>
</ul>
{% endif %}
Conclusão
O Jekyll é sem dúvidas uma ferramenta simples e direta para implementar o seu website estático ou blog. Sua instalação é bastante fácil e, mesmo se você não se agradar completamente de um dos temas open source disponíveis, é possível botar a mão na massa e fazer as suas alterações sem muito esforço.
Considerando que minha maior dificuldade foi encontrar uma boa maneira de fazer com que o Jekyll suportasse mais de uma língua, passei a maior parte do post tentando explicar como consegui cumprir isso. No entanto, caso esteja faltando alguma peça importante ou detalhe do qual você precise neste passo-a-passo, por favor fique à vontade para dar uma olhada (ou mesmo fazer um fork) deste repositório público no GitHub e procurar pelo que precisa. Você pode também entrar em contato comigo através de uma das formas existentes no rodapé deste blog.