Sito statico?

Secondo i miei piani questo questo doveva essere il primo post scritto nel nuovo sito realizzato con Jekyll. Il parto è stato un po' più lungo del previsto (giusto di 12 mesi...), tanto che dalla versione 0.11.2 su cui si basa questo post, siamo arrivati alla 1.0.3, ma comunque, eccoci qua :)
Jekyll è un'interessante gemma ruby che permette di gestire un blog (e non solo) attraverso semplici file con sintassi markdown, textile, liquid o HTML e produrre un sito quasi statico.
Dico quasi poichè, sebbene i file prodotti siano tutti html, con poche righe JavaScript si possono integrare nel sito tantissime funzioni dinamiche come commenti, invio email (con un minimo di programmazione server-side), statistiche, ecc.

Il perchè di questa pazzia, oltre al puro piacere nello spippolare che mi porta periodicamente ad annoiarmi del vecchio sito, è un progettino che mi gira per la testa e che renderò pubblico (e OSS) appena avrà preso un minimo di forma e che si basa su Jekyll.

Per una panoramica delle configurazioni vi rimando alla nuovissima documentazione ufficiale, fatta molto bene.

Configurare Jekyll

La struttura base dei file in un sito Jekyll è questa:

.
|-- _config.yml
|-- _drafts
|   |-- bozza-articolo.md
|-- _includes
|-- _layouts
|   |-- default.html
|   `-- post.html
|-- _posts
|   |-- 2012-03-11-hello-world.md
|   `-- 2012-04-01-second-post.md
|-- _site
`-- index.md
  • Il file _config.yml contiene le configurazioni lette da jekyll quando viene lanciato. Le varie opzioni possono essere passate anche da linea di comando se occorre sovrascrivere temporaneamente un valore. Per una lista completa visitate: http://jekyllrb.com/docs/configuration/.
  • Nelle varie pagine si possono includere altri file, con varie funzioni. Si usa il tag {% include file.ext %| e si posiziona file.ext in _includes.
  • I layout HTML, scritti usando Liquid Syntax, si trovano nella cartella _layouts. Il contenuto delle pagine si inserisce nel layout con il tag {{ content }}.
  • I post stanno in _posts, il formato è YEAR-MONTH-DAY-title.MARKUP. I permalink si impostano da _config.yml ma il nome determina la data e il markup usato (se ne possono usare vari oltre markdown e HTML).
  • _site: il sito statico prodotto quando si lancia jekyll. In pratica quello da copiare sul proprio server.
  • index.md nell'esempio è una pagina, scritta in sintassi markdown, che verrà elaborata e tradotta in _site/index.html. Ogni altra pagina contenente lo YAML Front Matter (vedi sotto) viene elaborata e posizionata in _site.

Nei vari file del sito si possono usare delle variabili globali. La lista la trovate qui: http://jekyllrb.com/docs/variables/. Usando _config.yml se ne possono definire anche di personalizzate.

Un suggerimento che mi sento di dare è quello di dare un'occhiata alle configurazioni di altri siti (che spesso hanno i sorgenti su GitHub), io ho preso spunto da Nolith e da Matteo Flora.

YAML Front Matter

Quando si lancia jekyll, la gemma scansiona la cartella in cui viene lanciato per cercare i file essenziali. A quel punto fa una lista di tutto ciò che deve essere convertito in HTML. Per farlo controlla se i file hanno lo YAML Front Matter, ovvero se in testa al file vi sono due serie di --- come nell'esempio sottostante:

---
layout: post
title: Blogging Like a Hacker
---

I file che iniziano con questa struttura vengono inviati ai Converter. Stessa cosa per i file che hanno come estensione .html, .markdown, .md, o .textile. Tutti gli altri file, che non fanno parte della struttura di jekyll e non hanno lo YAML Front Matter, vengono semplicemente copiati nella cartella _site (ad esempio le immagini).
All'interno dell'header possono essere usate alcune variabili, come layout, permalink, published, category/categories, tags. Alcune servono a jekyll per costruire l'output HTML (ad esempio la variabile layout), altre possono essere usate per vari scopi (ad esempio per costruire la lista delle categorie o dei tags a cui appartiene il post).
Se si creano variabili custom si possono poi usare nei layout, ad esempio:

<title>{{ page.title }}</title>

I comandi essenziali

Una volta creata la configurazione di base si devono usare fondamentalmente due comandi per "generare" il sito:

  • jekyll build per generare i file statici
  • jekyll serve per servire il sito all'indirizzo http://localhost:4000 e vederne un'anteprima. Volendo è possibile usare l'opzione ‐‐watch per monitorare cambiamenti nei file e rigenerarlo al volo oppure l'opzione ‐‐drafts per generare anche i post presenti nella cartella _drafts

Terminata la generazione troverete i file del sito in _site. Sarà sufficiente caricare quella cartella nel server e il sito è pronto.

Jekyll-Bootstrap

A raccontare tutta la verità non è che sono proprio tutte rose e fiori. Quando ho usato Jekyll la prima volta (versione 0.11.x), dopo aver perso una buona mezza giornata a leggere vari sorgenti ho imparato che il segreto del successo è Jekyll Bootstrap, infatti appena l'ho usato sono riuscito a far funzionare per bene il sito :)

JB in pratica rende facile (attraverso poche impostazioni in _config.yml) includere i commenti ai post (con disqus, facebook, intensedebate, ecc.), le statistiche (analytics o mixpanel), creare la sitemap, ecc. Se non fosse presente il vostro motore di commenti o statistiche, JB crea comunque uno scheletro da usare per creare facilmente la configurazione personalizzata. Ultimo ma non ultimo, usando JB diventa immediato (e gratuito) pubblicare il sito utilizzando Github pages. Nel tempo l'utilizzo di Jekyll in Github è diventato talmente diffuso che se create una branch gh-pages nel vostro repository e ci mettete la struttura di un sito Jekyll, quando lo pushate Github lo genera automaticamente e lo rende disponibile all'indirizzo http://REPO.github.com. Date un'occhiata a 9Github pages](http://pages.github.com/) per maggiori informazioni.

Tornando a JB, setta anche molte variabili in _config.yml, per usarle si fa così:

<a href="{{ BASE_PATH }}{{ site.JB.archive_path }}">Archivio</a></li>

Un'altra importante caratteristica di JB è il supporto ai temi. Jekyll utilizza Liquid come motore di template e JB, anche in questo caso, crea uno scheletro che rende semplice personalizzare il tema grafico e cambiarlo con un comando.

A proposito dei comandi, JB include una serie di comodi rake per gestire il sito. Eccone una carrellata abbastanza autoesplicativa:

rake post title="Hello World"
rake page name="about.md"
rake page name="pages/about.md"
rake page name="pages/about"
rake theme:install git="https://github.com/jekyllbootstrap/theme-the-program.git"
rake theme:switch name="the-program"

si possono anche includere rake personalizzati semplicemente salvandoli nella cartella _rake/, utile, ad esempio, per creare rake di deploy.

JB è sicuramente molto utile, ma l'evoluzione di Jekyll nella versione 1.x è stata notevole e molte cose sono adesso semplici e intuitive.

Importare i vecchi post da Wordpress

I post

Nel passare a Jekyll ho deciso di importare quanto possibile dal vecchio sito cercando di lasciare intatti gli url delle pagine e i vari contenuti (come commenti, categorie e tag). Devo dire che è stato meno facile del previsto, in particolare l'importazione dei post. I problemi principali li ho avuti poichè i contenuti dei miei post contengono spesso esempi di codice, in particolare ruby, che facevano arrabbiare gli script di importazione. Sul sito di Jekyll vengono indicati vari metodi per l'importazione ma quello che alla fine ha funzionato meglio è stato Exitwp. L'unica cosa che ho dovuto fare (modificando il file _config.yml) è stato l'importare i vecchi post in html e non in markdown, altrimenti, come detto prima, impazziva tutto :)

Nella migrazione ho anche voluto mantenere i vecchi url, tanto cari ai motori di ricerca. Ricreare la struttura dei post non è stato difficile, in quanto nel file _config.yml c'è la variabile permalink:

permalink: /:year/:month/:day/:title

Pagine

Il discorso è stato leggermente diverso per le pagine. Intando ho dovuto modificare i file standard di JB da archivio.html ad archivio/index.html (e così via), in questo modo l'archivio si poteva raggiungere con l'url /archivio, senza l'estensione html. Il risultato, sempre in _config.yml è:

about_path: /chi-sono
archive_path: /archivio
categories_path : /categorie
contact_path: /contattami
map_path: /mappa
portfolio_path: /portfolio
tags_path : /tag/

È stato necessario modificare anche come viene generata la lista delle pagine nel file _includes/JB/pages_list:

<li class="on link"><a href="{{ BASE_PATH }}{{node.url | replace:'/index.html','' }}" alt="{{ node.title }}" class="active">{{node.title}}</a></li>

Commenti

Già usavo Disqus con wordpress, quindi non è stato un grosso problema migrare i commenti. L'unico problema che ho riscontrato è che wordpress utilizza una variabile wordpressid nel javascript con cui include i commenti, quindi i vecchi commenti non venivano visualizzati. Fortunatamente gli script che ho usato per importare i post hanno anche importato questa variabile (scrivendola nell'header di ogni post). Quindi ho modificato il file che visualizza i commenti disqus (*_includes/JB/comments-providers/disqus*) per comunicare a disqus lo *wordpressid*, se presente:

{% if page.wordpress_id %}var disqus_identifier = '{{page.wordpress_id}} {{site.production_url}}/?p={{page.wordpress_id}}';{% endif %}

Mantenere i vecchi url

Oltre ai permalink è utile mantenere tutti i vecchi url (a parte quelli obsoleti). Dato che ho effettuato il deploy del sito jekyll su Heroku, il sito è un'applicazione rack (i dettagli sono nel paragrafo deploy) e quindi ho potuto utilizzare rack/rewrite nel file config.ru per impostare dei redirect con codice HTTP 301:

require 'rack/rewrite'
[..]
r301 %r{^/tag/(.*)/$}, '/tag/#$1
r301 %r{^/\w{4}/\w{2}/$}, '/archivio/' # /2010/03 va all'archivio

Varie osservazioni

In generale nella migrazione da wordpress a jekyll (ma il discorso potrebbe essere più generale) consiglio di dare una bella lettura al codice html generato da wordpress, in particolare gli header, e di cercare di replicare tutte le cose importanti nel nuovo sito. Oltre a capire meglio cosa importare e cosa no, ci si libera di un sacco di cose inutili di cui non si sapeva quasi nulla :)

Form di contatto

La prima cosa che vi verrà in mente è: ma se il sito è statico, mi perdo il modulo dei contatti?
Ebbene, non proprio.
Come promesso all'inizio del post, con un po' di codice server-side è ancora possibile inviare email da un form senza "sporcare" troppo il nostro bel sito statico.

Come specificato nell'introduzione del post, questo articolo ha avuto un parto mooooolto lungo, tanto che la parte relativa a come inviare email da Jekyll è diventata un articolo a sè stante, non mi resta quindi che rimandarvi proprio a quell'articolo per tutti i dettagli

blog comments powered by Disqus