Jekyll, de statische blog-generator

Ingediend door Dirk Hornstra op 09-jun-2021 21:40

We zijn er allemaal aan gewend geraakt. Je installeert Wordpress, Drupal, Joomla, Umbraco of een ander CMS. En zo'n beetje de eerste stap die je doet is dat je moet instellen welke database je gebruikt. Want in die database sla je jouw berichten en pagina's op. De afbeeldingen die je upload. En als iemand naar je website surft, haalt de code van het CMS de data uit je database.

"Vroeger" toen een hostingpakket nog niet een standaard database bevatte, had je vaak een programma op je computer staan waarmee je de website opbouwde en de HTML-pagina's en afbeeldingen (en documenten/downloads) zette je via FTP over naar de server.

En op zich was dat nog niet eens zo'n slecht idee. Want hoewel "het gemak de mens dient", vaak maak je een stuk tekst, met wat "plaatjes" en verandert er niets meer aan je website. Dus je website is eigenlijk "statisch". Behalve als je natuurlijk een webshop hebt, producten uitverkocht kunnen raken en prijzen kunnen wijzigen. In de andere gevallen is het enige dynamische wat je nog hebt de zoekfunctie, dus dat mensen op basis van steekwoorden in je artikelen kunnen zoeken. De lijst die getoond wordt, die is dynamisch.

In podcast 132 van Scott Hanselman wordt Jekyll genoemd. Met die tool kun je statische websites maken. Omdat ik al een tijdje een soort statische website zou gaan maken, is dit een prima gelegenheid om dit te testen. Dus eerst naar de website van Jekyll: https://jekyllrb.com/

Ik volg de stappen zoals die op de site staan. Ik ga kijken of ik het op mijn mac aan de praat krijg (hier draait Big Sur op). Bij de gem install --user-install bundler jekyll krijg ik een foutmelding op de installatie van Jekyll. De melding is dat /Users/mijnnaam/.gem/ruby/2.6.0/bin niet in mijn PATH zit. Als je een echo $PATH doet, dan klopt dat. Ook op deze pagina wordt uitgelegd hoe je het in kunt stellen: link. Met de echo $SHELL zie ik dat ik zsh gebruik, dus ik doe de

echo 'export PATH="$HOME/.gem/ruby/X.X.0/bin:$PATH"' >> ~/.zshrc

Maar dan werkt het nog niet. In het log-bestand zie ik dat een ruby.h niet gevonden kan worden. Nu ben ik trouwens ook bezig om Xcode te updaten, het kan zijn dat die het nog aanvult. Maar "even een snelle installatie" gaat ook hier weer niet op.

En dan ben je 2 weken verder. Druk bezig geweest met andere dingen. Kijken of het nu wel lukt dan. Dus eerst de xcode-select --install geeft de melding dat de Cliënt Tools al geïnstalleerd zijn. Top. ruby -v geeft me versie 2.6.3 dus die is ook up-to-date. Hierna in mijn projectmap de sudo gem install -user-install bundler jekyll doe ik met het sudo-command omdat anders de documentatie van bundler niet weggeschreven kan worden. Het duurt even, maar nu gaat het goed. De vorige keer zal de XCode-update die nog liep de problemen veroorzaakt hebben.

Ok, nu gaan we dus echt beginnen. jekyll new site, cd site, bundle install, bundle exec jekyll serve. En daarmee kan ik in mijn browser naar http://localhost:4000 gaan en de standaard Jekyll site bekijken. Ik heb vervolgens de map geopend in Visual Studio Code en heb wat aangepast in _site/index.html, een refresh in de browser en je ziet direct je aanpassing.

Ik heb de map verwijderd, want ik wil eigenlijk "clean" beginnen. Dat kan met jekyll new site --blank
Daarmee wordt al een mappenstructuur opgebouwd en heb je een minimale HTML start-pagina en een stukje CSS.

Daar krijg ik echter de foutmelding bij mijn bundle exec jekyll serve dat "Jekyll niet bestaat of gevonden kan worden". Ik voer in mijn site-map nog een keer de sudo gem install jekyll uit, maar dat maakt ook geen verschil. Dan maar kijken wat de verschillen zijn. Nogmaals de map "site"  verwijderd en nu weer de normale new site. Op dat moment staat er een bestand met de naam Gemfile in de root met deze inhoud:


source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!

gem "jekyll", "~> 4.2.0"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
gem "minima", "~> 2.5"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
     gem "jekyll-feed", "~> 0.12"
end
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
platforms :mingw, :x64_mingw, :mswin, :jruby do
     gem "tzinfo", "~> 1.2" gem "tzinfo-data"
end
# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]

Dus nogmaals de map site verwijderd, nu weer de site met --blank aangemaakt, maar zelf die Gemfile aangemaakt met bovenstaande inhoud. En dan werkt het dus wel.

