Um dos poucos requisitos que existiam para este blog desde o início era que ele permitisse várias línguas. Isto é algo que se pode fazer facilmente com o WordPress, mas eu descobri as GitHub Pages e uma coisa levou a outra e… muitas horas mais tarde tinha um blog multilingue, após ter canibalizado o belo tema Whiteglass. Deixo aqui uma descrição de como decorreu o processo.

Nota: O código não é bonito. Pensa nisto como um Produto Mínimo Viável. :)

O que é que podes aprender com este post

  • Como tornar o Jekyll multilingue

Eu comecei pelo…

Google, é claro! Eu estava a pensar assim “Existem vários plugins para isto no WordPress, por isso certamente existe um para o Jekyll”. Mas… estava redondamente errado! Para o Jekyll só existe uma língua no mundo inteiro num determinado momento.

O Google ajudou e encontrei uns posts muito úteis:

  • Este do Sylvain Durand foi o mais útil

  • Este, do developmentseed, não é tão detalhado, mas ainda assim deu a dica de usar categorias para simular/separar as línguas

  • Finalmente estes dois, do drallgood e do Anthony Gaudino são boas alternativas, mas eu já tinha encontrado um tema, estava limitado em termos de plugins por causa das páginas no GitHub e não queria encher os meus posts de código de tradução

Eu estava bloqueado, por isso pedi ajuda ao criador do tema

O/A Yous foi a pessoa que codificou o tema Whiteglass. Ele/ela foi super simpático/a e deu várias dicas, apesar de ter dito que tornar o tema multilingue era algo que não estava nos planos.

Então, peguei nesta informação e fiz o seguinte…

_config.yml

No _config.yml, alterei três coisas (relevantes ao ser multilingue)

lang: en
languages: ["en", "pt"]
permalink: /:categories/:year/:month/:day/:title/

A linha 1 diz que a língua por omissão do blog é Inglês.

A linha 2 cria um array de línguas possíveis no blog.

A linha 3 diz que os URLs devem conter as categorias (vamos voltar a essa ideia mais tarde).

_data/navigation.yml

O ficheiro _data/navigation.yml foi modificado para acrescentar menus nas várias línguas

languages:
  - language: "en"
    links:
    - title: "About"
      url: /about/
    - title: "Archives"
      url: /archives/
    - title: "GitHub"
      url: https://github.com/minac
    - title: "pt"
      url: /pt/
  - language: "pt"
    links:
    - title: "Sobre"
      url: /sobre/
    - title: "Arquivos"
      url: /arquivos/
    - title: "GitHub"
      url: https://github.com/minac
    - title: "en"
      url: /

Não tem nada que expicar aqui, duas línguas, duas subárvores com os URLs respectivos.

_includes/header.html

Depois eu precisei de incorporar isso no _includes/header.html

{% for item in site.data.navigation.languages %}
  {% if item.language == page.lang %}
    {% for link in item.links %}
      {% if link.url contains "http" %}
        {% assign url = link.url %}
      {% else %}
        {% assign url = link.url | relative_url %}
      {% endif %}
      <a class="page-link" href="{{ url }}">{{ link.title }}</a>
    {% endfor %}
  {% endif %}
{% endfor %}

As únicas linhas importantes aqui são as primeiras dias. Tem um ciclo for e uma cláusula if para mostrar o menu na língua correcta.

_layouts/archive.html

Agora a magia começa a acontecer no _layouts/archive.html

Isto <h1 class="page-heading">Blog Archive</h1> transforma-se nisto <h1 class="page-heading">Como tornar o Jekyll multilingue</h1> para evitar ter títulos hard coded.

Isto {% for post in site.posts %} passa a ser isto:

{% assign posts=site.posts | where: "lang", page.lang %}
{% for post in posts %}

Desta forma a página de arquivos passa a saber o que são línguas.

E finalmente isto:

<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}{% if post.categories != empty %} • {% include category_links.html categories=post.categories %}{% endif %}</span>

Transforma-se nisto:

<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}{% if post.tags != empty %} • {% for tag in post.tags %}{{ tag }}{% endfor %}{% endif %}</span>

Como estou a usar as categorias para as línguas, decidi usar as tags para categorizar os posts. Desta forma cada post pode ter uma ou mais tags, mas o URL apenas reflect as categorias (línguas).

_layouts/page.html e_layouts/post.html

Agora que o trabalho mais duro foi feito, a _layouts/page.html e a _layouts/post.html torna-se fáceis.

Aqui estão alguns meta-dados acrescentados a seguir ao título da página:

<header class="post-header">
  <h1 class="post-title">{{ page.title | escape }}</h1>
  <p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time> • {% assign pages=site.pages | where: "ref", page.ref | sort: 'lang' %}{% for page in pages %}<a href="{{ page.url }}" class="{{ page.lang }}">{{ page.lang }}</a> {% endfor %}</p>
