Jekyll i18n

Featured image

Sitios multilenguajes - Jekyll

Buenasss! como andan?? Estuve armando este blog para que sea multilenguaje y quería compartir con ustedes como fue el proceso por si alguna vez necesitan o se ven tentados de armar algo asi con Jekyll.

Hay bastante material dando vueltas, con y sin plugins, pero no había mucha claridad, entre otros varios aspectos que probé y no funcionaron como esperaba, además de algunas desventajas que presenta el hecho de usar plugins para este tipo de funcionalidad que luego no se comportan como se espera una vez que se deployan.

Así que ahi vamos con la implementación sin plugins! Para tener en cuenta el stack que utilizo es #Jekyll, #Liquid para templating, #RubyGems para paquetes y todo corriendo sobre la terminal de #Ruby.

enter image description here

Mini intro a Jekyll

enter image description here Para armar un blog o sitio estático vas a necesitar instalar Ruby Una vez instalado, ejecutas los siguientes comandos para configurar Jekyll bien fresh:

    $  gem install bundler jekyll
    ~  $  jekyll new my-awesome-site
    ~  $  cd my-awesome-site
    ~/my-awesome-site  $  bundle exec jekyll serve
    # => Now browse to http://localhost:4000

Para más documentación y detalles acá!

Qué es i18n?

“Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization con el numerónimo “i18n”. Ello se debe a que entre la primera i y la última ene de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia “L10n””

dicho en criollo cada vez que mencionamos i18n o internacionalización nos referimos al hecho de traducir nuestros contenidos a N idiomas.

enter image description here

Jekyll

Arrancamos con el skaffolding, muy similar a lo que Jekyll ya proporciona from scratch, la idea de organizar las divisiones por idioma es subjetiva y mi sugerencia es la siguiente, suponiendo un caso español e inglés:

    _posts
    	en
    		post1.md
    		post2.md
    	es
    		post1.md
    		post2.md

_config.yml

Seteamos estos nuevos paths y los configuramos en nuestro config de la siguiente forma:

    defaults:
        - scope:
        path: '_posts/es'
        type: 'posts'
        values:
        permalink: 'es'
        language: es
        - scope:
        path: '_posts/en'
        type: 'posts'
       values:
        permalink: 'en'
        language: en
        - scope:
        path: '_posts/en'
        type: 'posts'
        values:
        permalink: 'en/:title'
        language: en
        - scope:
        path: '_posts/es'
        type: 'posts'
        values:
        permalink: 'es/:title'
        language: es

Como vemos arriba, la idea es configurar los paths relativos a los idiomas que respeten la estructura que armamos. Lo más importante a destacar son los siguientes puntos:

Sumado a esto, en nuestro index.html e index.markdown

    ---
    layout: home
    permalink: en
    layout: home
    permalink: es
    ---

Liquid: i18n inside templates

Ahora queda la parte divertida para gestionar estos idiomas desde lo que visibilizamos. Usando Liquid, que es un motor de templating open source de Shopify. Si usaste algun motor como Twig o Smarty te vas a hacer amigo en un abrir y cerrar de ojos.

enter image description here

Selector de idiomas

    {% assign url_language = page.url | split: "/" %}

    <div  class="languages">
        <a  class="languages__link {% if url_language[1] == 'en' %} highlight-language {% endif %}"  href="/en">English</a>
        <a  class="languages__link {% if url_language[1] == 'es' %} highlight-language {% endif %}"  href="/es">Español</a>
    </div>

Filtrado de posts

Aquí vamos a filtrar los posts que mostramos, para que sólo se muestren aquellos que cumplan con la condición del idioma según la url:

    {% assign url_language = page.url | replace:'/','' %}
    {% assign posts = site.posts | where_exp:"post","post.language == url_language " %}
    {% for post in posts %}
    ...
    {% endfor %}

Y en el caso de otros filtrados que existan por otras condiciones, podemos sumar el filtro de idioma:

    {% assign next_posts = site.posts | where_exp:"post","post.is_generated != true" | where_exp:"post","post.path != page.path" %}
    {% assign url_language = page.url | split: "/" %}
    {% assign locale_next_posts = next_posts | where_exp:"post","post.language == url_language[1] " %}
    {% assign shuffled_array = locale_next_posts | shuffle %}
    {% for post in shuffled_array limit:3 %}
    ...
    {% endfor %}

Bonus!

enter image description here

Translations.yml

En caso de querer traducir no sólo a nivel posts, sino a nivel configuraciones de .yml para textos que cruzan el sitio, también es posible! Ejemplo:

    translations:
        text:
        new_post: "New Post"
        see_also: "See also"
        search: "Search"
        author: "Author"
        share: "Share"
        comments: "Comments"
        button:
        read_now: "Read Now"
        share_on_twitter: "Share on Twitter"
        share_on_facebook: "Share on Facebook"
        pagination:
        page: "Page"
        of: "of"
        next_page: "Next Page"
        next_post: "Previous Page"

Redirects

Hay varias formas de redireccionar tu index hacia alguno de estos idiomas por defecto, una de las mas simples (que tambien funciona con Github pages) es instalando la gem ‘jekyll-redirect-from’ mas info aca

Agregamos en _config.yml el nuevo plugin y lo agregamos a la whitelist:

plugins:
  - jekyll-redirect-from

whitelist:
  - jekyll-redirect-from

Finalmente creamos un index.md donde vamos a setear los path que queremos que redireccionen a nuestra home:

title: home
redirect_from:
  - /

Referencias de un blog que me sirvió finalmente para lograr todos estos cambios sin necesidad de plugins aquí!