Ik had natuurlijk ook gewoon bij stap 1 van de "walk through" kunnen beginnen: link. Als ik een bundle init had gedaan, dan was er een Gemfile gemaakt en had ik daar alleen maar gem "jekyll" in hoeven zetten.

In ieder geval, ik heb die documentatie even doorgelezen. Met bundle exec jekyll serve kun je de site lokaal draaien (op http://localhost:4000) en met bundle exec jekyll build maak je de HTML aan, staat in de map _site, wat je dan zo via FTP kunt overzetten.

In mijn _data map heb ik een bestand drawings.yml geplaatst met de volgende inhoud:


- name: Guust Flater
  date: 6 juni 2021
  description: Guust Flater, 1 van mijn favorieten. Vroeger alle albums gekocht. Eerst met Kwabbernoot als zijn baas, later Pruimpit.
  src: /assets/drawings/20210606-guust-flater.jpg
- name: Robin Hoed
  date: 29 mei 2021
  description: Robin Hoed van Turk en de Groot. Altijd leuke stripverhalen. Robin en de sherrif zijn vrienden, waarbij de sherrif alitjd de pisang is. Met vaak een rol van zijn stevige vrouw Cunegonde en haar deegroller.
  src: /assets/drawings/20210531-robin-hoed.jpg
...

Het is de bedoeling om elke week een afbeelding toe te voegen. Dan heb je in een jaar 52 tekeningen. Die wil ik natuurlijk niet allemaal op de front-page tonen. Alleen de meest recente post. De rest moet dus "linken" naar de afbeelding, die in een soort pop-up getoond wordt.

In _layouts/default.html staat onder andere dit:


{% include drawingslist.html %} 

In _includes/drawlinglist.html staat dit:



{% assign firstpost = true %}
{% for item in site.data.drawings %}
<h3>{{ item.name }}</h3>
<div class="gallery">
  <div class="gallery-item">
{% if (firstpost) %}
{% assign firstpost = false %}
    <img src="{{item.src}}" alt="{{item.name}}" /><br/>
{% else %}
    <img src="" alt="" />
    <a href="#" data-rel="{{item.src}}" title="{{item.name}}" class="showimagelink">Toon afbeelding</a>
{% endif %}
  </div>
</gallery>
    <span class="wp-caption">{{ item.date }}</span><br/>
    <p class="entry-content">{{item.description}}</p>
    <hr/>
  {% endfor %}

 

Dan heb je dus een blanco site. Maar je kunt natuurlijk wel een Wordpress-theme gebruiken om je site er goed uit te laten zien. Ik heb " popper" gebruikt, hier op Github te vinden: link. De HTML, styling en afbeeldingen overnemen en nu heb ik een statische site die er ook nog eens goed uit ziet.

Zoals je in bovenstaande HTML al kunt zien plaats ik een lege afbeelding op de plek waar anders de afbeelding getoond zou worden. Want die pop-up leek me toch niet een goed idee. Met een on-click event op een link met de class "showimagelink" plaats ik deze er met behulp van de data-rel waarde:

 

<script defer="true">
    var imagelinks = document.getElementsByClassName('showimagelink');
    for (k=0; k < imagelinks.length; k++) {
      imagelinks[k].onclick = function() {
        var image = this.getAttribute('data-rel');
        var childnodes = this.parentNode.childNodes;
        for (z=0; z < childnodes.length; z++) {
          if (childnodes[z].nodeName.toLowerCase() == 'img') {
            var imgTag = childnodes[z];
            imgTag.setAttribute('src', image);
          }
        }
        this.remove();
        return false;};
    }
</script>

Geen jQuery, maar "gewoon" met vanilla Javascript. Elke browser zou dit moeten ondersteunen.

Het "enige" wat ik nu hoef te doen is een tekst toevoegen in de drawings.yml, een afbeelding te plaatsen en dan een jekyll build uit te voeren. En dat dan via FTP over te zetten. Dat klinkt dan wel een beetje als "meer werk dan het onderhouden in Wordpress", omdat je daar simpel een nieuwe post aanmaakt, bestand upload en de tekst intypt en de post publiceert: klaar. Maar goed, ik krijg nu wel veel kudo's/punten van Google, Pagespeed Insights (link) geeft me een score van... 100! Beter kan niet lijkt me.

De site is te bekijken op tekenaar.dirkhornstra.nl

En voor je weer zonder erbij na te denken ergens een site online klapt, met tig include-bestanden, met allemaal mogelijke hacks/sql-injections, vertragingen en wat al niet meer, denk aan het credo van mijn oud collega Eric Limpens: "kan het niet gewoon als platte HTML opgeslagen/getoond worden?".