</header>

E aqui estão alguns meta-dados acrescentados a seguir ao ao título do post:

<p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time>{% if page.tags != empty %} • {% for tag in page.tags %}{{ tag }} • {% endfor %}{% endif %} {% assign posts=site.posts | where: "ref", page.ref | sort: 'lang' %}{% for post in posts %}<a href="{{ post.url }}" class="{{ post.lang }}">{{ post.lang }}</a> {% endfor %} • {{ content | number_of_words }} words</p>

index.html

Por preguiça, decidi usar o index.html em vez do home que é o que o autor do tema sugere. Aqui está o conteúdo do mesmo:

<div class="home">
  {% capture site_lang %}{{ site.lang | default: "en" }}{% endcapture %}
  {% assign posts=site.posts | where:"lang", page.lang %}
  <ul class="post-list">
    {% for post in posts %}
      {% capture lang %}{% if post.lang != site_lang %}{{ post.lang }}{% else %}{{ site_lang }}{% endif %}{% endcapture %}
      <li{% if lang != empty %} lang="{{ lang }}"{% endif %}>
        <header class="post-header">
          <h1 class="post-title">
            <a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}{% if post.external-url %} &rarr;{% endif %}</a>
          </h1>
          <p class="post-meta">{{ post.date | date: "%b %-d, %Y" }}{% if post.tags != empty %} • {% for tag in post.tags %} {{ tag }} • {% endfor %}{% endif %}</p>
        </header>
        <div class="post-content">
          {{ post.excerpt }}
        </div>
        {% if post.content contains site.excerpt_separator %}
          <p class="post-continue">
            <a href="{{ post.url | relative_url }}">Read on &rarr;</a>
          </p>
        {% endif %}
      </li>
    {% endfor %}
  </ul>
  {% include pagination.html %}
</div>

As linhas que interessam aqui são as 2, 3 e 6.

‘about’ fica ‘sobre’, ‘archives’ fica ‘arquivos’

Depois de tudo isto feito, precisei de criar as páginas Portuguesas equivalentes às Inglesas. Então o about.md ganhou uma irmã sobre.md e o archives.md ganhou o arquivos.md. O conteúdo destes ficheiros é irrelevante neste caso.

Árvore de ficheiros

No final do projecto esta é a nossa árvore de ficheiros:

./_config.yml
./_data
./_data/navigation.yml
./_includes
./_includes/fonts.html
./_includes/footer.html
./_includes/footer_content.html
./_includes/google_analytics.html
./_includes/head.html
./_includes/head_custom.html
./_includes/header.html
./_includes/pagination.html
./_layouts
./_layouts/archive.html
./_layouts/category_archives.html
./_layouts/default.html
./_layouts/feed.xml
./_layouts/page.html
./_layouts/post.html
./_sass
./_sass/whiteglass
./sass/whiteglass/base.scss
./sass/whiteglass/layout.scss
./sass/whiteglass/syntax-highlighting.scss
./_sass/whiteglass.scss
./about.md
./sobre.md
./archives.md
./arquivos.md
./assets
./assets/main.scss
./feed.xml
./Gemfile
./index.html
./en
./en/_posts
./en/_posts/2017-03-04-new-blog-new-life.md
./pt
./pt/_posts
./pt/_posts/2017-03-04-new-blog-new-life.md
./pt.html

A maior parte dos ficheiros já faziam parte do tema. Aqueles a que eu quero chamar a atenção estão nas linhas 26/27, 28/29 e a directoria de Inglês 35-37 e a de Português 38-40. O pt.html é o index.html, com um nome pouco imaginativo.

Agora que tudo isto está feito. Como é que podemos criar um novo post em Português e em Inglês (ou apenas numa das línguas)?

“Front matter” para os novos posts

Vejamos os ./en/_posts/2017-03-04-new-blog-new-life.md e ./pt/_posts/2017-03-04-new-blog-new-life.md. Aqui estão os meta-dados deles nas “front matters” respectivas. O Inglês:

---
layout: post
title: "New blog, new life"
tags: [blog]
author: "Miguel David"
date: 2017-03-04 16:12:07 +0000
lang: en
ref: new-blog-new-life
---

E o Português:

---
layout: post
title: "Novo blog, nova vida"
tags: [blog]
author: "Miguel David"
date: 2017-03-04 16:12:07 +0000
lang: pt
ref: new-blog-new-life
---

O que distingue estes ficheiros, aparte os conetúdos em si são o título e a língua que foram localizados. Tudo o resto fica o mesmo, incluindo a referência que é usada para podermos ligar as várias línguas de um mesmo post!

Espero que ajude!